RFC Compliance Matrix¶
This file is generated by cargo run --bin compliance_report. Do not edit by hand — re-run the generator to regenerate.
Summary¶
- Total annotated tests: 191
- Passing: 191
- Failing: 0
- Ignored: 0
- Compliance score (passed / passed+failed+ignored): 100%
RFC 6749¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.3.1 | MUST | The authorization server MUST support HTTP Basic authentication for clients with a client password. | rfc6749_s2_3_client_auth_via_basic_header tests/compliance_rfc6749.rs:899 |
| ✅ | §2.3.1 | MAY | Client credentials MAY be included in the request body using client_id and client_secret parameters. |
rfc6749_s2_3_client_auth_via_post_params tests/compliance_rfc6749.rs:942 |
| ✅ | §3.1.2 | MUST | Redirect URI in the authorization request must exactly match a registered redirect URI. | rfc6749_s3_1_2_redirect_uri_must_match tests/compliance_rfc6749.rs:247 |
| ✅ | §4.1.1 | MUST | Authorization requests bearing an unknown client_id MUST be rejected. |
rfc6749_s4_1_1_authorize_rejects_unknown_client tests/compliance_rfc6749.rs:414 |
| ✅ | §4.1.1 | MUST | Authorization requests with an unsupported response_type MUST be rejected with unsupported_response_type (or equivalent error). |
rfc6749_s4_1_1_authorize_rejects_unknown_response_type tests/compliance_rfc6749.rs:330 |
| ✅ | §4.1.1 | MUST | The authorization request MUST include the client_id parameter. |
rfc6749_s4_1_1_authorize_requires_client_id tests/compliance_rfc6749.rs:372 |
| ✅ | §4.1.1 | MUST | The authorization request MUST include the response_type parameter. |
rfc6749_s4_1_1_authorize_requires_response_type tests/compliance_rfc6749.rs:293 |
| ✅ | §4.1.2 | MUST | A successful authorization response MUST be delivered as a redirect to the client's redirect URI with a code query parameter. |
rfc6749_s4_1_2_authorize_redirects_with_code tests/compliance_rfc6749.rs:463 |
| ✅ | §4.1.2 | MUST | If the client includes a state parameter, the authorization server MUST include the exact value received in the response. |
rfc6749_s4_1_2_state_is_echoed_in_redirect tests/compliance_rfc6749.rs:522 |
| ✅ | §4.1.3 | MUST | Public clients (token_endpoint_auth_method=none) must exchange auth codes via PKCE without a secret. |
public_client_exchanges_code_without_secret tests/rfc_compliance.rs:586 |
| ✅ | §4.1.3 | MUST | Public clients presenting a client_secret must be rejected (invalid_client). |
public_client_must_not_present_secret tests/rfc_compliance.rs:687 |
| ✅ | §4.1.3 | MUST | Token requests with an unsupported grant_type MUST be rejected with unsupported_grant_type. |
rfc6749_s4_1_3_token_rejects_unsupported_grant_type tests/compliance_rfc6749.rs:629 |
| ✅ | §4.1.3 | MUST | The authorization server MUST ensure that an authorization code is bound to the client identifier it was issued to. | rfc6749_s4_1_3_token_rejects_wrong_client_for_code tests/compliance_rfc6749.rs:678 |
| ✅ | §4.1.3 | MUST | Token requests MUST include the grant_type parameter. |
rfc6749_s4_1_3_token_requires_grant_type tests/compliance_rfc6749.rs:584 |
| ✅ | §4.4.2 | MUST | A successful client credentials grant MUST return an access token in the token response body. | rfc6749_s4_4_2_client_credentials_returns_access_token tests/compliance_rfc6749.rs:805 |
| ✅ | §4.4.3 | MUST | Invalid client authentication on the token endpoint MUST be rejected with invalid_client. |
rfc6749_s4_4_3_client_credentials_rejects_invalid_client tests/compliance_rfc6749.rs:851 |
| ✅ | §5.1 | MUST | Successful token responses MUST include the access_token and token_type fields. |
rfc6749_s5_1_token_response_has_required_fields tests/compliance_rfc6749.rs:990 |
| ✅ | §5.1 | MUST | Token endpoint responses MUST include Cache-Control: no-store and Pragma: no-cache to prevent caching of sensitive credentials. |
rfc6749_s5_2_token_response_no_cache_headers tests/compliance_rfc6749.rs:1046 |
| ✅ | §5.2 | MUST | Error responses from the token endpoint MUST be JSON objects containing an error field. |
rfc6749_s5_2_error_response_format tests/compliance_rfc6749.rs:1108 |
| ✅ | §10.5 | MUST | Authorization codes MUST be single-use; a second redemption of the same code MUST be rejected. | rfc6749_s10_3_authorization_code_single_use tests/compliance_rfc6749.rs:1160 |
RFC 6750¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | A token without a resource-owner subject must not be accepted by the userinfo endpoint. | rfc6750_s2_client_credentials_token_cannot_access_userinfo tests/compliance_rfc6750.rs:315 |
| ✅ | §2.1 | MUST | Bearer token in the Authorization header must be accepted by protected resources. | rfc6750_s2_1_bearer_in_authorization_header_returns_200 tests/compliance_rfc6750.rs:132 |
| ✅ | §2.1 | MUST | A valid Bearer token must enable retrieval of the resource owner's sub claim. |
rfc6750_s2_1_userinfo_response_contains_sub tests/compliance_rfc6750.rs:165 |
| ✅ | §3.1 | MUST | Invalid token error body must contain error: invalid_token. |
rfc6750_s3_1_error_body_has_invalid_token_code tests/compliance_rfc6750.rs:279 |
| ✅ | §3.1 | MUST | Invalid Bearer token must return 401 with WWW-Authenticate including error=invalid_token. | rfc6750_s3_1_invalid_token_returns_401_with_www_authenticate tests/compliance_rfc6750.rs:240 |
| ✅ | §3.1 | MUST | Missing Bearer credentials must return 401 with WWW-Authenticate: Bearer. | rfc6750_s3_1_missing_token_returns_401 tests/compliance_rfc6750.rs:204 |
RFC 7009¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Revoking a token must cascade-revoke the entire token family (security BCP). | revoke_cascades_to_entire_token_family tests/rfc_compliance.rs:1833 |
| ✅ | §2 | MUST | A revoked token must subsequently be reported as inactive by introspection. | rfc7009_s2_token_inactive_after_revoke tests/compliance_rfc7662_7009.rs:624 |
| ✅ | §2.1 | MUST | Token revocation endpoint must require client authentication. | rfc7009_s2_1_revoke_requires_client_auth tests/compliance_rfc7662_7009.rs:582 |
| ✅ | §2.2 | MUST | Revocation of an unknown token must still return HTTP 200. | rfc7009_s2_2_revoke_unknown_token_returns_200 tests/compliance_rfc7662_7009.rs:538 |
| ✅ | §2.2 | MUST | Successful token revocation must return HTTP 200. | rfc7009_s2_2_revoke_valid_token_returns_200 tests/compliance_rfc7662_7009.rs:496 |
RFC 7515¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §6 | MUST | A JWS with alg: none and a non-empty signature must be rejected. |
wave2_c1_public_client_jar_rejects_nonempty_signature_with_alg_none tests/compliance_wave5.rs:797 |
RFC 7523¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.2 | MUST | Token endpoint must accept client_secret_jwt (HS256 JWT signed with client_secret). |
rfc7523_client_secret_jwt_authentication tests/phase2_rfc_compliance.rs:595 |
| ✅ | §2.2 | MUST | A client_secret_jwt assertion signed with the wrong secret must be rejected. | rfc7523_client_secret_jwt_wrong_secret_fails tests/phase2_rfc_compliance.rs:671 |
| ✅ | §2.2 | MUST | Token endpoint must accept private_key_jwt (RS256 JWT verified against registered JWKS). |
rfc7523_private_key_jwt_authentication tests/phase2_rfc_compliance.rs:748 |
RFC 7591¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Dynamic registration must reject public clients requesting the client_credentials grant. |
public_client_registration_with_client_credentials_is_rejected tests/rfc_compliance.rs:972 |
| ✅ | §2 | MUST | Dynamic registration must accept token_endpoint_auth_method=none for public clients. |
public_client_registration_with_none_auth_method_succeeds tests/rfc_compliance.rs:926 |
| ✅ | §2 | MUST | Registration request must not contain both jwks and jwks_uri. |
rfc7591_jwks_and_jwks_uri_mutually_exclusive tests/phase2_rfc_compliance.rs:1089 |
| ✅ | §2 | MUST | Registering with token_endpoint_auth_method=private_key_jwt must require jwks or jwks_uri. |
rfc7591_private_key_jwt_requires_jwks tests/phase2_rfc_compliance.rs:1022 |
| ✅ | §2 | MUST | Registration must reject invalid redirect_uris (malformed/non-absolute/etc). |
rfc7591_rejects_invalid_redirect_uris tests/phase2_rfc_compliance.rs:296 |
| ✅ | §3.1 | MUST | Registration must default grant_types/response_types to authorization_code/code when omitted. |
rfc7591_defaults_grant_and_response_types tests/phase2_rfc_compliance.rs:186 |
| ✅ | §3.1 | MUST | Successful dynamic client registration must return 201 with full client info plus registration_access_token. | rfc7591_dynamic_registration_success tests/phase2_rfc_compliance.rs:100 |
| ✅ | §3.1 | MUST | Public-client registration must omit client_secret from the registration response. |
rfc7591_public_client_no_secret tests/phase2_rfc_compliance.rs:238 |
RFC 7592¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | GET on the client configuration endpoint must return the client config when authenticated with the registration access token. | rfc7592_read_client_configuration tests/phase2_rfc_compliance.rs:379 |
| ✅ | §2.2 | MUST | PUT on the client configuration endpoint must update the client metadata. | rfc7592_update_client_configuration tests/phase2_rfc_compliance.rs:451 |
| ✅ | §2.3 | MUST | DELETE on the client configuration endpoint must remove the client. | rfc7592_delete_client tests/phase2_rfc_compliance.rs:521 |
RFC 7636¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §4.1 | MUST | Public clients using authorization_code must include code_challenge in the authorize request. | rfc7636_s4_1_pkce_required_for_authorization_code tests/compliance_rfc7636.rs:190 |
| ✅ | §4.1 | MUST | code_verifier longer than 128 characters must be rejected. | rfc7636_s4_1_verifier_max_length_128 tests/compliance_rfc7636.rs:291 |
| ✅ | §4.1 | MUST | code_verifier shorter than 43 characters must be rejected. | rfc7636_s4_1_verifier_min_length_43 tests/compliance_rfc7636.rs:236 |
| ✅ | §4.2 | MUST | code_challenge_method without code_challenge must be rejected. | rfc7636_s4_2_method_without_challenge_rejected tests/compliance_rfc7636.rs:457 |
| ✅ | §4.2 | MUST | The plain code_challenge_method must be rejected (S256-only enforcement). | rfc7636_s4_2_plain_method_is_rejected tests/compliance_rfc7636.rs:398 |
| ✅ | §4.2 | MUST | Servers must support the S256 code_challenge_method. | rfc7636_s4_2_s256_challenge_method_is_accepted tests/compliance_rfc7636.rs:348 |
| ✅ | §4.3 | MUST | Missing code_verifier when challenge was registered must yield invalid_grant. | rfc7636_s4_3_missing_verifier_rejects_pkce_code tests/compliance_rfc7636.rs:603 |
| ✅ | §4.3 | MUST | Verifier-as-challenge (plain-style) misuse must be rejected when S256 is required. | rfc7636_s4_3_sending_verifier_as_challenge_rejected tests/compliance_rfc7636.rs:657 |
| ✅ | §4.3 | MUST | A correct PKCE code_verifier must be accepted at the token endpoint. | rfc7636_s4_3_valid_verifier_exchanges_code tests/compliance_rfc7636.rs:502 |
| ✅ | §4.3 | MUST | An incorrect PKCE code_verifier must yield invalid_grant at the token endpoint. | rfc7636_s4_3_wrong_verifier_is_rejected tests/compliance_rfc7636.rs:552 |
RFC 7662¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | Introspection endpoint must accept HTTP Basic client authentication. | rfc7662_s2_1_introspect_accepts_basic_auth tests/compliance_rfc7662_7009.rs:449 |
| ✅ | §2.1 | MUST | Introspection endpoint must require client authentication. | rfc7662_s2_1_introspect_requires_client_auth tests/compliance_rfc7662_7009.rs:294 |
| ✅ | §2.2 | MUST | Active introspection response must include nbf, jti, aud, and iss claims. |
rfc7662_introspection_includes_nbf_jti_aud_iss tests/rfc_compliance.rs:371 |
| ✅ | §2.2 | MUST | Introspection response must satisfy nbf <= iat for tokens valid from issuance. |
rfc7662_introspection_nbf_le_iat tests/rfc_compliance.rs:479 |
| ✅ | §2.2 | MUST | Introspection of an active token must yield active: true. |
rfc7662_s2_2_introspect_active_token_returns_true tests/compliance_rfc7662_7009.rs:207 |
| ✅ | §2.2 | MUST | Introspection must report a token belonging to a different client as inactive. | rfc7662_s2_2_introspect_cross_client_returns_inactive tests/compliance_rfc7662_7009.rs:391 |
| ✅ | §2.2 | MUST | Introspection must return active: false for an invalid or unknown token. |
rfc7662_s2_2_introspect_invalid_token_returns_false tests/compliance_rfc7662_7009.rs:251 |
| ✅ | §2.2 | MUST | Introspection response for an active token must include scope, client_id, and token_type. | rfc7662_s2_2_introspect_response_includes_required_fields tests/compliance_rfc7662_7009.rs:337 |
| ✅ | §5 | MUST | Anonymous introspection must strip subject identity fields (username, sub) while keeping lifecycle claims. | rfc9700_anonymous_introspection_strips_username_and_sub tests/rfc9700_introspection_pii.rs:28 |
| ✅ | §5 | MUST | Authenticated owner introspection must still return identity claims (sub, client_id) for the token's owner. | rfc9700_owner_introspection_still_returns_pii tests/rfc9700_introspection_pii.rs:169 |
RFC 8252¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §7.1 | MUST | Claimed/custom URI schemes must match registered redirect URI byte-for-byte. | rfc8252_custom_scheme_exact_match_only tests/rfc8252_native_apps.rs:149 |
| ✅ | §7.3 | MUST | IPv4 loopback (127.0.0.1) redirect URIs must accept any port at request time. | rfc8252_ipv4_loopback_any_port_accepted tests/rfc8252_native_apps.rs:36 |
| ✅ | §7.3 | MUST | IPv6 loopback ([::1]) redirect URIs must accept any port at request time. | rfc8252_ipv6_loopback_any_port_accepted tests/rfc8252_native_apps.rs:50 |
| ✅ | §7.3 | MUST | Loopback exception must still require path equality; only the port is wildcarded. | rfc8252_loopback_exception_still_requires_path_match tests/rfc8252_native_apps.rs:119 |
| ✅ | §7.3 | MUST | Loopback exception must still require scheme equality (http vs https are distinct). | rfc8252_loopback_exception_still_requires_scheme_match tests/rfc8252_native_apps.rs:134 |
| ✅ | §7.3 | MUST | IPv4 and IPv6 loopback hosts must be treated as distinct (no cross-family wildcarding). | rfc8252_loopback_families_do_not_cross tests/rfc8252_native_apps.rs:88 |
| ✅ | §7.3 | MUST | Non-loopback hosts must require exact redirect URI match (no port wildcard). | rfc8252_non_loopback_host_requires_exact_match tests/rfc8252_native_apps.rs:105 |
| ✅ | §8.3 | MUST | localhost hostname must NOT receive the loopback port-wildcard exception. |
rfc8252_localhost_hostname_does_not_wildcard_port tests/rfc8252_native_apps.rs:67 |
RFC 8414¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Discovery doc must reflect supported client auth methods (incl. client_secret_jwt, private_key_jwt) and registration endpoint. | rfc8414_discovery_reflects_phase2 tests/phase2_rfc_compliance.rs:857 |
| ✅ | §2 | MUST | Metadata must include the authorization_endpoint field. |
rfc8414_s2_authorization_endpoint_present tests/compliance_rfc8414.rs:91 |
| ✅ | §2 | MUST | code_challenge_methods_supported must include S256. |
rfc8414_s2_code_challenge_methods_includes_s256 tests/compliance_rfc8414.rs:166 |
| ✅ | §2 | MUST | grant_types_supported must include authorization_code. |
rfc8414_s2_grant_types_includes_authorization_code tests/compliance_rfc8414.rs:243 |
| ✅ | §2 | MUST | The issuer metadata value must match the configured issuer URL. |
rfc8414_s2_issuer_matches_configured_value tests/compliance_rfc8414.rs:68 |
| ✅ | §2 | MUST | Authorization-server metadata endpoint must return 200 OK. | rfc8414_s2_metadata_endpoint_returns_200 tests/compliance_rfc8414.rs:49 |
| ✅ | §2 | MUST | response_types_supported must include code. |
rfc8414_s2_response_types_includes_code tests/compliance_rfc8414.rs:142 |
| ✅ | §2 | MUST | token_endpoint_auth_methods_supported must include client_secret_basic. |
rfc8414_s2_token_endpoint_auth_methods_include_basic tests/compliance_rfc8414.rs:215 |
| ✅ | §2 | MUST | Metadata must include the token_endpoint field. |
rfc8414_s2_token_endpoint_present tests/compliance_rfc8414.rs:120 |
| ✅ | §3 | MUST | Both /.well-known/oauth-authorization-server and /.well-known/openid-configuration must serve identical metadata. |
rfc8414_both_well_known_paths_return_same_response tests/rfc_compliance.rs:857 |
| ✅ | §3 | MUST | AS metadata must be served at /.well-known/oauth-authorization-server. |
rfc8414_oauth_authorization_server_well_known_returns_metadata tests/rfc_compliance.rs:792 |
RFC 8628¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3.1 | MUST | Device authorization endpoint must accept client_secret_basic credentials. | rfc8628_s3_1_accepts_client_secret_basic tests/compliance_rfc8628.rs:654 |
| ✅ | §3.1 | MUST | Device authorization endpoint must reject missing or unknown client_id. | rfc8628_s3_1_missing_client_id_returns_error tests/compliance_rfc8628.rs:235 |
| ✅ | §3.1 | MUST | Device authorization response must include device_code, user_code, verification_uri, expires_in. | rfc8628_s3_1_response_contains_required_fields tests/compliance_rfc8628.rs:171 |
| ✅ | §3.1 | MUST | A client without device_code grant must receive unauthorized_client. |
rfc8628_s3_1_unauthorized_client_is_rejected tests/compliance_rfc8628.rs:273 |
| ✅ | §3.3 | MUST | Approving a valid user_code at the verification endpoint must return a 2xx response. | rfc8628_s3_3_approve_returns_success tests/compliance_rfc8628.rs:328 |
| ✅ | §3.3 | MUST | Denying a valid user_code at the verification endpoint must return a 2xx response. | rfc8628_s3_3_deny_returns_success tests/compliance_rfc8628.rs:395 |
| ✅ | §3.4 | MUST | After user approval, token polling must return 200 with an access token. | rfc8628_s3_4_approved_returns_access_token tests/compliance_rfc8628.rs:524 |
| ✅ | §3.4 | MUST | Token polling before approval must return 400 with error=authorization_pending. | rfc8628_s3_4_pending_returns_authorization_pending tests/compliance_rfc8628.rs:462 |
| ✅ | §3.4 | MUST | Unknown or invalid device_code at the token endpoint must return a 4xx error. | rfc8628_s3_4_unknown_device_code_returns_error tests/compliance_rfc8628.rs:609 |
RFC 8693¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | Discovery metadata must include urn:ietf:params:oauth:grant-type:token-exchange in grant_types_supported. |
wave4_rfc8693_token_exchange_grant_type_in_discovery tests/compliance_wave4.rs:126 |
RFC 8705¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | tls_client_auth must validate the client certificate Subject DN against the registered value. |
test_vector_p_mtls_subject_dn_validation tests/rfc9700_compliance.rs:1535 |
| ✅ | §3 | MUST | Discovery metadata must advertise tls_client_certificate_bound_access_tokens: true. |
wave4_rfc8705_mtls_advertised_in_discovery tests/compliance_wave4.rs:104 |
RFC 8707¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Token endpoint must accept resource parameter and bind it as token audience. |
rfc8707_resource_indicator_accepted_in_client_credentials tests/compliance_wave3.rs:376 |
| ✅ | §2 | MUST | Token request resource parameter must populate the issued token's aud claim. |
test_vector_m_resource_to_aud_claim tests/rfc9700_compliance.rs:1392 |
RFC 9068¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | JWT access tokens must use JOSE header typ: "at+JWT". |
rfc9068_access_token_has_typ_at_jwt tests/rfc_compliance.rs:225 |
| ✅ | §2.2 | MUST | Access-token JWT iss claim must equal the configured AS issuer URL. |
rfc9068_jwt_iss_matches_configured_issuer tests/rfc_compliance.rs:292 |
RFC 9101¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §4 | MUST | Authorization endpoint must accept and process the JAR request parameter. |
test_vector_q_jar_request_parameter_integration tests/rfc9700_compliance.rs:1622 |
| ✅ | §4 | MUST | JAR signed via private_key_jwt must be verified using the client's resolved JWKS. |
test_vector_r_jar_private_key_jwt_jwks_cache tests/rfc9700_compliance.rs:1794 |
| ✅ | §4 | MUST | A public-client JAR with a non-none alg header must be rejected (no signature-bypass). |
wave2_c1_public_client_jar_rejects_non_none_alg_header tests/compliance_wave5.rs:736 |
| ✅ | §4 | MAY | A confidential client may submit a JAR signed with HS256 derived from client_secret. | wave5_jar_confidential_client_hs256_succeeds tests/compliance_wave5.rs:585 |
| ✅ | §4 | MAY | A public client may submit an unsigned (alg=none) JAR via the request parameter. |
wave5_jar_public_client_unsigned_succeeds tests/compliance_wave5.rs:512 |
| ✅ | §4 | MUST | JAR with an invalid / tampered signature must be rejected. | wave5_jar_tampered_hs256_is_rejected tests/compliance_wave5.rs:661 |
| ✅ | §9 | MUST | Discovery must advertise request_parameter_supported: true. |
wave5_discovery_request_parameter_supported_is_true tests/compliance_wave5.rs:997 |
RFC 9126¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | PAR endpoint must reject confidential clients that do not authenticate. | rfc9126_par_confidential_client_no_secret_rejected tests/compliance_wave3.rs:263 |
| ✅ | §2.1 | MUST | PAR endpoint must accept confidential client authenticated via HTTP Basic. | rfc9126_par_confidential_client_with_basic_auth_succeeds tests/compliance_wave3.rs:312 |
| ✅ | §2.1 | MUST | PAR endpoint must reject requests containing duplicate parameters. | rfc9126_par_duplicate_param_is_rejected tests/compliance_wave3.rs:215 |
| ✅ | §2.1 | MUST | PAR endpoint must reject requests missing the response_type parameter. |
rfc9126_par_missing_response_type_is_rejected tests/compliance_wave3.rs:168 |
| ✅ | §2.2 | MUST | PAR endpoint must return 201 with request_uri and expires_in for valid public-client requests. |
rfc9126_par_public_client_returns_request_uri tests/compliance_wave3.rs:108 |
RFC 9207¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Authorization response must include the iss parameter naming the AS. |
rfc9207_iss_included_in_authorization_response tests/rfc_compliance.rs:136 |
| ✅ | §2 | MUST | Authorization response (success or error) must include the iss parameter. |
test_vector_e_iss_in_authorization_response tests/rfc9700_compliance.rs:724 |
| ✅ | §3 | MUST | Discovery must advertise authorization_response_iss_parameter_supported: true. |
discovery_includes_iss_parameter_supported tests/rfc_compliance.rs:1998 |
RFC 9396¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §7 | MUST | Discovery metadata must advertise authorization_details_types_supported. |
wave4_rfc9396_rar_advertised_in_discovery tests/compliance_wave4.rs:152 |
RFC 9449¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §4 | MUST | DPoP proof with invalid typ JOSE header must be rejected with invalid_dpop_proof. |
test_vector_n_dpop_invalid_typ tests/rfc9700_compliance.rs:1476 |
| ✅ | §4 | MUST | Replayed DPoP proof (same jti) must be rejected with invalid_dpop_proof. |
test_vector_o_dpop_jti_replay tests/rfc9700_compliance.rs:1504 |
| ✅ | §5 | MUST | Discovery metadata must advertise dpop_signing_alg_values_supported. |
wave4_rfc9449_dpop_signing_alg_values_supported_advertised tests/compliance_wave4.rs:75 |
RFC 9470¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §4 | MUST | Discovery metadata must advertise acr_values_supported. |
wave4_rfc9470_acr_values_supported_advertised tests/compliance_wave4.rs:175 |
RFC 9700¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1.1 | MUST | Authorization-code replay must cascade-revoke every access/refresh token issued from the original exchange. | rfc9700_authorization_code_replay_revokes_issued_tokens tests/rfc9700_code_replay.rs:54 |
| ✅ | §2.1.1 | MUST | PKCE plain method must be rejected; only S256 is acceptable. |
test_vector_a_plain_pkce_rejected tests/rfc9700_compliance.rs:158 |
| ✅ | §2.1.1 | MUST | Public clients must supply PKCE on the authorization-code flow. | test_vector_b_public_client_missing_pkce tests/rfc9700_compliance.rs:229 |
| ✅ | §2.1.5 | MUST | Authorization-code replay must revoke the entire issued token family. | test_vector_c_authorization_code_replay tests/rfc9700_compliance.rs:305 |
| ✅ | §2.1.5 | MUST | Replaying a rotated refresh token must revoke the entire token family. | test_vector_d_refresh_token_replay tests/rfc9700_compliance.rs:501 |
| ✅ | §2.3 | MUST | Token endpoint responses must include Cache-Control: no-store. |
test_vector_i_token_cache_control_no_store tests/rfc9700_compliance.rs:1055 |
| ✅ | §2.4 | MUST | Resource Owner Password Credentials grant must be disabled (unsupported_grant_type). |
wave2_c3_password_grant_is_rejected tests/compliance_wave5.rs:867 |
| ✅ | §2.5 | SHOULD | Rate-limit buckets must be keyed per client_id so one client's exhaustion does not affect others. | invalid_client_buckets_are_isolated_per_client_id tests/rfc9700_rate_limit.rs:180 |
| ✅ | §2.5 | MUST | Without a configured rate limiter, the token endpoint must still respond 401 invalid_client to bad credentials. |
invalid_client_no_limiter_returns_401 tests/rfc9700_rate_limit.rs:140 |
| ✅ | §2.5 | SHOULD | Token endpoint must rate-limit repeated invalid_client failures and return 429 when the budget is exhausted. |
invalid_client_rate_limit_returns_429_after_budget_exhausted tests/rfc9700_rate_limit.rs:76 |
| ✅ | §2.5 | MUST | Replayed JWT client-assertion (same client_id + jti within exp window) must be rejected with invalid_client. |
rfc9700_client_secret_jwt_replay_is_rejected tests/rfc9700_jti_replay.rs:27 |
| ✅ | §2.5 | MUST | A new (client_id, jti) pair from the same client must still be accepted. | rfc9700_fresh_jti_from_same_client_is_accepted tests/rfc9700_jti_replay.rs:175 |
| ✅ | §2.5 | MUST | A replayed client assertion (same jti within exp window) must be rejected. |
test_vector_l_client_assertion_jti_replay tests/rfc9700_compliance.rs:1276 |
| ✅ | §2.5 | SHOULD | Successful token issuance must not consume the invalid_client rate-limit bucket. |
valid_requests_do_not_deplete_invalid_client_bucket tests/rfc9700_rate_limit.rs:288 |
| ✅ | §2.6 | MAY | HTTPS-enforcement middleware must be a no-op when explicitly disabled. | disabled_by_default_passes_plain_http_through tests/rfc9700_https_enforcement.rs:19 |
| ✅ | §2.6 | MUST | Plain-HTTP requests must be redirected (308) to the corresponding HTTPS URL when enforcement is on. | enforced_plain_http_is_redirected_308_to_https tests/rfc9700_https_enforcement.rs:45 |
| ✅ | §2.6 | MUST | HTTPS-enforcement must accept TLS-terminated upstream traffic via trusted X-Forwarded-Proto. | trusted_forwarded_proto_https_passes_through tests/rfc9700_https_enforcement.rs:96 |
| ✅ | §2.6 | MUST | Untrusted X-Forwarded-Proto must not bypass HTTPS enforcement (anti-spoof). | untrusted_forwarded_proto_header_is_ignored tests/rfc9700_https_enforcement.rs:131 |
| ✅ | §4 | MUST | Discovery doc must satisfy RFC 9700 BCP constraints (S256-only, no password, no implicit, iss param). | test_vector_k_discovery_json_constraints tests/rfc9700_compliance.rs:1215 |
| ✅ | §4.1 | MUST | redirect_uri must be matched byte-for-byte; trailing-slash differences must be rejected. | test_vector_f_redirect_uri_trailing_slash tests/rfc9700_compliance.rs:828 |
| ✅ | §4.1 | MUST | redirect_uri carrying additional query parameters must be rejected. | test_vector_g_redirect_uri_extra_query_param tests/rfc9700_compliance.rs:907 |
| ✅ | §4.7 | MAY | Default require_state=false must allow authorize requests without a state parameter. |
require_state_off_accepts_missing_state tests/rfc9700_require_state.rs:151 |
| ✅ | §4.7 | MUST | require_state=true must accept authorize requests when state is provided. |
require_state_on_accepts_present_state tests/rfc9700_require_state.rs:183 |
| ✅ | §4.7 | MUST | require_state=true must reject authorize requests missing a state parameter. |
require_state_on_rejects_missing_state tests/rfc9700_require_state.rs:167 |
| ✅ | §4.11 | SHOULD | Login form POST handler should redirect with 303 See Other (not 302). | test_vector_h_login_redirect_303 tests/rfc9700_compliance.rs:986 |
| ✅ | §4.12 | MUST | /authorize and /consent must set X-Frame-Options: DENY or CSP frame-ancestors 'none'. | test_vector_j_authorize_security_headers tests/rfc9700_compliance.rs:1123 |
RFC 9701¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §4 | MUST | Introspection must return a signed JWT response when Accept: application/token-introspection+jwt. |
rfc9701_jwt_accept_header_returns_jwt_introspection_response tests/compliance_wave3.rs:442 |
| ✅ | §4 | MUST | JWT introspection payload must include a token_introspection claim with standard fields. |
rfc9701_jwt_payload_contains_token_introspection_claim tests/compliance_wave3.rs:604 |
| ✅ | §4 | MUST | Introspection without special Accept must return the standard JSON response. | rfc9701_standard_accept_returns_json_introspection_response tests/compliance_wave3.rs:531 |
RFC 9728¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3 | MUST | Protected resource metadata must include an authorization_servers array. |
wave4_rfc9728_protected_resource_metadata_has_authorization_servers tests/compliance_wave4.rs:238 |
| ✅ | §3 | MUST | Protected resource metadata must include a resource field. |
wave4_rfc9728_protected_resource_metadata_has_resource_field tests/compliance_wave4.rs:216 |
| ✅ | §3 | MUST | /.well-known/oauth-protected-resource must return 200. | wave4_rfc9728_protected_resource_metadata_returns_200 tests/compliance_wave4.rs:195 |
OpenID Connect Back-Channel Logout 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2.1 | MUST | Dynamic client registration must accept backchannel_logout_uri and backchannel_logout_session_required. |
wave6_client_registration_includes_logout_fields tests/compliance_wave6.rs:724 |
| ✅ | §2.4 | MUST | logout_token must have typ=logout+JWT, exp, and required claims. | wave6_backchannel_logout_posts_valid_token tests/compliance_wave6.rs:584 |
OpenID Connect Core 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | id_token aud claim must contain the requesting RP's client_id. |
oidc_core_s3_1_id_token_aud_matches_client tests/compliance_oidc_core.rs:409 |
| ✅ | §2 | MUST | id_token must have iat and exp NumericDate claims with exp > iat. |
oidc_core_s3_1_id_token_has_iat_and_exp tests/compliance_oidc_core.rs:455 |
| ✅ | §2 | MUST | id_token iss claim must match the configured issuer value exactly. |
oidc_core_s3_1_id_token_iss_matches_config tests/compliance_oidc_core.rs:368 |
| ✅ | §2 | MUST | id_token must contain a sub claim identifying the end-user. |
oidc_core_s3_1_id_token_sub_claim_present tests/compliance_oidc_core.rs:329 |
| ✅ | §3.1 | MUST | id_token must be a compact-serialised JWT (header.payload.signature). | oidc_core_s3_1_id_token_is_valid_jwt tests/compliance_oidc_core.rs:289 |
| ✅ | §3.1 | MUST | Token response without openid scope must not include an id_token. |
oidc_core_s3_1_no_id_token_without_openid_scope tests/compliance_oidc_core.rs:543 |
| ✅ | §3.1 | MUST | Authorization-code flow with openid scope must include an id_token in the token response. |
oidc_core_s3_1_openid_scope_triggers_id_token tests/compliance_oidc_core.rs:251 |
| ✅ | §3.1.2.1 | MUST | max_age=0 must force re-authentication when auth_time is unavailable or stale. |
max_age_zero_forces_reauthentication tests/rfc_compliance.rs:1674 |
| ✅ | §3.1.2.1 | MUST | A nonce in the authorization request must be echoed verbatim in the id_token. | oidc_core_s3_1_2_1_nonce_echoed_in_id_token tests/compliance_oidc_core.rs:497 |
| ✅ | §3.1.2.1 | MUST | prompt=login must force re-authentication even when an active session exists. |
prompt_login_forces_reauthentication tests/rfc_compliance.rs:1591 |
| ✅ | §3.1.2.1 | MUST | prompt=none without an active session must return a login_required error redirect. |
prompt_none_without_session_returns_login_required tests/rfc_compliance.rs:1508 |
| ✅ | §3.1.2.1 | MUST | prompt=consent must proceed to authorization (auto-approve in test harness). |
wave6_prompt_consent_proceeds_after_auto_approve tests/compliance_wave6.rs:454 |
| ✅ | §3.1.2.1 | MUST | prompt=select_account must force account selection / re-authentication. |
wave6_prompt_select_account_forces_reauth tests/compliance_wave6.rs:521 |
| ✅ | §3.3 | MUST | Hybrid code id_token flow must return both code and id_token in the response fragment. |
wave5_hybrid_code_id_token_delivers_both_in_fragment tests/compliance_wave5.rs:370 |
| ✅ | §3.3 | MUST | Hybrid code id_token without openid scope must not return an id_token. |
wave5_hybrid_no_openid_scope_omits_id_token tests/compliance_wave5.rs:441 |
| ✅ | §5.3 | MUST | UserInfo endpoint must return 401 with WWW-Authenticate: Bearer when token is missing. | oidc_core_userinfo_s5_3_missing_token_returns_401 tests/compliance_oidc_core.rs:632 |
| ✅ | §5.3 | MUST | UserInfo response with a valid token must include the sub claim. |
oidc_core_userinfo_s5_3_sub_claim_present tests/compliance_oidc_core.rs:585 |
| ✅ | §5.4 | SHOULD | id_token SHOULD include email/preferred_username when the corresponding scopes are granted. | id_token_includes_email_and_preferred_username_when_scopes_granted tests/rfc_compliance.rs:1326 |
| ✅ | §5.4 | MUST | UserInfo must return profile claims (e.g. preferred_username) when profile scope is granted. |
userinfo_returns_real_claims_for_auth_code_flow tests/rfc_compliance.rs:1146 |
| ✅ | §5.4 | MUST | UserInfo must return the email claim when the access token has the email scope. |
userinfo_returns_real_email_when_email_scope_requested tests/rfc_compliance.rs:1022 |
| ✅ | §5.5 | MUST | Discovery claims_supported must advertise acr and auth_time to indicate Claims Request support. |
wave4_oidc_claims_request_acr_auth_time_in_claims_supported tests/compliance_wave4.rs:311 |
OpenID Connect Discovery 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3 | MUST | OIDC discovery metadata must include userinfo_endpoint. |
rfc8414_s2_userinfo_endpoint_present tests/compliance_rfc8414.rs:192 |
| ✅ | §3 | MUST | Discovery response_modes_supported must include fragment. |
wave5_discovery_response_modes_includes_fragment tests/compliance_wave5.rs:963 |
| ✅ | §3 | MUST | Discovery response_types_supported must include code id_token for hybrid flow. |
wave5_discovery_response_types_includes_code_id_token tests/compliance_wave5.rs:932 |
OpenID Connect Front-Channel Logout 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3 | MUST | Logout endpoint must render front-channel logout iframes for clients with frontchannel_logout_uri. |
wave6_logout_renders_frontchannel_iframes tests/compliance_wave6.rs:317 |
OAuth 2.0 Multiple Response Type Encoding Practices¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | response_mode=fragment must encode authorization response in URL fragment. |
wave5_response_mode_fragment_delivers_code_in_fragment tests/compliance_wave5.rs:247 |
| ✅ | §2 | MUST | An unsupported response_mode value must produce invalid_request. |
wave5_unsupported_response_mode_is_rejected tests/compliance_wave5.rs:321 |
OpenID Connect Dynamic Client Registration 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §2 | MUST | Registration must accept and round-trip OIDC client metadata (contacts, *_uri fields, response_types). | oidc_metadata_preserved_in_registration tests/phase2_rfc_compliance.rs:933 |
OpenID Connect RP-Initiated Logout 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3 | MUST | Logout endpoint must reject id_token_hint whose aud does not match a registered client. |
logout_with_invalid_aud_id_token_hint_returns_error tests/rfc_compliance.rs:1762 |
| ✅ | §3 | MUST | Logout must accept post_logout_redirect_uri only when registered in post_logout_redirect_uris. | wave6_logout_accepts_registered_post_logout_redirect_uri tests/compliance_wave6.rs:368 |
| ✅ | §3 | MUST | Logout must reject unregistered post_logout_redirect_uri values. | wave6_logout_rejects_unregistered_post_logout_redirect_uri tests/compliance_wave6.rs:408 |
| ✅ | §3 | SHOULD | Logout endpoint must accept a simple GET (no id_token_hint, no redirect) and return 200. | wave6_simple_logout_returns_ok tests/compliance_wave6.rs:789 |
OpenID Connect Session Management 1.0¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §3 | MUST | check_session_iframe must return HTML with a postMessage handler. | wave6_check_session_iframe_returns_html tests/compliance_wave6.rs:266 |
| ✅ | §4 | MUST | Discovery must advertise check_session_iframe for OIDC Session Management. |
wave6_discovery_includes_session_management_fields tests/compliance_wave6.rs:211 |
OAuth 2.0 Token Status List (draft-ietf-oauth-status-list)¶
| Status | Section | Level | Requirement | Test |
|---|---|---|---|---|
| ✅ | §5 | MUST | Token Status List discovery endpoint must return 200. | wave4_token_status_list_returns_200 tests/compliance_wave4.rs:267 |
| ✅ | §5 | MUST | Token Status List response must be valid JSON. | wave4_token_status_list_returns_valid_json tests/compliance_wave4.rs:288 |
Legend: ✅ passing test · ❌ failing test · ⚠️ ignored / pending · · status unknown (no test results provided)