Sessions, grants and tokens
What a sign-in leaves behind, how long each part lives, and what ends it.
Sessions
Signing in at a brand leaves a session in that browser: a cookie that belongs to the brand's issuer host alone, good for 14 days. While it lasts, the brand's apps can sign the person in again without asking (prompt=none), and an app that needs a fresh sign-in asks for one with prompt=login or max_age. An app that lets people pick which account to use sends prompt=select_account: someone already signed in sees who that is, with Continue as (the session goes on as it was, with its own sign-in time) and Use another account (a fresh sign-in as someone else, which replaces the session's account). A "Create an account" button sends prompt=create: the hosted page opens on its sign-up screen where the brand lets someone new sign up, with Sign in a link away, and someone already signed in is simply signed in. A person sees their sessions, and ends one, through the account API.
Grants
A grant is what one app has for one person: the OpenID scopes and claims, and each API's scopes, they allowed it (or the brand's own app asked for). Every token the app gets for them is issued under that grant, so ending a grant ends its tokens. Without offline_access, an app's grant lives only as long as the session it came from; with it, its refresh tokens outlive a sign-out.
Tokens
| Token | What it is | How long it lives |
|---|---|---|
| ID token | Who signed in, for the app: sub, auth_time, acr, amr and the claims allowed | An hour |
| Access token for an API | An ES256 JWT whose aud is that one API | What the API says: 5 to 15 minutes |
| Access token without an API | Opaque, good only for the issuer's /userinfo | |
| Refresh token | Gets new tokens without the person | 14 days from its last use, never past 90 days from the sign-in; an agent's 30 days |
| Authorization code | Traded once for tokens, with the PKCE verifier | A minute |
Refresh tokens rotate on every use: each refresh answers a new one, and presenting a used one again revokes the whole grant, since only a stolen copy would. A confidential web app that runs on several processes, whose requests may refresh at once, can be given a short window (up to 60 seconds) in which the same refresh token gets back the very tokens its rotation gave (refresh_token_reuse_window_seconds). A public app (a SPA, a native app, an agent) never gets one.
Only the app a token was issued to may introspect or revoke it, at the issuer's /token/introspection and /token/revocation; an API's own client may also introspect a stored token issued for that API. An API's JWT can't be revoked: the API checks it itself, against the issuer's keys, until it expires.
What ends them
One session, and the grants that live only as long as it:
- Signing out at the issuer (
/session/end), in that browser. - The person ending one of their sessions through the account API.
Every session and every grant the user has, offline ones and the device flow's included, refusing anything proved before, even a sign-in already in flight:
- The tenant ending a user's sessions, disabling them or scheduling their deletion.
- The person asking for their account to be deleted.
- A password reset, and a claimed email address (see users).
Either way, apps that registered a backchannel_logout_uri are told about each session they signed in to that ended, with a signed logout token (OpenID Connect Back-Channel Logout).