features.attestClientAuth
draft-ietf-oauth-attestation-based-client-auth-12 - OAuth 2.0 Attestation-Based Client Authentication
Specifies whether Attestation-Based Client Authentication capabilities shall be enabled. When enabled, the authorization server shall support the attest_jwt_client_auth authentication method within the server’s clientAuthMethods configuration. This mechanism enables Client Instances to authenticate using a Client Attestation JWT issued by a trusted Client Attester and a corresponding Client Attestation Proof-of-Possession JWT generated by the Client Instance. It can also enable Client Attestation as an additional security signal alongside existing Client Authentication methods using the attestation_pop_jwt Proof-of-Possession method. When features.dPoP is enabled, the server also supports the attest_jwt_client_auth_dpop authentication method and the dpop_combined Proof-of-Possession method. In combined mode, the DPoP proof demonstrates possession of the Client Instance Key and always requires a DPoP nonce, regardless of features.dPoP.requireNonce. Enabling both features requires configuring features.dPoP.nonceSecret.
default value:
{ ack: undefined, additionalSecuritySignal: false, assertAttestationJwtAndPop: [AsyncFunction: assertAttestationJwtAndPop], // see expanded details below challengeSecret: undefined, enabled: false, getAttestationSignaturePublicKey: [AsyncFunction: getAttestationSignaturePublicKey] // see expanded details below}(Click to expand) features.attestClientAuth options details
additionalSecuritySignal
Section titled “additionalSecuritySignal”Specifies whether Client Attestation shall be accepted or required as an additional security signal alongside regular client authentication. Use optional to validate the signal when it is present, or required to require the OAuth-Client-Attestation header and a proof of possession after the client is identified. The proof uses the attestation_pop_jwt method, or dpop_combined when features.dPoP is enabled. When both proof headers are present, the Client Attestation PoP JWT is validated and the DPoP proof is handled independently.
default value:
falseassertAttestationJwtAndPop
Section titled “assertAttestationJwtAndPop”Specifies a helper function that shall be invoked to perform additional validation of the Client Attestation JWT and its proof of possession beyond the specification requirements. This enables enforcement of extension profiles, deployment-specific policies, or additional security constraints.
The pop argument is the verified Client Attestation PoP JWT, or the verified DPoP proof in combined mode. Both expose protectedHeader, payload, and key.
At the point of invocation, both JWTs have undergone signature verification and standard validity claim validation. The function may throw errors to reject non-compliant attestations or return successfully to indicate acceptance of the client authentication attempt or additional security signal.
default value:
async function assertAttestationJwtAndPop( ctx: KoaContextWithOIDC, attestation: JWTVerificationResult, pop: JWTVerificationResult, client: Client,): Promise<void> {}challengeSecret
Section titled “challengeSecret”Specifies the cryptographic secret value used for generating server-provided challenges. This value MUST be a 32-byte Buffer instance to ensure sufficient entropy for secure challenge generation. Challenges are derived from this secret rather than stored; the same value MUST be configured on all instances of a deployment and kept stable across restarts.
type:
BuffergetAttestationSignaturePublicKey
Section titled “getAttestationSignaturePublicKey”Specifies a helper function that shall be invoked to retrieve the public key used for Client Attestation JWT signature verification. At the point of this function’s invocation, only the JWT format has been validated; no cryptographic or claims verification has occurred.
The authorization server uses the resolved key to verify the Client Attestation JWT signature. An unsupported or invalid key rejects client authentication.
default value:
async function getAttestationSignaturePublicKey( ctx: KoaContextWithOIDC, header: UnknownObject, payload: UnknownObject, client: Client,): Promise<crypto.KeyObject | crypto.webcrypto.CryptoKey | JWK> { /* implementation required */ }Example: (Click to expand) Fetching attester public keys from the attester’s hosted JWKS
import * as jose from 'jose';const attesters = new Map(Object.entries({ 'https://attester.example.com': jose.createRemoteJWKSet(new URL('https://attester.example.com/jwks')),}));function getAttestationSignaturePublicKey(ctx, header, payload, client) { if (typeof header.jku === 'string' && attesters.has(header.jku)) return attesters.get(header.jku)(header); throw new Error('unsupported oauth-client-attestation attester');}