OIDC
Every instance is a standard OpenID Connect provider, for apps and tools that sign users in with OIDC instead of the Zautha SDKs. Its users sign in on the hosted login; the relying party gets ID and access tokens.
Endpoints
Section titled “Endpoints”On the instance’s host (https://{frontend host}):
| Discovery | /.well-known/openid-configuration |
| Keys (JWKS) | /.well-known/jwks.json |
| Authorization | /oauth/authorize |
| Token | /oauth/token |
| UserInfo | /oauth/userinfo |
| Revocation | /oauth/revoke |
| Logout | /oauth/end_session |
Clients
Section titled “Clients”Create a client on the instance’s OAuth clients page:
- Confidential (a server that can keep a secret): authenticates with its client secret. It may use the client credentials grant.
- Public (a single-page or native app): no secret (
oauth_client_public); PKCE withS256is required.
Each client lists its redirect URIs (see invalid_redirect_uri) and its scopes.
A client marked first-party signs users in without a consent screen. Any other asks the user to allow it: a
confidential client once (until the user’s consent is revoked), a public client every time, since nothing proves a
public client is the app it claims to be. Reusing an authorization code revokes the tokens its first use issued.
Authorized apps
Section titled “Authorized apps”Every client that is not first-party and still holds a grant for the user - a remembered consent, or a sign-in from a
session that is still active - is one of the user’s authorized apps. The user sees them under Authorized apps in
<UserProfile />’s Security tab and removes one there (after verifying again); your server does the same with
GET /v1/backend/users/{userId}/authorized_apps and POST /v1/backend/users/{userId}/authorized_apps/{clientId}/revoke,
and the dashboard on the user’s page. Removing an app revokes its grants, refresh tokens and authorization codes at once
and the next sign-in asks for consent again; the user stays signed in. An access token already issued is a JWT valid
for up to 15 minutes: a resource server that checks it offline accepts it until then, so one that needs revocation to
take effect at once asks /oauth/userinfo, which refuses it. A removal by your server or a dashboard member is in the
audit log; one by the user is not.
Grants, scopes and tokens
Section titled “Grants, scopes and tokens”- Grants:
authorization_code,refresh_tokenandclient_credentials. Responses come in the query or as aform_post. - Scopes:
openid,profile,emailandoffline_access(for a refresh token). - Tokens: an authorization code lives 5 minutes, access and ID tokens 15 minutes. A refresh token is rotated on use, never outlives the session it came from, and reusing a redeemed one revokes the whole family.
- Claims:
sub,sidandnonce, andauth_time(an impersonation session carriesactinstead); withprofile,name,given_name,family_nameandpreferred_usernamewhen the user has them, andupdated_at; withemail,email(the primary address) andemail_verified.
prompt and max_age
Section titled “prompt and max_age”prompt=nonenever shows a page: without a signed-in session the answer islogin_required, without consentconsent_required.prompt=login, or amax_agethe session’s sign-in is older than, sends the user through a fresh sign-in.prompt=consentasks for consent again.
Logout
Section titled “Logout”Send the browser to /oauth/end_session with id_token_hint, an ID token issued for the browser’s current session,
and optionally post_logout_redirect_uri (one of the client’s). A logout that cannot be tied to the current session
is refused with id_token_hint_invalid.
On a production instance the session cookie is SameSite=Lax, so a cross-site POST to /oauth/end_session (a form
on another site posting to it) arrives without the cookie and is refused with 400 id_token_hint_invalid. Use a
GET redirect to the endpoint instead.