Skip to main content

Tokens and Claims

This page describes token response fields, ID token validation expectations, scopes, and the claims exposed by Muhajir Studio OIDC endpoints.

Token Response

POST /api/auth/oauth2/token returns OidcTokenResponse on success:

FieldTypeNotes
access_tokenstringBearer token for UserInfo and external APIs.
token_typeBearerToken type is always Bearer.
expires_innumberPositive integer lifetime in seconds.
id_tokenstringOptional in schema; present when the OIDC provider issues one for the flow.
refresh_tokenstringOptional; present when refresh-token behavior is available for the grant/client.
scopestringOptional space-separated granted scope string.

Use Authorization: Bearer ACCESS_TOKEN for bearer-protected endpoints.

Access Tokens

Access tokens are stored by the OIDC provider and resolved server-side for first-party external APIs. /api/external/me accepts only OIDC bearer access tokens; cookie-only sessions are not accepted there.

An access token is rejected when:

  • the Authorization header is missing
  • the scheme is not Bearer
  • the token is unknown
  • the token is expired
  • the token has no associated user

In those cases, bearer-protected APIs return 401.

ID Tokens

The ID token claims schema allows standard OIDC fields and selected optional claims:

ClaimNotes
issIssuer. Must match configured OIDC_ISSUER.
subStable subject identifier.
audAudience. Must include your client_id.
expExpiration time. Must be in the future.
iatIssued-at time.
noncePresent when nonce was included and should match your stored nonce.
emailAvailable when email-related claims are granted.
email_verifiedAvailable when email-related claims are granted.
nameAvailable when profile-related claims are granted.
pictureAvailable when profile-related claims are granted.
given_nameAvailable when profile-related claims are granted.
family_nameAvailable when profile-related claims are granted.
permissionsAvailable when the permissions scope is granted and claims are included.

When using the ID token for local sign-in, validate:

  • signature with keys from /api/auth/jwks
  • iss
  • aud
  • exp
  • iat according to your client policy
  • nonce when you sent one in the authorize request

Scopes

Supported scopes come from OIDC_SCOPE_METADATA and are exposed by GET /api/public/oidc/scopes.

ScopeDeveloper purposeClaims
openidRequired OIDC scope for stable subject identity.sub
profileAllows profile claims such as name and picture when available.name, picture, given_name, family_name
emailAllows email and email verification claims when available.email, email_verified
offline_accessAllows refresh-token based sessions where supported.none
permissionsAllows permissions claim and permission-based fields in supported APIs.permissions

For dynamic applications, admin-selected scopes are the source of truth. During authorization, the server rewrites the request scope to the application's configured scope set.

Permissions Claim

The OIDC provider adds custom UserInfo claims through buildAdditionalUserInfoClaims. Currently, this adds only permissions and only when the granted scopes include permissions.

When included, permissions is the user's effective permission key list from the roles/permissions system.

Example:

{
"sub": "user-id",
"permissions": ["manage-applications", "login-web-admin"]
}

Never check user roles directly in clients. Permission keys are the supported authorization signal.

External Current User Claims

GET /api/external/me returns a smaller, stable external API shape filtered by granted scopes:

ScopeResponse fields
openidsub
profilename, picture
emailemail, emailVerified
permissionspermissions

The endpoint requires openid. If the bearer token is valid but lacks openid, the response is:

{
"error": "FORBIDDEN",
"missingScopes": ["openid"]
}

Refresh Tokens

Refresh tokens can be present in standard token responses when refresh behavior is available for the grant/client. The offline_access scope is intended for refresh-token based sessions where supported.

First-party cookie-token helpers move refresh tokens out of the JSON response and into an HTTP-only cookie. Third-party integrations should normally use the standard /api/auth/oauth2/token endpoint and handle refresh tokens according to their platform security model.

OAuth Error Shape

OIDC and token errors follow the OAuth error schema:

{
"error": "invalid_request",
"error_description": "...",
"error_uri": "https://example.com/docs/error"
}

error_description and error_uri are optional.