Skip to content

OIDC and OAuth

masks is an OpenID Connect provider. This page lists each specification it implements and the parts it leaves out.

Four OpenID Foundation certification plans pass with no failures: oidcc-config and oidcc-basic with 2,194 conditions, oidcc-rp-initiated-logout with 642, and oidcc-backchannel-rp-initiated-logout with 104. ./dev conformance runs all four against a local server.

✅ Implemented, covered by the test suite, and passing its conformance plan where one exists.
◐ Partly implemented. The Coverage column names the parts left out.
✗ Not implemented, and the discovery document says so.
Specification Status Coverage
OpenID Connect Core 1.0 ✅ The authorization code flow, ID tokens, userinfo, prompt, max_age, acr and amr, and the claims parameter.
OpenID Connect Discovery 1.0 ✅ /.well-known/openid-configuration, one for each tenant.
OpenID Connect Dynamic Registration 1.0 ✅ Bounded by the tenant’s ceiling.
OAuth 2.0 (RFC 6749) ◐ The authorization_code, refresh_token, and client_credentials grants. The implicit and password grants are not offered.
Bearer tokens (RFC 6750) ✅ The userinfo endpoint reads a bearer token from the Authorization header, a form-encoded body, or the access_token query parameter.
JWT (RFC 7519) ✅ RS256, with a signing key for each tenant. ID tokens are typed JWT, access tokens at+jwt, and logout tokens logout+jwt.
JWK (RFC 7517) ✅ /.well-known/jwks.json, which also publishes staged and retired keys during a rotation.

The only response type is code, and the only response mode is query.

Specification Status Coverage
PKCE (RFC 7636) ✅ S256 only. Every public client must send a challenge.
Pushed authorization requests (RFC 9126) ✅ A client can be required to use them. See pushed requests.
DPoP (RFC 9449) ✅ Includes dpop_jkt, bound refresh tokens, and dpop_bound_access_tokens. See binding a token with DPoP.
Issuer identification (RFC 9207) ✅ iss on every authorization response.
Rich authorization requests (RFC 9396) ✅ authorization_details at /authorize, /par, in a signed request, and at the token endpoint for the code, refresh, and exchange grants, each checked against the type an approved client declared. See rich authorization requests.
Resource indicators (RFC 8707) ✅ resource narrows the audience at both the authorization and token endpoints.
Request objects, JAR (RFC 9101) ◐ A signed request at /authorize and /par, and a client can be required to sign. See signed requests. The only request_uri accepted is one issued by /par. Encrypted request objects are not read.
FAPI 2.0 ◐ PAR, PKCE, private_key_jwt, DPoP, iss on the response, and signed requests, each of which a client can be required to use. The FAPI certification plan has not been run.
Specification Status Coverage
Device authorization (RFC 8628) ✅ See device sign-in.
Token exchange (RFC 8693) ✅ Access tokens and ID tokens as the subject, actor tokens, a nested act chain, and a provider’s access token for a delegation. Tokens signed by other issuers are not exchanged. See exchanging a token.
client_credentials ✅ For an approved client that authenticates. The token holds only scopes that do not act for a person. See signing in as itself.
Specification Status Coverage
Introspection (RFC 7662) ✅ A client can introspect its own tokens and the tokens issued for a resource it serves.
Revocation (RFC 7009) ✅ Revoking a refresh token also revokes the refresh tokens rotated from it and every access token issued from the same grant.
JWT access tokens (RFC 9068) ✅ Typed at+jwt, with jti, client_id, scope, aud, and cnf. An endpoint that expects an access token refuses a token of any other type.
Dynamic registration (RFC 7591) ✅
Registration management (RFC 7592) ✅ Read, update, and delete with a registration access token.
Client ID metadata documents ✅ A client_id that is an https URL is read as the client’s metadata, within the tenant’s ceiling. See a client named by its metadata document.
Protected resource metadata (RFC 9728) ✅ /.well-known/oauth-protected-resource.
Specification Status Coverage
Back-channel logout 1.0 ✅ Signed logout tokens. Delivery is attempted up to five times, and a delivery that still fails is recorded as an event.
RP-initiated logout 1.0 ✅ end_session_endpoint, with id_token_hint, client_id, post_logout_redirect_uri, and state. A request with no hint for the signed-in person asks before signing out.
Front-channel logout 1.0 ✗ Discovery sets frontchannel_logout_supported to false.
Session management 1.0 ✗ Not planned, because current browsers block the iframe it depends on. Discovery has no check_session_iframe.
Specification Status Coverage
Pairwise subject identifiers ✅ Includes a verified sector_identifier_uri. See subject identifiers.
WebAuthn Level 2 ✅ Passkeys, as a first factor or a second factor.
TOTP (RFC 6238) ✅ With backup codes.
SCIM 2.0 ◐ /Users with filters, PATCH, ETags, and suspension, /Groups as an organization’s roles, and the discovery endpoints. See provisioning. Bulk operations and sorting are not implemented.
SAML 2.0 ◐ Both directions. A SAML identity provider can sign people in to masks (see providers), and masks signs people in to SAML applications over HTTP-Redirect and HTTP-POST, checking signed requests (see SAML applications). Single logout and encrypted assertions are not implemented.

The token endpoint accepts four authentication methods.

client_secret_basic The secret in an HTTP Basic Authorization header. The default for a client added in /manage.
client_secret_post The secret in the form body.
private_key_jwt A JWT assertion (RFC 7523) signed with RSA, RSA-PSS, or ECDSA, checked against the client’s jwks or jwks_uri.
none A public client, which must use PKCE.

See client authentication for how each is configured.

client_secret_jwt is not offered, because masks stores only a hash of a client secret. Mutual TLS (RFC 8705) is not implemented.