FAPI 2.0 + HAIP hardened profile
Honesty boundary: the wallet-provider root is a locally-minted in-process STAND-IN for the EU Wallet Trust Framework — NOT EU/eIDAS-accredited. The sender-constrained-token, PAR+S256 and chain-to-root MECHANISMS are real; the ROOT is a stand-in.
✓ defense-in-depth: a stolen token and a bad auth request fail at the FAPI 2.0 layer; a rogue client fails at the HAIP layer.
FAPI 2.0 secures the token/API layer (sender-constrained tokens, PAR, PKCE-S256);
HAIP secures the credential/holder layer (attestation chains to a trusted root).
A high-assurance endpoint runs both: PSDP_FAPI2_ENFORCE=1 + PSDP_HAIP_ENFORCE=1.
Scenarios
- ✓ [FAPI 2.0] compliant auth request (PAR + PKCE-S256) → ACCEPTED — allowed
- ✓ [FAPI 2.0] auth request without PAR → REJECTED — FAPI2: a pushed authorization request (PAR, RFC 9126) is required
- ✓ [FAPI 2.0] plain PKCE (S256 required) → REJECTED — FAPI2: PKCE code_challenge_method must be S256 (plain is not allowed)
- ✓ [FAPI 2.0] token request not sender-constrained → REJECTED — FAPI2: sender-constrained tokens required — present a DPoP proof (RFC 9449) or use mTLS
- ✓ [FAPI 2.0] stolen bearer access token (replayed) → REJECTED — FAPI2: bearer access tokens must be sender-constrained; present a DPoP-bound token (RFC 9449) or an mTLS-certificate-bound token (RFC 8705)
- ✓ [FAPI 2.0] sender-constrained DPoP token → ACCEPTED — allowed
- ✓ [HAIP] attester under trusted wallet-provider root → ACCEPTED — chains to trusted root
- ✓ [HAIP] rogue client (forged self-signed attester) → REJECTED — rejected: signing cert does not chain to a configured trusted wallet-provider root (HAIP trust anchor)