RFC compliance matrix
Every standard the library actively cites in its code, mapped to the package that implements it and the option / feature that gates it.
Status legend
full implements the OP-facing surface the library claims for that spec end-to-end.
partial implements the parts the OP needs; some optional sections are out of scope by design.
planned in the spec list, not landed yet.
out out-of-scope; structurally not the library's concern.
refused deliberately rejected (e.g. alg=none).
OIDC core / discovery
| Standard | Status | Where |
|---|---|---|
| OpenID Connect Core 1.0 | partial (response_type=code only; Aggregated and Distributed claim types §5.6.2 are not emitted; pairwise sub §8.1 is now wired via op.WithPairwiseSubject. See "Out of scope by design" below.) | op/, internal/authorize, internal/tokenendpoint, internal/userinfo, internal/sector |
| OpenID Connect Discovery 1.0 | full | internal/discovery |
| OpenID Connect Dynamic Client Registration 1.0 | partial (core flow, sector_identifier_uri fetch, application_type=web / =native redirect rules, JWKs / pairwise / response-type cross-checks, PUT reserved-field rejection, post_logout_redirect_uris round-trip, and the five JWE alg/enc encrypted-response families are enforced; client_secret is intentionally omitted from GET /register/{id} responses, software_statement is not accepted) | internal/registrationendpoint |
| OpenID Connect RP-Initiated Logout 1.0 | full | internal/endsession |
| OpenID Connect Back-Channel Logout 1.0 | full | internal/backchannel |
| OpenID Connect Front-Channel Logout 1.0 | out (iframe / third-party-cookie signalling is intentionally not shipped; use Back-Channel Logout) | — |
| OpenID Connect Session Management 1.0 | out (third-party-cookie-dependent; back-channel preferred) | — |
| OpenID Connect CIBA Core 1.0 | partial (poll delivery only; ping / push deferred to v2+) | internal/ciba, internal/cibaendpoint, op.WithCIBA |
OAuth 2.0 core RFCs
| RFC | Status | Where / option |
|---|---|---|
| RFC 6749 OAuth 2.0 Framework | partial (authorization-code, refresh-token, and client-credentials surfaces; implicit and password grants are intentionally not implemented) | op/, internal/authorize, internal/tokenendpoint |
| RFC 6750 Bearer Token Usage | partial (OP-issued bearer tokens and OP-hosted resource endpoints such as UserInfo / introspection; general RS challenge behaviour belongs to resource servers) | internal/tokens, internal/userinfo, internal/introspectendpoint |
| RFC 6819 Threat Model & Security Considerations | partial (security guidance applied across the OP; not a standalone protocol surface) | whole codebase |
| RFC 7009 Token Revocation | full (gated by feature.Revoke) | internal/revokeendpoint |
| RFC 7521 Assertion Framework | partial (private_key_jwt client authentication only; assertion grants and client_secret_jwt are intentionally not implemented) | internal/clientauth |
| RFC 7523 JWT Bearer Assertions for Client Auth | partial (private_key_jwt; JWT bearer authorization grants and client_secret_jwt are not implemented, and client_secret_jwt is rejected at registration with invalid_client_metadata) | internal/clientauth |
| RFC 7591 Dynamic Client Registration | partial (gated by feature.DynamicRegistration; software_statement is rejected with invalid_software_statement) | internal/registrationendpoint |
| RFC 7592 DCR Management | partial (read / update / delete; PUT omission resets to server defaults rather than deleting fields, and the response only re-emits client_secret on a none → confidential auth-method upgrade or an explicit rotation request) | internal/registrationendpoint |
| RFC 7636 PKCE | full (only S256; plain refused) | internal/pkce |
| RFC 7662 Token Introspection | full (gated by feature.Introspect) | internal/introspectendpoint |
RFC 7800 Confirmation Methods (cnf) | full | internal/dpop, internal/mtls, internal/tokens |
| RFC 8252 OAuth 2.0 for Native Apps | partial (OP-side native redirect / loopback hardening; client-app behaviour is out of scope) | internal/registrationendpoint, internal/authorize |
| RFC 8414 Authorization Server Metadata | full | internal/discovery |
| RFC 8485 Vectors of Trust | partial (consumed via ACR/AAL mapping) | op/aal.go, op/acr.go |
| RFC 8628 Device Authorization Grant | full (gated by op.WithDeviceCodeGrant; slow_down ladder persisted atomically with LastPolledAt; op/devicecodekit ships the brute-force gate + revoke audit hook) | internal/devicecode, internal/devicecodeendpoint, op/devicecodekit |
| RFC 8693 OAuth 2.0 Token Exchange | full (gated by op.RegisterTokenExchange; act chain mandatory whenever actor differs from subject; cnf rebinding to request's verified DPoP / mTLS) | internal/customgrant/tokenexchange |
| RFC 8705 OAuth 2.0 mTLS Client Auth & Cert-Bound Tokens | full (gated by feature.MTLS; mtls_endpoint_aliases now published in discovery) | internal/mtls |
| RFC 8707 Resource Indicators | partial (canonicalisation and client allow-list enforcement across authorize / token / device / CIBA; v1.x issuance narrows most built-in grants to a single resource value) | internal/resourceindicator, internal/authorize, internal/tokenendpoint, internal/devicecodeendpoint, internal/cibaendpoint |
| RFC 8725 JWT Best Current Practices | full (alg allow-list, type checks) | internal/jose |
| RFC 9068 JWT Profile for Access Tokens | full | internal/tokens |
| RFC 9101 JAR (JWT-Secured Authorization Request) | full (gated by feature.JAR) | internal/jar |
| RFC 9126 PAR (Pushed Authorization Requests) | full (gated by feature.PAR) | internal/parendpoint |
| RFC 9207 OAuth 2.0 Authorization Server Issuer Identifier | full | internal/authorize (iss parameter on the response) |
RFC 9396 Rich Authorization Requests (authorization_details) | full (gated by op.WithAuthorizationDetailTypes; validated at /authorize, /par, /token, persisted on the grant, echoed on JWT access tokens and introspection, advertised in discovery) | internal/authorizationdetails, op/authorization_details.go |
| RFC 9449 DPoP | full incl. §8 nonce flow (gated by feature.DPoP) | internal/dpop, op.WithDPoPNonceSource |
| RFC 9470 OAuth 2.0 Step Up Authentication Challenge | full (OP honours acr_values / max_age re-authentication via ACR rules; op.StepUpChallenge builds the resource-server WWW-Authenticate challenge the embedder's RS returns) | op/rule.go (RuleACR), op/stepup.go |
| RFC 9700 OAuth 2.0 Security Best Current Practice | partial (OP-side BCP posture; resource-server and client-side requirements remain with embedders) | whole codebase |
| RFC 9701 JWT Response for OAuth 2.0 Token Introspection | full (signed JWT default; JWE-wrapped per client introspection_encrypted_response_alg / _enc metadata) | internal/introspectendpoint, internal/jose |
| RFC 9728 OAuth 2.0 Protected Resource Metadata | full (gated by op.WithProtectedResources; served at /.well-known/oauth-protected-resource with the issuer stamped into authorization_servers) | internal/protectedresource, op/protected_resource.go |
IETF drafts
| Draft | Status | Where |
|---|---|---|
OAuth 2.0 Grant Management (draft-ietf-oauth-grant-management) | partial (gated by op.WithGrantManagement; grant_management_action / grant_id honoured, query / revoke endpoint mounted, grant_id on the token response, discovery advertisement. Tracks an IETF draft — surface may change before v1.0) | internal/grantmgmtendpoint, op/grant_management.go |
JOSE family
| RFC | Status | Where |
|---|---|---|
| RFC 7515 JWS | partial (compact JWS surfaces used by JWT / JAR / JARM / DPoP / client assertions; general JSON serialization is not exposed) | internal/jose |
| RFC 7516 JWE | partial — closed allow-list (RSA-OAEP-256 / ECDH-ES{,+A128KW,+A256KW} × A{128,256}GCM). Inbound JWE request_object (JAR / PAR §6.1), outbound JWE id_token, JWT-shape userinfo, JARM authorization response, and RFC 9701 introspection response wired. RSA1_5 refused (CVE-2017-11424 padding oracle); RSA-OAEP-384/512, dir, symmetric-only A*KW deferred to v2+ | internal/jose, op.WithEncryptionKeyset |
| RFC 7517 JWK | partial (JWK Set publication and client JWKS consumption for supported asymmetric key types; symmetric oct keys are not accepted for signing) | internal/jwks |
| RFC 7518 JWA | partial — issuance is ES256 only; verification accepts RS256, PS256, ES256, EdDSA. HS* and none refused | internal/jose |
| RFC 7519 JWT | partial (signed / encrypted JWT surfaces used by OIDC and OAuth extensions; unsecured JWTs are refused) | internal/jose |
| RFC 7638 JWK Thumbprint | full (used by DPoP cnf.jkt) | internal/dpop |
RFC 8037 Edwards-curve DSA / EdDSA | partial (Ed25519; Ed448 not enabled) | internal/jose |
FAPI family
| Profile | Status | Switch |
|---|---|---|
| FAPI 2.0 Baseline | full (continuously regressed; see OFCS) | op.WithProfile(profile.FAPI2Baseline) |
| FAPI 2.0 Message Signing | full (continuously regressed) | op.WithProfile(profile.FAPI2MessageSigning) |
| FAPI 1.0 Advanced | out | — (use FAPI 2.0) |
| FAPI-CIBA | full (poll mode; enforces JAR + DPoP|MTLS, 10-min access TTL, FAPI 2.0 client-auth set, requested_expiry ≤ 600 s, JAR iss / aud / exp / nbf required, request-object lifetime ≤ 60 min per FAPI 2.0 Message Signing §5.6, access-token revocation required) | op.WithProfile(profile.FAPICIBA) |
| OpenID iGov High | planned for v2 | profile.IGovHigh (constant exists; op.New rejects it today because the runtime constraints have not landed) |
Other RFCs the library cites
| RFC | Use |
|---|---|
| RFC 1918 | Private-network deny-list for back-channel logout SSRF defense |
| RFC 2606 | Reserved example domains in tests / examples |
| RFC 3986 | URI parsing |
| RFC 4122 | UUIDv4 generation |
| RFC 4226 | HOTP building block used by the TOTP authenticator |
| RFC 4514 | DN handling for mTLS subject DN |
| RFC 4648 | Base64url encoding |
| RFC 5280 | X.509 cert validation |
| RFC 5321 | SMTP address length bounds for email OTP inputs |
| RFC 6238 | TOTP authenticator |
| RFC 6265 | Cookie syntax |
| RFC 6711 | Authentication Context Class Reference values registry |
| RFC 7230 / 7231 / 7232 / 7235 | HTTP/1.1 (now superseded by RFC 9110) |
| RFC 7239 | Forwarded header parsing for trusted-proxy handling |
| RFC 7807 | application/problem+json (selected error paths) |
| RFC 8017 | RSA-PSS / RSA-OAEP algorithm references through JOSE |
| RFC 8141 | URN handling for PAR request_uri values |
| RFC 8176 | AMR values registry |
| RFC 8259 | JSON |
| RFC 9110 | HTTP semantics |
Out of scope by design
A handful of OIDC Core / OAuth surfaces are intentionally not implemented. The library tracks each one as a row with status: out-of-scope in the scenario catalog (test/scenarios/catalog/<feature>.yaml) so the policy is auditable alongside the tests that pin everything else.
response_typeiscodeonly. Implicit (id_token,id_token token), hybrid (code id_token, ...), andresponse_type=noneare not issued. RFC 9700 §1.4 deprecates the implicit grant; FAPI 2.0 mandates code. Discovery advertisesresponse_types_supported: ["code"].fragmentresponse mode is not wired. Withcode-only issuance there is nothing to put in the URL fragment.queryandform_postare both implemented (the latter renders an auto-submitting HTML form per OIDC Core Form Post Response Mode 1.0); whenfeature.JARMis on, the four*.jwtvariants are also wired. Discovery advertisesresponse_modes_supported: ["query", "form_post"]by default and appends*.jwtmodes when JARM is enabled.- Aggregated and Distributed claim types (OIDC Core §5.6.2) are not emitted. Only Normal claims are produced; the
_claim_names/_claim_sourceskeys never appear in tokens or UserInfo responses. client_secret_jwtis refused at registration. Useprivate_key_jwtinstead. The HMAC-shared-secret JWT profile is rejected withinvalid_client_metadata: token_endpoint_auth_method client_secret_jwt is not supported.- JWE alg / enc allow-list is closed. The default set is
RSA-OAEP-256+ECDH-ES{,+A128KW,+A256KW}for key-wrap andA{128,256}GCMfor content.WithSupportedEncryptionAlgscan narrow but not extend.RSA1_5is permanently rejected (CVE-2017-11424);RSA-OAEP-384/RSA-OAEP-512,dir, and symmetric-onlyA*KWare deferred to v2+. - CIBA push and ping delivery modes are not implemented. Discovery advertises
backchannel_token_delivery_modes_supported: ["poll"]exclusively so a client cannot negotiate them. - Custom-grant handlers cannot supply refresh-token values. A handler that wants refresh issuance sets
CustomGrantResponse.IssueRefreshToken; the OP mints and persists the credential through its ownRefreshTokenStore, preserving lineage, rotation, replay cascade, and DPoP / mTLS binding. If the client is not registered forrefresh_token, the access-token response still succeeds andcustom_grant.refresh_droppedrecords the omission.
Out of scope (intentional)
Not every RFC in the OAuth / OIDC sphere is the OP's responsibility. The library deliberately doesn't ship support for the following — they belong to the resource server, the client SDK, or other layers.
| RFC / Spec | Status | Notes |
|---|---|---|
| RFC 9421 — HTTP Message Signatures | out | Resource-server (API protection) concern, not OP. The OP-side equivalents are JAR (RFC 9101) for signed authorization requests, JARM for signed authorization responses, and DPoP (RFC 9449) for proof-of-possession on /token and /userinfo. RS-side HTTP signing is the embedder's responsibility. |
Verification
The list is grepped from the live source under op/ and internal/. You can audit it yourself:
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
grep -rhoE 'RFC [0-9]+' op/ internal/ | sort -uThe list above mirrors the output of that command, with the ones that are normative-for-the-library called out and the ones that are incidental references rolled up in "Other".