← Payment Reference GuidesAPI Security Reference

FAPI: the Financial-grade API Security Profiles

FAPI is the OpenID Foundation's hardened profile of OAuth 2.0 and OpenID Connect for APIs where a stolen token means a stolen payment. This guide covers FAPI 1.0 Baseline and Advanced, the FAPI 2.0 Security Profile and its attacker model, Message Signing and CIBA — what each one requires, the authorization-code flow message by message, which open-banking ecosystems mandate which profile, and a checklist for shipping it.

Message Signing: non-repudiation

The Security Profile guarantees that nobody but the right client can use a token. It does not let a bank prove, a year later and to a court, that this TPP asked for this payment — TLS gives integrity in transit, not an artefact you can store. FAPI 2.0 Message Signing adds application-level signatures for exactly that, defined as separately certifiable options so an ecosystem can mandate the ones it needs:

MessageMechanismKey rules
NR1 / NR2 pushed and front-channel authorization requestsJAR (RFC 9101) signed request object, sent to the PAR endpointaud is (or contains) the issuer URL; nbf at most 60 min in the past; exp at most 60 min after nbf; typ: oauth-authz-req+jwt. Because the request went through PAR, the front-channel request is covered automatically.
NR3 authorization responsesJARM — response_mode=jwtThe whole response (code, state, iss) is one signed JWT; iss lives inside the JWT, not beside it. Encryption of the JARM response is possible but is not what non-repudiation needs.
NR4 introspection responsesRFC 9701 JWT introspection responsesThe resource server requests application/token-introspection+jwt and verifies the signature — a stored proof of what the AS said about a token.
NR5 ID tokensAlready signed under the Security ProfileClients verify the signature; no new server requirement.

And the API calls themselves? HTTP Message Signatures

Signing the resource requests and responses — the payment order and the bank's acknowledgement — was split out of Message Signing into a separate FAPI 2.0 HTTP Signing draft built on RFC 9421 HTTP Message Signatures: a Signature-Input header naming the covered components (method, target URI, selected headers, Content-Digest of the body) and a Signature header carrying the signature. It is the same mechanism as Web Bot Auth and Visa's Trusted Agent Protocol in agentic payments — decode one in the HTTP Message Signature decoder. Until ecosystems adopt it, FAPI 1.0 deployments typically rely on JWS-signed payloads (UK Open Banking's x-jws-signature) or eIDAS seals for the same purpose.

mTLS or DPoP?

Both satisfy the sender-constraint requirement. The Security Profile's security considerations are candid about the trade-off:

mTLS (RFC 8705)DPoP (RFC 9449)
Where the binding livesTLS layer: the client certificate on the connection.Application layer: a signed JWT per request.
DeploymentNeeds a TLS terminator that passes the client certificate to the application; harder behind CDNs and managed load balancers. eIDAS QWACs already exist in PSD2 ecosystems.Works through any TLS terminator; the client just needs a key pair.
What is coveredEverything on the connection — body and all headers.Method, URI, access-token hash, timestamp, nonce. Not the body or most headers.
Attacker A5 (reads processed resource requests)Cannot reuse the request — no certificate.Could replay the proof, possibly against an altered body (different amount or payee) within its freshness window. Mitigations: short-lived server nonces, jti replay detection, signed resource requests, or choosing mTLS.
Clock sensitivityNone beyond certificate validity.iat freshness — hence the 10 s / 60 s skew rules and the nonce mechanism.
Rule of thumb. For a payment API where a replayed-but-altered request is the nightmare, use mTLS or DPoP plus signed resource requests. For read-only data APIs, DPoP with server nonces is a pragmatic choice.

Related tools: HTTP Signature Decoder · Base64URL decoder (take a JWT apart) · ASN.1 / DER decoder (client certificates) · SHA-256 (compute ath and x5t#S256)

Put it into practice

Next steps

Keep reading

Related articles