1. Private link from Discord
The user clicks “Verify through Riot.” The bot creates a ten-minute session and returns a link visible only to that person. The link token has 256 bits of entropy and only its SHA‑256 digest is stored.
Opening the page does not consume the link. An intentional form POST starts RSO, preventing automated link scanners from locking the user out.
2. Riot-hosted authorisation
The browser goes to auth.riotgames.com/authorize. Moon Poro asks for only:
openid cpidopenid identifies the account and cpid provides its League platform. We do not request offline_access, because the product does not refresh or store tokens.
3. Callback and identity
Riot returns to the exact registered callback. The service consumes and compares a one-time state, exchanges the code server-to-server, reads /riot/account/v1/accounts/me and obtains the platform from /userinfo.
The access token exists only in memory for these requests. It is never written to the database, a cookie, logs, or the Discord bot process.
4. Discord roles
The callback atomically reserves the unique PUUID ↔ Discord link. The bot retrieves the official Solo/Duo rank, applies the roles and sends a private confirmation. Temporary Riot or Discord failures use bounded exponential retries.
For Riot Developer Relations
This page documents the complete public product flow for approved production application ID 524635. Reviewer access is shared privately in App Notes. The exact redirect URI is https://moonporo.pl/oauth2/callback.