Tokens
The token endpoint: codes redeemed once, five-minute access tokens addressed to one resource, ID tokens, acr and amr, refresh rotation with reuse detection, client credentials and DPoP.
POST <issuer>/oauth2/token
The token endpoint reads a form body of at most 16 KiB, refuses a repeated
parameter or more than one client authentication method, and authenticates the
client by its registered method before it reads the grant. Refusals carry the
error code alone.
Authorization codes
Codes are stored by their SHA-256 digest only and are spent with one conditional write. The code is spent first and its bindings checked after (client, exact redirect URI, PKCE verifier, user, company), so a code redeems once whatever the outcome. Of any number of simultaneous redemptions exactly one succeeds. A code presented again is refused and revokes the refresh family it started.
The access token
An RFC 9068 JWT addressed to one resource, carrying only iss, aud, sub,
client_id, scope, iat, exp and jti, valid for five minutes. sub is a
pairwise identifier per client. Five minutes is also how long a revoked grant can
still be used: an access token is never recalled.
The ID token
A code granted openid also redeems for an ID token (OpenID Connect Core
§3.1.3.3): a JWT of type JWT, signed by the same key, addressed to the client
alone, living five minutes. It states how the user signed in, as the code
recorded it: auth_time, acr, amr, sid (the session's public id, never its
cookie), the request's nonce when one was sent, and at_hash binding it to the
access token beside it, under the same pairwise sub. It carries no profile or
contact data.
acr and amr come only from the methods verified in the sign-in behind the
code, never from what the account has enrolled or what the request asked for: the
server reads no acr_values. A recovery code counts as a one-time code. A passkey
verifies its user when the authenticator checked a PIN or a biometric. Passkeys
sync between devices, so no level claims a device-bound key.
| Methods verified in the sign-in | acr | amr |
|---|---|---|
| password | urn:tessaridb:acr:sf | pwd |
| one-time or recovery code alone | urn:tessaridb:acr:sf | otp |
| passkey that did not verify its user | urn:tessaridb:acr:sf | hwk |
| password and a one-time or recovery code | urn:tessaridb:acr:mfa | pwd, otp, mfa |
| password and a passkey that did not verify its user | urn:tessaridb:acr:mfa | pwd, hwk, mfa |
| passkey that verified its user | urn:tessaridb:acr:phr | hwk, mfa |
| password and a passkey that verified its user | urn:tessaridb:acr:phr | pwd, hwk, mfa |
sf is one factor category, mfa two different ones (something known and
something held), and phr a passkey that verified its user, which the browser
binds to this origin. A one-time code and a recovery code together are still one
category.
Refresh tokens
A client registered for refresh tokens also receives one and redeems it at the same endpoint (RFC 6749 §6). Refresh tokens rotate on every use and are kept as digests only. The request is judged on the family's grant before the token is rotated, so a refused refresh leaves the token usable. The new access token may be narrowed to fewer scopes or one of the grant's resources, never widened. A token presented after it was rotated revokes its whole family. A refresh token lives at most 14 days unused and 30 days in all.
Client credentials
A confidential client registered for client_credentials (RFC 6749 §4.4; a public
client cannot register it) gets a token of its own. It names its scopes within its
ceiling, never openid since no user signed in, and one of the resources it
registered. The token's sub is the client itself (RFC 9068 §2.2), and no refresh
token is issued.
DPoP
A request carrying a DPoP proof, one DPoP header verified for this endpoint and
spent once after every other check, receives a DPoP token naming the proof's key
in cnf.jkt. A client registered with dpop_bound_access_tokens is refused
without one, and a public client's refresh token keeps needing the key it was
issued to. Without a proof the token is Bearer.