| Discovery |
OIDC Discovery 1.0, RFC 8414 |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oidc/discovery.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts |
Metadata is generated from TenantContext. ssf_configuration_endpoint is not advertised (SSF stays a 501 stub); dpop_signing_alg_values_supported matches the enforced ES256/RS256/PS256 allowlist; scopes_supported drops address (no address data in the user model) and includes organization; claims_supported matches the claims actually emitted and includes sid (carried on session-linked grant chains); authorization_response_iss_parameter_supported=true (RFC 9207). |
| JWKS |
OIDC Core 1.0 |
implemented |
L1/L2 |
apps/server/worker/oidc/jwks.ts, packages/crypto/src/jwks.ts |
apps/server/worker/oidc/__tests__/discovery.test.ts, packages/crypto/src/__tests__/jwks.test.ts |
Public keys only, active kid included. |
| ID token code flow |
OIDC Core 1.0 |
implemented |
L1/L2 |
apps/server/worker/oidc/token-issue.ts, packages/protocol/src/tokens.ts |
apps/server/worker/oidc/__tests__/token.test.ts, packages/protocol/src/__tests__/tokens.test.ts |
Code flow signs id_token from instance key. ID tokens carry sid when the grant chain is bound to a hosted session (authorization codes persist session_id, refresh records inherit it through rotation); sessionless grants (client_credentials, token-exchange, device) omit sid; check_session uses the separate session_state mechanism and logout_token takes sid from the session. |
| Nonce |
OIDC Core 1.0 |
implemented |
L1/L2 |
apps/server/worker/oidc/authorize.ts, apps/server/worker/oidc/token-grants.ts, apps/server/worker/oidc/token-issue.ts, packages/protocol/src/authorize.ts, packages/protocol/src/tokens.ts |
apps/server/worker/oidc/__tests__/token.test.ts, apps/server/worker/oidc/__tests__/authorize.test.ts, packages/protocol/src/__tests__/authorize.test.ts, packages/protocol/src/__tests__/tokens.test.ts |
Persisted from authorize code to id_token. |
| Userinfo |
OIDC Core 1.0 |
implemented |
L1/L2/L3 |
apps/server/worker/oidc/userinfo.ts |
apps/server/worker/oidc/__tests__/userinfo.test.ts, apps/server/tests/smoke/l3-protocol-client.test.mjs |
Scope projection exists; scope=phone emits phone_number/phone_number_verified from user_phones. Public-client CORS preflight uses an origin allowlist shared with /token, and success responses carry Pragma: no-cache. Local L3 protocol client smoke verifies DPoP userinfo claims from a live access token. |
| RP-initiated logout |
OIDC RP-Initiated Logout |
implemented |
L1/L2 |
apps/server/worker/oidc/end-session.ts |
apps/server/worker/oidc/__tests__/end-session.test.ts |
RP logout revokes the local session, validates post logout redirects, and triggers Back-Channel Logout delivery when the client has registered a URI. |
| ACR/AMR/auth_time |
OIDC Core 1.0 |
implemented |
L1/L2 |
apps/server/worker/lib/auth-context.ts, apps/server/worker/lib/session.ts, apps/server/worker/oidc/authorize.ts, apps/server/worker/oidc/token-grants.ts, apps/server/worker/oidc/token-issue.ts, apps/server/worker/me-auth/passkey-mfa-challenge.ts |
apps/server/worker/lib/__tests__/session.test.ts, apps/server/worker/me-auth/__tests__/mfa-challenge.test.ts, apps/server/worker/me-auth/__tests__/passkey-mfa-challenge.test.ts, apps/server/worker/oidc/__tests__/authorize.test.ts, apps/server/worker/oidc/__tests__/token.test.ts, apps/server/worker/oidc/__tests__/token-issue.test.ts |
acr/amr/auth_time persist from session to authorization code, refresh family, access token, and id_token for the supported AAL1/AAL2 mappings. Requests for urn:xid:aal3 return an explicit interaction_required error because current WebAuthn evidence does not prove NIST AAL3. Legacy AAL3 state is normalized to AAL2 before re-issuance. |
| Hybrid response type |
OIDC Core 1.0 |
implemented |
L1/L2 |
packages/protocol/src/authorize.ts, packages/protocol/src/tokens.ts, packages/protocol/src/discovery.ts, apps/server/worker/oidc/authorize.ts, apps/server/worker/oauth/register.ts |
packages/protocol/src/__tests__/authorize.test.ts, apps/server/worker/oidc/__tests__/authorize.test.ts, apps/server/worker/oauth/__tests__/register.test.ts, packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts |
Discovery and DCR support code id_token; authorize returns code and signed id_token through the fragment by default. Route tests verify nonce, c_hash, and absence of at_hash for the hybrid front-channel id_token. |
| Form post response mode |
OAuth Form Post Response Mode |
implemented |
L1/L2 |
apps/server/worker/oidc/authorize-respond.ts, apps/server/worker/oidc/authorize.ts |
apps/server/worker/oidc/__tests__/authorize.test.ts |
Route tests cover form_post HTML form response and fragment redirect mode. |
| OIDC Dynamic Client Registration |
OIDC Registration 1.0 |
implemented |
L1/L2 |
apps/server/worker/oauth/register.ts |
apps/server/worker/oauth/__tests__/register.test.ts |
Supports redirect URIs, post logout redirect URIs, Back-Channel Logout URI, public subject type, ES256 ID token signing metadata, JWKS for private_key_jwt clients, and registration access token read/update/delete. Unsupported sector identifiers, request URIs, front-channel logout URI, and non-ES256 ID token alg metadata are rejected. backchannel_logout_session_required is persisted and round-trips through create, read, and update because logout_token always carries sid. Error responses use the RFC {error, error_description} shape with RFC7591 codes. |
| Front-channel logout |
OIDC Front-Channel Logout |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oauth/register.ts, apps/server/worker/oidc/end-session.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts, apps/server/worker/oauth/__tests__/register.test.ts, apps/server/worker/oidc/__tests__/end-session.test.ts, apps/site/src/lib/docs-registry.test.ts |
Discovery advertises frontchannel_logout_supported=true; DCR accepts frontchannel_logout_uri; /end_session renders hidden iframe logout HTML when the client registered a front-channel URI. Scope: IdP-initiated only, single client, iframe rendered only when no post_logout_redirect_uri redirect fires; the RP-side /frontchannel_logout receiver endpoint does not exist here and remains the RP's own responsibility. |
| Back-channel logout profile |
OIDC Back-Channel Logout |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oauth/register.ts, apps/server/worker/oidc/end-session.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts, apps/server/worker/oauth/__tests__/register.test.ts, apps/server/worker/oidc/__tests__/end-session.test.ts |
Discovery advertises backchannel_logout_supported=true and backchannel_logout_session_supported=true; DCR persists HTTPS no-fragment backchannel_logout_uri plus backchannel_logout_session_required across create, read, and update; /end_session sends a signed logout+jwt form POST with logout event, sid (always present), and sub. |
| Session Management |
OIDC Session Management |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oidc/check-session.ts, apps/server/worker/oidc/session-state.ts, apps/server/worker/oidc/index.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/check-session.test.ts, apps/site/src/lib/docs-registry.test.ts |
Discovery advertises check_session_iframe; /check_session compares RP session_state against OP state derived from the browser session and salt cookie. Full RP logout coordination remains outside current scope. |
| CIBA |
OIDC CIBA Core |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oidc/ciba.ts, apps/server/worker/durable-objects/ciba-store.ts, apps/server/worker/oidc/token.ts, apps/server/worker/me-auth/ciba-activation.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/ciba.test.ts, apps/server/worker/durable-objects/__tests__/ciba-store.test.ts, apps/site/src/lib/docs-registry.test.ts |
Discovery advertises backchannel_authentication_endpoint; POST /backchannel_authentication creates a 256-bit CSPRNG base64url auth_req_id and one CibaStore Durable Object for it; authenticated /auth/ciba-activation approves or denies requests with login_hint binding. The Durable Object atomically reserves an approved request as an expiring issuing lease with a fencing token. Signing and optional D1 refresh persistence run under that reservation; failures roll back the refresh row and abort to approved, while success alone finalizes consumed. A poll while the lease is active returns recoverable authorization_pending; an expired lease can be replaced without allowing its stale owner to finalize. Finalize is idempotent for its fencing token; the Worker retries once after an ambiguous response and then confirms the stored terminal record before discarding the in-memory token response. A token endpoint response lost after the Worker has returned remains the normal one-time-grant transport ambiguity; XID does not persist replayable bearer-token responses in the Durable Object. Notification UX and production L4 evidence are not claimed. |
| Federation |
OpenID Federation 1.0 |
implemented |
L1/L2 |
packages/protocol/src/discovery.ts, apps/server/worker/oidc/federation.ts, apps/server/worker/oidc/index.ts |
packages/protocol/src/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/discovery.test.ts, apps/server/worker/oidc/__tests__/federation.test.ts, apps/site/src/lib/docs-registry.test.ts |
Discovery advertises federation metadata; POST /federation_registration is instance-manager gated. Full trust-chain resolution is not claimed. |
| FAPI 2.0 |
OpenID FAPI 2.0 Security Profile, OpenID FAPI 2.0 Message Signing |
implemented |
L1/L2 |
apps/server/worker/oidc/client-policy.ts, apps/server/worker/oidc/par.ts, apps/server/worker/oidc/request-object.ts, apps/server/worker/oidc/dpop.ts, apps/server/worker/oidc/mtls.ts, apps/server/worker/oauth/register.ts, apps/server/worker/oidc/authorize.ts, apps/server/worker/oidc/token.ts, packages/protocol/src/discovery.ts |
apps/server/worker/oidc/__tests__/fapi.test.ts, apps/server/worker/oidc/__tests__/par.test.ts, apps/server/worker/oidc/__tests__/token-security.test.ts, apps/server/worker/oauth/__tests__/register.test.ts, apps/server/worker/oidc/__tests__/authorize.test.ts, packages/protocol/src/__tests__/discovery.test.ts, apps/site/src/lib/docs-registry.test.ts |
Clients with fapi_profile require PAR (request_uri), PKCE S256 at authorize, and DPoP or mTLS sender-constraint at token. Discovery advertises fapi_profile_supported only when tenant oidcProfiles.fapiProfileSupported is enabled. Production FAPI conformance is not L4 claimed. |