CastyrDocs

User info and ID tokens

Learn who signed in, from the user info endpoint or the ID token.

User info

curl https://sso.castyr.cloud/oauth/userinfo \
  -H "Authorization: Bearer cat_…"
Response
{
  "sub": "3f2b8c1e-5a7d-4e19-9c0a-2d6f1b8e4a70",
  "name": "Sam Rivera",
  "preferred_username": "samstreams",
  "picture": "https://…/avatar.png",
  "email": "someone@example.com",
  "email_verified": true
}

You get only the claims your scopes allow:

ClaimScope needed
subAlways. The user's permanent id: use it as your key, not the username.
nameprofile or identify
preferred_usernameprofile, identify or username. Users can change it.
pictureprofile, identify or avatar, when they have one
email, email_verifiedemail, when they have one

The token must be in the Authorization header; query-string tokens are refused. A token without any of openid profile username avatar identify email gets 403 insufficient_scope. An expired or revoked one gets 401 with WWW-Authenticate: Bearer error="invalid_token".

ID token

When you ask for openid, the token response includes an id_token: a JWT signed with RS256. Verify it before trusting it:

Fetch the public keys from https://sso.castyr.cloud/.well-known/jwks.json and pick the one whose kid matches the token header. Cache the keys, and refetch on an unknown kid: keys rotate.

Check the signature with algorithm RS256 only.

Check iss is https://sso.castyr.cloud, aud is your client_id, and exp is in the future.

If you sent a nonce, check it matches.

ClaimMeaning
subThe user's permanent id (same as user info)
iss, aud, iat, expIssuer, your client_id, issued at, expiry
auth_timeWhen the user last signed in to Castyr
nonceYour nonce, if you sent one
at_hashBinds the ID token to the access token issued with it

The ID token carries no profile or email claims. Get those from user info.

On this page