Sign in with Cube Community
Cube Community is an OpenID Connect provider: your tool, bot or site can sign people in with their Cube Community account, and know who they are (their Discord, their verified BeatLeader or verified ScoreSaber account) without asking them. Register your application, point any OpenID Connect library at the discovery URL below, and you are set.
Endpoints
Every endpoint (authorize, token, userinfo, keys, logout) is listed in the discovery document. Tokens are signed with RS256.
- Issuer
https://cube.community/api/auth- Discovery URL
https://cube.community/api/auth/.well-known/openid-configuration
Use the authorization code flow. A server-side application keeps a client secret; a single-page or native app has none and uses PKCE, which every application should send anyway.
Scopes and claims
Pick the scopes your application needs when you register it; people see each one on the consent screen before they let it in. Each scope's claims come in two places, with the same values: the ID token (a signed JWT returned with the tokens) and the UserInfo response (GET /api/auth/oauth2/userinfo with the access token as a Bearer token). The ID token also carries OpenID Connect's own claims: iss, aud, exp, iat, auth_time, nonce, at_hash, sid.
openidRequired: makes the flow OpenID Connect, so you get an ID token.
substringTheir Cube Community user id. Stable: use it as the key to your own user records.
Example: "clgfoxlm50000s04mvxqq8ymg"
profileWho they are on the site, as it shows them.
namestringTheir display name: the custom username they chose, or their Discord username.
Example: "JiveOff"
preferred_usernamestringTheir Discord display name: their global name, or their username when they have none.
Example: "JiveOff"
picturestring | nullTheir avatar URL: their game avatar or their Discord one, whichever they chose.
Example: "https://cdn.discordapp.com/avatars/..."
discordTheir Discord identity, to match them on a server or with a bot.
discord_idstringTheir Discord user id (a snowflake, sent as a string: it does not fit in a JavaScript number).
Example: "186156892379283456"
accountsTheir verified linked accounts, such as BeatLeader or ScoreSaber.
linked_accountsarray of { provider, id, username? }One entry per account they linked: provider is discord, beatleader, scoresaber or steam. Only the Discord entry has a username: their Discord display name, as in preferred_username.
Example: [{ "provider": "discord", "id": "1378...", "username": "JiveOff" }, { "provider": "beatleader", "id": "7656..." }]
game_account{ platform, id, name } | nullThe account they play with: platform is steam or oculus. null if they have not linked one.
Example: { "platform": "steam", "id": "7656...", "name": "JiveOff" }
offline_accessKeeps your application signed in without asking them again.
No claim: the token endpoint also returns a refresh_token, which you exchange for new tokens (grant_type=refresh_token) once the access token expires, after an hour.
Example UserInfo response
For an application granted openid profile discord accounts:
{
"sub": "clgfoxlm50000s04mvxqq8ymg",
"name": "JiveOff",
"preferred_username": "JiveOff",
"picture": "https://cdn.discordapp.com/avatars/...",
"discord_id": "186156892379283456",
"linked_accounts": [
{ "provider": "discord", "id": "186156892379283456", "username": "JiveOff" },
{ "provider": "beatleader", "id": "76561198000000000" }
],
"game_account": { "platform": "steam", "id": "76561198000000000", "name": "JiveOff" }
}Reserved scopes
These are granted by an admin, not picked: ask [email protected], saying which application needs them and why.
emailTheir email address. Which one depends on what was granted: the email of their Discord account, or their @cube.community address for staff tools.
emailstringThe email address of the Discord account they sign in with (Discord gives it to us at sign-in, and it follows a change there at their next sign-in), or their @cube.community address. Absent if their Discord account has none.
Example: "[email protected]"
email_verifiedbooleanFor a Discord email: whether Discord itself has verified the address (its own verification, by email). Always true for a @cube.community address, which we issue. Treat false as unconfirmed.
Example: true
groupsThe Cube Community groups they are in, to gate access or map roles in your application.
groupsstring[]The names of their groups. Empty if they are in none.
Example: ["Staff Cubes", "Tournament Cubes"]