Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RFC Support Reference

This chapter lists every standard that Ahdapa implements, the implementation scope, and any known limitations.

OAuth 2.0 core

RFCTitleStatusNotes
RFC 6749OAuth 2.0 Authorization FrameworkFullImplicit grant (§4.2) and Resource Owner Password Credentials grant (§4.3) intentionally not implemented per RFC 9700 §2.1.2 and §2.4.
RFC 9700OAuth 2.0 Security Best Current PracticeFull
RFC 6750Bearer Token UsageFull
RFC 7009Token RevocationFullRevocation invalidates the entire token family; the JTI blocklist is propagated to all cluster nodes via CRDT gossip. Additionally, ahdapa acts as an RFC 7009 client when revoking upstream IdP tokens: when revoke_on_replace = true on an upstream IdP, old access tokens are revoked at the upstream’s revocation endpoint on replacement.
RFC 7636PKCEFullplain method intentionally not supported.
RFC 8693Token ExchangeFullFull OBO flow including actor_token validation, act claim chains, multi-way scope intersection (requested, subject token, client registration, federation policy ceiling, target client scopes), delegation target guards (delegation_targets / delegation_target_category), federation policy resolution (pattern-based identity mapping for workload federation), service identity resolution (when the resolved subject matches a registered client_id), and HBAC enforcement. When the subject token is an ID token (no scope claim), the subject-scope constraint is skipped; remaining ceilings still apply. Impersonation (acting as a different user without a subject token) is not supported.
RFC 8707Resource IndicatorsFullresource parameter supported at authorization and token endpoints. Per-client allowed_resources restricts which resource URIs a client may request. Resource-driven aud claim in access tokens. resource_indicators_supported advertised in discovery metadata.
RFC 8628Device Authorization GrantFullverification_uri_complete (§3.2) intentionally omitted to reduce phishing risk.
RFC 9126Pushed Authorization RequestsFull
RFC 9207Authorization Server Issuer IdentificationFull
RFC 8705OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access TokensFullSubject DN (§2.1.1) and SAN-based (§2.1.2) client authentication: tls_client_auth_san_dns, tls_client_auth_san_uri, tls_client_auth_san_ip, tls_client_auth_san_email. IPv6 SAN addresses are compared via parsed IpAddr for canonical equivalence. When DPoP and mTLS are both active, cnf.jkt and cnf.x5t#S256 are both present in the same cnf object. In cluster mode the client-certificate thumbprint is carried in the internal auth-code payload so the origin node embeds it in the access token without re-seeing the certificate.
RFC 9449DPoPFullServer-issued nonces are supported: the server returns a DPoP-Nonce header when a DPoP proof is present, and validates the nonce claim on subsequent proofs. Nonce generation is conditional on DPoP proof presence (nonces are not issued to non-DPoP requests).
RFC 7591Dynamic Client RegistrationFullSee Known limitations for authorization mechanisms.

JWT and JOSE

RFC / DraftTitleStatusNotes
RFC 7519JSON Web Token (JWT)Full
RFC 7521Assertion FrameworkFull
RFC 7523JWT Client AuthenticationFull
RFC 9068JWT Profile for Access TokensFull
RFC 9864Fully Specified Algorithms for JOSEFull"EdDSA" migrated to "Ed25519" and "Ed448" per §4. "EdDSA" is accepted as a deprecated alias in configuration and verification. Key generation and signing use ML-DSA-44, ML-DSA-65, and ML-DSA-87 via native-ossl.
RFC 9964ML-DSA for JOSE and COSEFullML-DSA-44, ML-DSA-65, and ML-DSA-87 key types (kty=AKP) with JWK pub field. The priv field (32-byte seed format per §4) is validated when present and rejected in public-key-only contexts. COSE identifiers are JOSE-only (WebAuthn uses COSE integers separately).

Verifiable Credentials

RFC / SpecTitleStatusNotes
RFC 9901SD-JWT-based Verifiable CredentialsFullCredential issuance at POST /credential (OID4VCI). Per-client opt-in via sd_jwt_enabled. Selective disclosure of standard OIDC claims (name, given_name, family_name, email, groups, etc.). Signing uses the server’s active JWT signing key. Advertised in discovery as credential_endpoint and sd_jwt_alg_values_supported.

OpenID Connect

SpecificationStatusNotes
OIDC Core 1.0FullPairwise subject identifiers (HMAC-SHA256, per-client sector key). acr_values_supported includes Kerberos (FreeIPA-authenticated sessions). ID token signing algorithm is configurable per client via id_token_signed_response_alg.
OIDC Discovery 1.0Fullscopes_supported and claims_supported are rebuilt from the CRDT scope definitions on every request.
OIDC Federation 1.0PartialSelf-signed Entity Statement published at /.well-known/openid-federation (including authority_hints when trust anchors are configured); bilateral trust via pre-configured [federation].trusted_issuers; multi-hop trust-chain validation (leaf through intermediaries to trust anchor) via [federation].trust_anchors with configurable max_chain_depth (default 5). Metadata policy operators (value, add, default, one_of, subset_of, superset_of, essential) are applied top-down from anchor to leaf. Resolved chains are cached with TTL derived from the shortest exp in the chain. Trust marks, subordinate listing (/list endpoint), and the /fetch endpoint for serving our own subordinate statements are not yet implemented.

ACME Token Authority

RFC / SpecTitleStatusNotes
RFC 9447ACME Token Binding for tkauth-01Full — Kerberos issuance pathToken Authority endpoint at POST /at/account/{id}/token. Authentication is Kerberos SPNEGO only; constraint values are derived from the authenticated Kerberos principal — this is a Kerberos-identity binding, not the telephony tnauthlist profile. Advertised in discovery as token_authority_endpoint when [gssapi] is configured. Only tktype = "JWTClaimConstraints" is accepted.
RFC 8226 §6.2JWTClaimConstraints X.509 extensionPartial — §8 JWTClaimConstraints only, Kerberos variantUsed as the authority token constraint encoding format. The permittedValues fields bind Kerberos-specific claims: sub carries the authenticated Kerberos principal (e.g. alice@IPA.TEST), iss carries the server issuer URL, and (for host/service principals) dns carries the IPA-managed FQDNs for that principal. This is distinct from the telephony tnauthlist use of the same extension.
RFC 9118EnhancedJWTClaimConstraintsFullAhdapa builds and DER-encodes an EnhancedJWTClaimConstraints structure. mustInclude is set to ["sub"], requiring the ACME server to reject any PASSporT that omits the sub claim. permittedValues binds sub to the Kerberos principal, iss to the server issuer URL, and (for host/service principals) dns to the IPA-managed FQDNs returned by an LDAP subtree search against cn=accounts for objects with managedBy pointing to the principal’s DN. The base64url-encoded DER is carried as tkvalue in the signed authority token JWT. mustExclude is supported by the ASN.1 codec but is not populated in the current issuance path.

Discovery and metadata

RFCStatus
RFC 8414 (AS Metadata)Full — /.well-known/oauth-authorization-server

Signing algorithms

The following algorithms are advertised in the discovery document and accepted for client authentication (private_key_jwt; client_secret_jwt uses HMAC-SHA2 only):

  • Classical: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, Ed25519, Ed448
  • Post-quantum: ML-DSA-44, ML-DSA-65, ML-DSA-87

The default signing algorithm for tokens issued by the server is ES256 (ECDSA P-256). The algorithm is configurable via [server] jwt_signing_algorithm; changing it on an existing deployment triggers automatic key rotation on the next startup, with the old public key retained for backward verification. The active signing key is rotatable via the admin API and propagates to all cluster nodes automatically.

ID tokens may be signed with any algorithm from the same set (configurable via id_token_signed_response_alg per client).

Token endpoint client authentication methods

MethodStatus
private_key_jwtFull — accepted at /token, device grant polling, and /par
client_secret_jwtFull — accepted at /token, device grant polling, and /par
client_secret_basicFull
client_secret_postFull
noneSupported for public clients
tls_client_authFull (RFC 8705)
self_signed_tls_client_authFull (RFC 8705)
kerberos_client_authFull (FreeIPA extension) — client presents a Kerberos AP-REQ in Authorization: Negotiate; SPNEGO is verified server-side; principal matched against a registered exact value or glob pattern. Accepted at /token, /device_authorization, /revoke, and /introspect. Advertised in discovery only when [gssapi] is configured. Not available via dynamic client registration. See Kerberos client authentication for setup.

SAML2

SpecificationStatusNotes
OASIS SAML 2.0 Core (saml-core-2.0-os)PartialAuthnRequest, Response, Assertion, LogoutRequest, LogoutResponse, ArtifactResolve, ArtifactResponse. NameID formats: persistent, transient, email, kerberos, unspecified. Persistent uses sub directly (not pairwise HMAC).
OASIS SAML 2.0 Bindings (saml-bindings-2.0-os)FullHTTP-Redirect (DEFLATE+base64), HTTP-POST (base64), and Artifact binding (type 0x0004) with SOAP resolution at POST /saml2/artifact.
OASIS SAML 2.0 Metadata (saml-metadata-2.0-os)PartialIdP and SP EntityDescriptor generation at /saml2/metadata and /saml2/sp/metadata/{upstream_id}. IdP metadata includes ArtifactResolutionService. Remote metadata import via admin API (POST /api/admin/saml2/sp/import-metadata and /saml2/idp/import-metadata) supports both bare EntityDescriptor and EntitiesDescriptor wrapper documents, with optional XML signature verification via trusted_certificate_pem. When metadata_url is stored, metadata is automatically re-fetched every [saml2] metadata_refresh_interval_secs (default 1 hour).
OASIS SAML 2.0 Profiles (saml-profiles-2.0-os)PartialWeb Browser SSO Profile (both IdP and SP roles). Single Logout Profile (front-channel only, including SP-initiated SLO).
XML Digital Signatures (xmldsig-core)Full (RSA, ECDSA)libxmlsec1-openssl FFI. Outgoing SAML Responses are signed via sign_xml when sign_responses or sign_assertions is enabled (both default to true). Incoming assertion signatures are verified in the ACS handler and SLO handler using registered certificates. Supported key types: RSA, ECDSA P-256, ECDSA P-384. EdDSA and ML-DSA keys are not supported for XML signatures.

WebAuthn / Passkeys

SpecificationStatusNotes
W3C WebAuthn Level 2 §7.2 (assertion)FullCredentials are merged from FreeIPA LDAP (ipa passkey-register) and the server’s own database at assertion time.
W3C WebAuthn Level 2 §7.1 (registration)Full
FIDO MDS / attestation statement verificationPartialDisabled by default (FreeIPA passkeys are registered externally). Set [passkey] mds_url = "https://mds3.fidoalliance.org/" to enable MDS blob fetching (refreshed every mds_refresh_interval_secs, default 24 h). Configure [passkey] mds_trusted_root_pem with the FIDO Alliance root certificate(s) for JWT blob signature verification and x5c chain validation (iterative, arbitrary depth). When enabled, revoked AAGUIDs are rejected and packed attestation is verified: with x5c, the certificate chain is walked against MDS root certificates; without x5c (self-attestation), the credential’s own public key is used for signature verification. tpm format is accepted but not cryptographically verified. Set [passkey] require_attestation = true to reject registrations with fmt: "none" or unverifiable chains.

Passkey login is enabled by setting ipa.passkey_rp_id in the configuration.

Supported COSE key types: EC2/P-256 (ES256), OKP/Ed25519 (EdDSA, COSE alg -8), RSA (RS256). FreeIPA stores passkey public keys as base64-encoded SPKI DER; ahdapa converts between SPKI DER and COSE CBOR transparently via cose_to_spki_der() / spki_der_to_cose() in src/auth/passkey.rs. Passkey management in IPA API mode uses the dedicated user_add_passkey / user_remove_passkey JSON-RPC commands.

Intentional non-implementations

These gaps are deliberate design decisions aligned with RFC 9700 (Security BCP) or the server’s scope:

  • alg=none JWTs (RFC 7519 §8): Not supported. No legitimate AS use case; security risk.
  • PKCE plain method (RFC 7636): S256-only per RFC 9700 §2.1.1.
  • Nested JWTs (RFC 7519 §5.2, §7.2): Not needed; no JWE implementation.
  • COSE support in RFC 9964: Server is JOSE-only. WebAuthn COSE algorithm integers are handled separately in src/auth/passkey.rs.
  • CORS/JSONP for revocation (RFC 7009 §2.3): Not needed; revocation is server-to-server.
  • JAR request parameter (RFC 9101): request_parameter_supported and request_uri_parameter_supported are both false in discovery. Request objects are not needed because PAR (RFC 9126) is supported and provides equivalent confidentiality and integrity without the complexity of signed/encrypted request JWTs.

Known limitations

  • RFC 7523 urn:ietf:params:oauth:grant-type:jwt-bearer: The client must have either a jwks_uri or inline jwks registered (RFC 7591 §2; mutually exclusive). The assertion iss must be present in [federation].trusted_issuers (or resolvable via a trust-chain anchor); it does not need to equal the requesting client’s client_id.
  • RFC 7591 Dynamic Client Registration: Client CRUD is available via the admin API (/api/admin/clients). The public POST /register endpoint accepts three authorization mechanisms: (1) a Kerberos service principal session from the server’s realm, (2) a JWT initial access token issued via POST /api/admin/registration-tokens (RFC 7591 §3, typ: "reg+jwt", supports one-time-use tokens), or (3) a static bearer token configured via server.registration_token. When none of these paths are available, /register returns 404.
  • Token Exchange (RFC 8693) impersonation: Full OBO delegation with actor_token is supported. Pure impersonation (acting as a different user without a subject token carrying that user’s identity) is not supported.
  • OIDC Federation 1.0: The server publishes a spec-compliant Entity Statement at /.well-known/openid-federation (including authority_hints when trust anchors are configured). Trust chain validation supports multi-hop intermediary resolution: the chain walker follows authority_hints from the leaf upward through intermediaries until a configured trust anchor is reached, with configurable max_chain_depth (default 5). Metadata policy operators (value, add, default, one_of, subset_of, superset_of, essential) are applied top-down from anchor to leaf. Resolved chains are cached with TTL derived from the shortest exp in the chain. Trust marks, subordinate listing (/list endpoint), and the /fetch endpoint for serving our own subordinate statements are not yet implemented.
  • kerberos_client_auth — HBAC hostgroup resolution: When kerberos_hbac_service is set on a Kerberos client, HBAC rules match machine principals by individual hostname and by IPA hostgroup membership. Hostgroup memberships for the requesting machine and the IdP server are resolved via LDAP at token time, and HBAC service-group memberships are also resolved. LDAP errors during group resolution are non-fatal: if the lookup fails, only direct-name and category=all rules continue to match.
  • Wrapping key distribution: The cluster wrapping key is stored locally on each node; only its UUID is gossiped. When a node sees an unfamiliar UUID it fetches the raw key via GET /api/gossip/wrapping-key, which returns a CMS EnvelopedData blob sealed to the requesting node’s ML-KEM-768 public key. Gossip sync messages themselves are wrapped in CMS SignedData(EnvelopedData) (ECDSA P-256 outer signature, ML-KEM-768 inner encryption per recipient). Restrict /api/gossip/sync and /api/gossip/wrapping-key to the cluster subnet as an additional defence-in-depth measure.