Skip to content

RFC compliance matrix ​

Every standard the library cites in its code, mapped to the package that implements it and the option or feature that gates it. Read the status column first (see the legend below), then the parenthesis: it names what is and is not covered.

How a specification is classified
Every specification in the matrix is first sorted by whether it is the OP's concern at all. What is the OP's concern is then marked full, partial or planned; what is not is marked out of scope or refused.A specificationRFC · OIDC · FAPIone row in the matrixIs it the OP's concern?some specs tell an RP or aresource server what to doYes — the OP's concernfullpartialplannedNo — outside the OPout of scoperefused
"Out of scope" and "refused" are different claims. The first says the specification is somebody else's job; the second says it is the OP's job and this OP declines it on purpose, with the reasoning recorded.

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).

These labels describe implementation coverage, not OpenID Foundation certification. A full label does not override requirements outside this library's stated scope; the exceptions in each row still apply.

OIDC core / discovery ​

StandardStatusWhere
OpenID Connect Core 1.0partial (response_type=code only)op/, internal/authorize, internal/tokenendpoint, internal/userinfo, internal/sector
OpenID Connect Discovery 1.0partial (metadata endpoint is implemented)internal/discovery
OpenID Connect Dynamic Client Registration 1.0partial (core flow and registration-metadata checks are enforced)internal/registrationendpoint
OpenID Connect RP-Initiated Logout 1.0fullinternal/endsession
OpenID Connect Back-Channel Logout 1.0fullinternal/backchannel
OpenID Connect Prompt Create 1.0full (prompt=create is accepted when LoginFlow.Registration is configured and advertised in prompt_values_supported)internal/authorize, internal/authn, internal/discovery
OpenID Connect Front-Channel Logout 1.0out (iframe / third-party-cookie signalling is intentionally not shipped; use Back-Channel Logout)—
OpenID Connect Session Management 1.0out (third-party-cookie-dependent; back-channel preferred)—
OpenID Connect CIBA Core 1.0partial (poll delivery only; ping / push deferred to v2+)internal/ciba, internal/cibaendpoint, op.WithCIBAGrant
  • OpenID Connect Core 1.0: Aggregated and Distributed claim types §5.6.2 are not emitted; pairwise sub §8.1 is supported through op.WithPairwiseSubject. See "Out of scope by design" below.
  • OpenID Connect Discovery 1.0: With the default ES256, id_token_signing_alg_values_supported omits RS256, which Discovery requires; an OP built with op.WithSigningAlgorithm(op.AlgRS256) advertises RS256
  • OpenID Connect Dynamic Client Registration 1.0: Enforced: 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. client_secret is intentionally omitted from GET /register/{id} responses, software_statement is not accepted

OAuth 2.0 core RFCs ​

RFCStatusWhere / option
RFC 6749 OAuth 2.0 Frameworkpartial (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 Usagepartial (OP-issued bearer tokens and OP-hosted resource endpoints such as UserInfo / introspection)internal/tokens, internal/userinfo, internal/introspectendpoint
RFC 6819 Threat Model & Security Considerationspartial (security guidance applied across the OP; not a standalone protocol surface)whole codebase
RFC 7009 Token Revocationfull (gated by feature.Revoke)internal/revokeendpoint
RFC 7521 Assertion Frameworkpartial (private_key_jwt client authentication and the JWT bearer authorization grant)internal/clientauth, internal/assertiongrant
RFC 7523 JWT Bearer Assertions for Client Auth and Authorization Grantspartial (private_key_jwt)internal/clientauth, internal/assertiongrant, internal/tokenendpoint
RFC 7591 Dynamic Client Registrationpartial (enabled by op.WithDynamicRegistration; software_statement is rejected with invalid_software_statement)internal/registrationendpoint
RFC 7592 DCR Managementpartial (read / update / delete)internal/registrationendpoint
RFC 7636 PKCEfull (only S256; plain refused)internal/pkce
RFC 7662 Token Introspectionfull (gated by feature.Introspect; an active refresh token reports no token_type, so a resource server cannot mistake it for an access token)internal/introspectendpoint
RFC 7800 Confirmation Methods (cnf)fullinternal/dpop, internal/mtls, internal/tokens
RFC 8252 OAuth 2.0 for Native Appspartial (OP-side native redirect / loopback hardening; client-app behaviour is out of scope)internal/registrationendpoint, internal/authorize
RFC 8414 Authorization Server Metadatafullinternal/discovery
RFC 8485 Vectors of Trustpartial (consumed via ACR/AAL mapping)op/aal.go, op/acr.go
RFC 8628 Device Authorization Grantfull (gated by op.WithDeviceCodeGrant)internal/devicecode, internal/devicecodeendpoint, op/devicecodekit
RFC 8693 OAuth 2.0 Token Exchangefull (gated by op.WithTokenExchangeGrant)internal/customgrant/tokenexchange
RFC 8705 OAuth 2.0 mTLS Client Auth & Cert-Bound Tokensfull (feature.MTLS wires certificate-bound access tokens, mtls_endpoint_aliases, and tls_client_auth / self_signed_tls_client_auth client authentication at every client-authenticating endpoint)internal/mtls
RFC 8707 Resource Indicatorspartial (canonicalisation and client allow-list enforcement across authorize / token / device / CIBA)internal/resourceindicator, internal/authorize, internal/tokenendpoint, internal/devicecodeendpoint, internal/cibaendpoint
RFC 8725 JWT Best Current Practicesfull (alg allow-list, type checks)internal/jose
RFC 9068 JWT Profile for Access Tokenspartial (JWT issuance uses the OP's single algorithm, ES256 by default)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 Identifierfullinternal/authorize (iss parameter on the response)
RFC 9396 Rich Authorization Requests (authorization_details)full (gated by op.WithAuthorizationDetailTypes)internal/authorizationdetails, op/authorization_details.go
RFC 9449 DPoPfull incl. §8 nonce flow (gated by feature.DPoP)internal/dpop, op.WithDPoPNonceSource
RFC 9470 OAuth 2.0 Step Up Authentication Challengefull (OP honours acr_values / max_age reauthentication via ACR rules)op/rule.go (RuleACR), op/stepup.go
RFC 9700 OAuth 2.0 Security Best Current Practicepartial (OP-side BCP posture, including refresh-token rotation with replay cascade per §2.2.2)whole codebase
RFC 9701 JWT Response for OAuth 2.0 Token Introspectionfull (signed JWT default; JWE-wrapped per client introspection_encrypted_response_alg / _enc metadata)internal/introspectendpoint, internal/jose
RFC 9728 OAuth 2.0 Protected Resource Metadatafull (gated by op.WithProtectedResources; served at /.well-known/oauth-protected-resource with the issuer stamped into authorization_servers)internal/protectedresource, op/protected_resource.go
  • RFC 6750 Bearer Token Usage: General RS challenge behaviour belongs to resource servers
  • RFC 7009 Token Revocation: Revoking a refresh token revokes its whole rotation chain however long it has grown, plus the grant's access tokens; the user's other refresh chains on the same client stay usable
  • RFC 7521 Assertion Framework: The SAML bearer grant and client_secret_jwt are intentionally not implemented
  • RFC 7523 JWT Bearer Assertions for Client Auth and Authorization Grants: An assertion with an empty or over-long jti is rejected, and a client JWKS fetch fault answers 503 instead of invalid_client. The urn:ietf:params:oauth:grant-type:jwt-bearer grant is implemented for assertions from explicitly trusted issuers, and every assertion is single-use by jti. client_secret_jwt is not implemented and is rejected at registration with invalid_client_metadata
  • RFC 7591 Dynamic Client Registration: A client record carrying both jwks and jwks_uri is refused on every surface, as §2 forbids the pair
  • RFC 7592 DCR Management: 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
  • RFC 8628 Device Authorization Grant: slow_down ladder persisted atomically with LastPolledAt; redemption records a store.Grant, so revocation and pairwise /userinfo reach the tokens; op/devicecodekit ships the brute-force gate and a Revoke helper that cascades under the grant and, given Deps.Grants, deletes the grant record
  • RFC 8693 OAuth 2.0 Token Exchange: act chain mandatory whenever actor differs from subject, nesting the subject_token's own chain up to five levels; issued tokens sit under the subject_token's grant, so revoking it revokes them; cnf rebinding to the request's verified DPoP / mTLS; a requested scope outside the client's registered scopes is refused with invalid_scope
  • RFC 8707 Resource Indicators: Built-in grants currently narrow most issuance paths to a single resource value
  • RFC 9068 JWT Profile for Access Tokens: §2.1 requires RS256 support, which an OP built with op.WithSigningAlgorithm(op.AlgRS256) meets; the verifier requires jti only when the revocation strategy keys on it, so with strategy None it accepts tokens without the §2.2 required claim
  • RFC 9396 Rich Authorization Requests (authorization_details): Validated at /auth, /par, /token, persisted with each authorization code, refresh chain and access token so a later authorization cannot change them, echoed on JWT access tokens and introspection, advertised in discovery
  • RFC 9470 OAuth 2.0 Step Up Authentication Challenge: op.StepUpChallenge builds the resource-server WWW-Authenticate challenge the embedder's RS returns
  • RFC 9700 OAuth 2.0 Security Best Current Practice: Resource-server and client-side requirements remain with embedders

IETF drafts ​

DraftStatusWhere
OAuth 2.0 Grant Management (draft-ietf-oauth-grant-management)partial (gated by op.WithGrantManagement)internal/grantmgmtendpoint, op/grant_management.go
Identity Assertion JWT Authorization Grant (ID-JAG) (draft-ietf-oauth-identity-assertion-authz-grant, draft-06)partial (resource authorization server role: redeeming an ID-JAG through the jwt-bearer grant is supported)internal/assertiongrant, internal/customgrant/tokenexchange
OAuth Client ID Metadata Document (draft-ietf-oauth-client-id-metadata-document, draft-02)partial (gated by op.WithClientIDMetadataDocuments)internal/cimd, op/cimd.go
  • OAuth 2.0 Grant Management (draft-ietf-oauth-grant-management): 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 on a draft update
  • Identity Assertion JWT Authorization Grant (ID-JAG) (draft-ietf-oauth-identity-assertion-authz-grant, draft-06): Identity provider role: issuing an ID-JAG through token exchange is supported. An ID-JAG is signed with the OP's issuing algorithm. With the default ES256 the draft's mandatory-to-implement RS256 is not met and a resource AS that implements only RS256 rejects it; an OP built with op.WithSigningAlgorithm(op.AlgRS256) signs ID-JAGs with RS256. Experimental; tracks an IETF draft, so the surface may change on a draft update
  • OAuth Client ID Metadata Document (draft-ietf-oauth-client-id-metadata-document, draft-02): An HTTPS URL client_id is resolved to a fetched metadata document, for none and private_key_jwt clients using authorization_code and refresh_token. Confidential shared-secret and mTLS clients are not supported, and a changed document does not revoke existing grants. Experimental, opt-in; tracks an IETF draft, so the surface may change on a draft update. The MCP authorization specification cites draft-00

Shared Signals (transmitter) ​

All rows describe the transmitter side only; the OP does not receive events from other transmitters. Enable it with op.WithSharedSignals; see Shared Signals.

SpecificationStatusWhere / option
OpenID Shared Signals Framework 1.0partial (transmitter metadata, stream create / read / update / replace / delete, stream status, verification, push and poll delivery)internal/ssf, op.WithSharedSignals
OpenID CAEP 1.0partial (session-revoked and credential-change only)internal/ssf, op.SessionRevoked, op.CredentialChange
OpenID RISC 1.0partial (account-disabled, account-enabled, account-purged and credential-compromise)internal/ssf, op.AccountDisabled, op.AccountEnabled, op.AccountPurged, op.CredentialCompromise
RFC 8417 Security Event Tokenfull (issuing side: typ: secevent+jwt, one event per token, no sub and no exp)internal/ssf
RFC 8935 Push-Based SET Deliveryfull (transmitter side, with retry and SSRF-guarded delivery)internal/ssf
RFC 8936 Poll-Based SET Deliveryfull (transmitter side, including long polling)internal/ssf
CAEP Interoperability Profile 1.0partial (the transmitter requirements are met except §2.6, which asks for RS256 signing)internal/ssf
  • OpenID Shared Signals Framework 1.0: add_subject / remove_subject, inactivity_timeout and min_verification_interval are not implemented; the metadata advertises default_subjects: "ALL", meaning every subject that holds a grant for the receiver's client
  • OpenID RISC 1.0: Experimental: the published RISC text is still a draft, so this surface may change in a minor release
  • CAEP Interoperability Profile 1.0: SETs are signed with the OP's single issuing algorithm: ES256 by default, which does not meet §2.6, and RS256 when op.WithSigningAlgorithm(op.AlgRS256) is set

JOSE family ​

RFCStatusWhere
RFC 7515 JWSpartial (compact JWS surfaces used by JWT / JAR / JARM / DPoP / client assertions; general JSON serialization is not exposed)internal/jose
RFC 7516 JWEpartial — closed allow-list (RSA-OAEP-256 / ECDH-ES{,+A128KW,+A256KW} × A{128,256}GCM)internal/jose, op.WithEncryptionKeyset
RFC 7517 JWKpartial (JWK Set publication and client JWKS consumption for supported asymmetric key types; symmetric oct keys are not accepted for signing)internal/jwks
RFC 7518 JWApartial — issuance uses one algorithm per OP, ES256 by default or RS256 through op.WithSigningAlgorithminternal/jose
RFC 7519 JWTpartial (signed / encrypted JWT surfaces used by OIDC and OAuth extensions; unsecured JWTs are refused)internal/jose
RFC 7638 JWK Thumbprintfull (used by DPoP cnf.jkt)internal/dpop
RFC 8037 Edwards-curve DSA / EdDSApartial (Ed25519; Ed448 not enabled)internal/jose
  • RFC 7516 JWE: 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+
  • RFC 7518 JWA: Verification accepts RS256, PS256, ES256, EdDSA. HS* and none refused

FAPI family ​

The FAPI2Baseline Go identifier retains the former Baseline name. The final specification is FAPI 2.0 Security Profile. The OFCS results cited here come from the suite's FAPI 2.0 Final test plans (and the FAPI-CIBA ID1 plan); they are a regression run, not a certification, and do not establish conformity with every requirement of the final specifications. Under FAPI2Baseline and FAPI2MessageSigning the library accepts only the issuer identifier as a string in the private_key_jwt aud (§5.3.2.1(8)) and does not rotate refresh tokens (§5.3.2.1(9)); other profiles keep the wider aud set and rotate.

ProfileStatusSwitch
FAPI 2.0 Security Profilepartial (PAR, PKCE and sender-constrained tokens are implemented; this switch also requires JAR as a library choice)op.WithProfile(profile.FAPI2Baseline)
FAPI 2.0 Message Signingpartial (JAR and JARM are implemented; the final specification permits separate signing profiles and inherits the Security Profile requirements)op.WithProfile(profile.FAPI2MessageSigning)
FAPI 1.0 Advancedout— (use FAPI 2.0)
FAPI-CIBApartial (library preset: poll mode, JAR, DPoP or mTLS, a 10-minute access-token TTL ceiling, requested_expiry ≤ 600 s, and an access-token revocation path)op.WithProfile(profile.FAPICIBA)
OpenID iGov Highout—
  • FAPI 2.0 Security Profile: See the note above and OFCS.
  • FAPI-CIBA: The historical ID1 plan uses mTLS; the demo selects it explicitly. The 60-minute request-object age limit is a library constraint; see OFCS.

The profile enumeration also carries two profiles that are not FAPI profiles. profile.OAuth21, the default when no profile is declared, is the OAuth 2.1 / RFC 9700 posture and adds PKCE on every authorization-code request, including confidential clients. profile.OIDCCore declares the OpenID Connect Core 1.0 shape, PKCE optional for confidential clients, for legacy relying parties; it cannot be combined with another profile. See Declaring a security profile.

Other RFCs the library cites ​

RFCUse
RFC 1918Private-network deny-list for back-channel logout SSRF defense
RFC 2045Case-insensitive media-type comparison for request-object typ
RFC 2606Reserved example domains in tests / examples
RFC 3986URI parsing
RFC 4122UUIDv4 generation
RFC 4226HOTP building block used by the TOTP authenticator
RFC 4514DN handling for mTLS subject DN
RFC 4647Language-tag lookup when selecting a locale bundle
RFC 4648Base64url encoding
RFC 5280X.509 cert validation
RFC 5321SMTP address length bounds for email OTP inputs
RFC 6238TOTP authenticator
RFC 6265Cookie syntax
RFC 6711Authentication Context Class Reference values registry
RFC 6761Special-use domain names: the development issuer hosts WithAllowInsecureOutboundForDev accepts
RFC 6838Media-type suffix matching (+json) for fetched documents
RFC 7230 / 7231 / 7232 / 7235HTTP/1.1 (now superseded by RFC 9110)
RFC 7239Forwarded header parsing for trusted-proxy handling
RFC 7807application/problem+json (selected error paths)
RFC 8017RSA-PSS / RSA-OAEP algorithm references through JOSE
RFC 8141URN handling for PAR request_uri values
RFC 8176AMR values registry
RFC 8259JSON
RFC 9110HTTP semantics
RFC 9111HTTP caching: freshness lifetime of a fetched Client ID Metadata Document
RFC 9325TLS recommendations; op.FAPITLSConfig keeps TLS 1.3 enabled alongside the FAPI TLS 1.2 cipher list
RFC 9493iss_sub subject identifiers in Shared Signals events

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_type is code only. Implicit (id_token, id_token token), hybrid (code id_token, ...), and response_type=none are not issued. RFC 9700 §2.1.2 deprecates the implicit grant; FAPI 2.0 mandates code. Discovery advertises response_types_supported: ["code"].
  • fragment response mode is not wired. With code-only issuance there is nothing to put in the URL fragment. query and form_post are both implemented (the latter renders an auto-submitting HTML form per OIDC Core Form Post Response Mode 1.0); when feature.JARM is on, the four *.jwt variants are also wired. Discovery advertises response_modes_supported: ["query", "form_post"] by default and appends *.jwt modes 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_sources keys never appear in tokens or UserInfo responses.
  • client_secret_jwt is refused at registration. Use private_key_jwt instead. The HMAC-shared-secret JWT profile is rejected with invalid_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 and A{128,256}GCM for content. WithSupportedEncryptionAlgs can narrow but not extend. RSA1_5 is permanently rejected (CVE-2017-11424); RSA-OAEP-384 / RSA-OAEP-512, dir, and symmetric-only A*KW are 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 own RefreshTokenStore, preserving lineage, rotation, replay cascade, and DPoP / mTLS binding. If the client is not registered for refresh_token, the access-token response still succeeds and custom_grant.refresh_dropped records 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 / SpecStatusNotes
RFC 9421 — HTTP Message SignaturesoutResource-server (API protection) concern, not OP.
  • RFC 9421 — HTTP Message Signatures: 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:

sh
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
grep -rhoE 'RFC [0-9]+' op/ internal/ | sort -u

The tables above follow the output of that command: standards the library implements get their own rows, and incidental references are collected under "Other RFCs the library cites".