Accepted tokens

Every door on this service that takes a token from a caller, what it must be to get through, and what happens in each mode. It is a companion to What is not checked, which covers passwords, assertions, certificates and everything else. This page covers the one question that page used to answer badly: will a token this service did not issue get through?

The short answer is no, except at the three OpenID4VCI endpoints in development mode. Every other door below verifies.

“Verifies” here means the signature verifies against the realm’s own signing key (the one published at /oauth2/jwks, or the realm’s own under /realm/{id}/), the token is inside its exp and nbf, and — unless the row says otherwise — its jti has not been revoked on /admin/tokens. Every token this service signs is signed with the same key, so a door that needs an access token also reads typ to tell one from an ID Token or a refresh token. An access token also meets RFC 9068 section 4 wherever it is presented: an at+jwt header, an issuer this service publishes at the address the request arrived on, and this resource server in aud.

This list was made by reading the code. It is not generated, and a door added since may not be on it. The live list of endpoints is /admin/sts-metadata.

Access tokens at a resource

Door Must be Development Product
GET/POST /oauth2/userinfo Verified, typ Bearer, not revoked, carrying openid The same The same
/scim/v2 (Bearer or DPoP) Verified, typ Bearer, not revoked, carrying scim:read or scim:write. SCIM’s other five credential schemes are separate The same The same
The Shared Signals endpoints Verified, typ Bearer, carrying ssf:read or ssf:write The same The same
The step-up resource (RFC 9470) Verified, then assessed against oauth2.stepUpAcrValues and max_age The same The same
/admin-api Verified against the default realm’s key, or the ambient realm’s under a realm prefix, audienced to the API, carrying admin:read or admin:write. A realm’s token is confined to that realm The same The same
The embedded debugger’s listener Verified, audienced to urn:sts:debugger-api:, carrying the debugger permission, which only a console administrator is issued The same The same
The OpenID4VCI credential, deferred credential and notification endpoints A token this realm issued is verified like any other A token this realm cannot verify is read without verifying, because OpenID4VCI lets the authorization server be somebody else. A credential issued that way can never be used to sign in Refused, and so is a revoked one (invalid_token)
The GNAP resource server (/gnap/rs/*) A token the GNAP authorization server holds a record of and has not revoked or expired, under the scheme its binding needs (Bearer for a bearer token, GNAP with a key proof otherwise). Nothing is decoded The same The same

Any of the OAuth rows above that is presented with the DPoP scheme also needs a proof that verifies against the token’s cnf.jkt, and a certificate-bound token needs the certificate on the connection (RFC 8705). Four settings make one of the two mandatory; see Require DPoP or mutual TLS in What is not checked.

Tokens handed to the authorization server

Door Token Development Product
POST /oauth2/introspect token A token that does not verify, or was revoked, is {"active": false}. The caller authenticates for an RFC 9701 JWT response The same, and the caller authenticates for a JSON response too
POST /oauth2/revoke token An access or refresh token is revoked if it verifies (a refresh token with its whole grant); otherwise nothing is revoked and the answer is still 200, as RFC 7009 says. Any other token this realm signed, an ID Token for one, is unsupported_token_type. A caller with no credential is not authenticated; one that presents a credential is, and may revoke only its own client’s tokens (invalid_grant otherwise) The client authenticates, or a public client names its registered client_id, and may revoke only its own tokens
POST /oauth2/token, grant_type=refresh_token refresh_token Opened, verified, not revoked. Whether it was issued to the client presenting it, and whether the scope asked for is no wider than the one granted, is checked only in RFC 9700 or OAuth 2.1 mode Product implies RFC 9700 mode, so both are checked, and a refresh token presented twice revokes its whole family
POST /oauth2/token, token exchange (RFC 8693) subject_token, actor_token Read without verifying if they do not verify, so a client under test can exchange a token from anywhere Verified and not revoked, or refused with invalid_request. The token’s typ is not compared with the declared subject_token_type — #116
POST /oauth2/token, JWT or SAML bearer grant; JWT client authentication assertion, client_assertion Verified against a key registered for a declared issuer, accepted once ever. See JWT assertions and SAML 2.0 assertions The same
GET/PUT/DELETE /oauth2/register/{client_id} (RFC 7592) The registration access token Compared with the one issued at registration, in constant time; an empty one never matches The same
GET/POST /oauth2/logout (RP-Initiated Logout) id_token_hint Verified as an ID Token this authorization server issued (an expired one still counts); its audience is the client, and a client_id it was not issued to is refused. A hint for the current session signs out at once; otherwise the person confirms (#124, #115) The same

Other tokens

Door Token Development Product
SPIFFE ValidateJWTSVID A JWT-SVID Verified against the bundle of the trust domain its sub names, with the audience the caller gives and no clock leeway. A trust domain with no bundle is refused The same
POST /ssf/receive A Security Event Token Recorded whether or not it verifies, and shown as unverified. Nothing acts on it Refused (400 invalid_key) — #117
The console’s and portal’s own SSF receivers A Security Event Token The stream’s own authorization secret, and this receiver in aud. An unverified one is recorded unless ssf.receiveRequireSignature is on, and is never acted on. A verified one the signal-response policy permits is recorded as what it would have ended, unless ssf.actOnSignalsInDevelopment is on An unverified one is refused (400 invalid_key, #117); a verified one the signal-response policy permits ends the surface’s own sessions for the person named

Where the two open issues are

Issue What
#116 Token exchange in product mode accepts an ID Token as a subject_token declared to be an access token
#117 /ssf/receive stores Security Event Tokens it cannot verify in product mode as well as development