Webrizendocs
Integrate your app

Tokens & claims

Exactly what your app receives after sign-in, and how to use it for identity, organization context and permission checks.

Scopes

ScopeAdds
openidsub, the stable user ID. Required
profilename, given_name, family_name, picture
emailemail, email_verified
organizationThe org claim: organization, roles, teams and permissions
offline_accessA refresh token, so your app can renew access silently

Example claims

With all scopes, the ID token and the userinfo response look like this:

{
  "iss": "https://accounts.webrizen.com/api/auth",
  "aud": "your-client-id",
  "sub": "e8be9dc8-983d-493e-b16b-edb539a9b321",
  "email": "ravi@spiceroute.in",
  "email_verified": true,
  "name": "Ravi Kumar",
  "picture": null,
  "org": {
    "id": "0b6f2c1e-…",
    "name": "Spice Route Restaurants",
    "slug": "spice-route-restaurants",
    "logo": null,
    "roles": ["cashier"],
    "teams": [{ "id": "7a1d…", "name": "Andheri branch" }],
    "permissions": {
      "menu": ["read"],
      "order": ["read", "create", "update"],
      "table": ["read"]
    }
  }
}

The org claim

  • Which organization? The one the user picked when signing in to your app (or their only one). It's null if they don't belong to any organization yet. Design your app to handle that, for example with an "Ask your admin for an invite" screen.
  • roles are the role names exactly as defined, built-in or custom.
  • permissions are already resolved: the union of all roles. Check permissions, not role names, so owners can reshape roles without code changes.
  • teams are the member's teams in that organization.
Use sub, never email, as the key

sub never changes. Emails can be changed by the user. Store sub (and org.id) as foreign keys in your app's database.

Token types and lifetimes

TokenFormatDefault lifetime
ID tokenJWT, signed RS25610 hours
Access tokenOpaque string1 hour
Refresh tokenOpaque string30 days (issued with offline_access)

Access tokens are opaque: don't try to decode them. To learn who a token belongs to, call /oauth2/userinfo with it, or /oauth2/introspect from a backend using the client credentials.

Verifying an ID token yourself

Most libraries do this automatically. If you're writing it by hand, use the JWKS endpoint:

import { createRemoteJWKSet, jwtVerify } from "jose";
 
const JWKS = createRemoteJWKSet(new URL("https://accounts.webrizen.com/api/auth/jwks"));
 
const { payload } = await jwtVerify(idToken, JWKS, {
  issuer: "https://accounts.webrizen.com/api/auth",
  audience: process.env.WEBRIZEN_SSO_CLIENT_ID,
});

Keeping permissions fresh

Claims describe the user at the moment the token was issued. When an admin changes roles:

  • the change applies in Webrizen SSO immediately;
  • your app sees it at the next sign-in, or when it refreshes (the SDK's /refresh route);
  • for sensitive actions, re-check with /oauth2/userinfo, which always returns current data.