Reference
Payment Certification Levels
A practical guide to EMVCo L1 / L2 / L3 terminal certifications, PCI DSS merchant compliance tiers, and the standards that govern every card-present transaction.
FAPI — Financial-grade API Security Profiles
The OpenID Foundation's hardened profile of OAuth 2.0 / OpenID Connect for APIs that move money or expose regulated data. FAPI picks the secure option for every choice OAuth leaves open and adds hard limits; open-banking ecosystems mandate it and require certification before onboarding. Cheatsheet below — the full walkthrough is in the FAPI guide.
Profiles at a glance
| Document | Status | Scope | Signature features |
|---|---|---|---|
| FAPI 1.0 Part 1: Baseline | Final · Mar 2021 | Read-only APIs | Confidential clients, TLS 1.2+, PKCE, code flow, x-fapi-* headers |
| FAPI 1.0 Part 2: Advanced | Final · Mar 2021 | Read-write APIs | Signed request objects (JAR), hybrid code id_token or JARM, mTLS / private_key_jwt, certificate-bound tokens, PS256 / ES256 |
| FAPI 2.0 Security Profile | Final · Feb 2025 | One read-write profile | PAR + PKCE S256, response_type=code only, iss in response, tokens bound by mTLS or DPoP, formally analysed against the Attacker Model |
| FAPI 2.0 Attacker Model | Final · Feb 2025 | Companion | Security goals and attackers A1, A1a, A2, A3a, A5 (A4 informative) |
| FAPI 2.0 Message Signing | Final · Sep 2025 | Non-repudiation add-on | JAR at the PAR endpoint, JARM responses, RFC 9701 signed introspection, signed ID tokens — each certifiable separately |
| FAPI-CIBA | Implementer's Draft | Decoupled flows | Signed backchannel requests, poll and ping modes only |
| FAPI 2.0 HTTP Signing | Draft | Resource requests / responses | RFC 9421 HTTP Message Signatures with Content-Digest |
| ISO/IEC 26083-1 / -2 | DIS ballot closed Jan 2026 | ISO track for FAPI 2.0 | Security Profile and Attacker Model as international standards (publication pending) |
FAPI 2.0 building blocks
| Spec | Role | Mandatory? |
|---|---|---|
RFC 9126 PAR | All authorization parameters server-to-server; browser carries client_id + request_uri only | Yes |
RFC 7636 PKCE | S256, fresh per request; CSRF and code-injection defence | Yes |
RFC 9207 | iss in the authorization response; client checks it (mix-up defence) | Yes |
RFC 8705 mTLS | Client authentication and certificate-bound tokens (cnf.x5t#S256) | One of mTLS / DPoP for binding; one of mTLS / private_key_jwt for client auth |
RFC 9449 DPoP | Proof-of-possession JWT per request; tokens bound to cnf.jkt; server nonces; dpop_jkt code binding | Alternative to mTLS binding |
OIDC Core §9 private_key_jwt | Client assertion, aud = issuer identifier as a string | Alternative to mTLS client auth |
RFC 8414 / OIDC Discovery | Only source of endpoint URLs; issuer must match the URL | Yes |
RFC 9700 (BCP 240) | OAuth 2.0 Security BCP: no open redirectors, no 307 with credentials, one-time codes | Yes |
RFC 8725 | JWT BCP for every JWT handled | Yes |
RFC 9396 RAR | authorization_details for payments and fine-grained consent | Recommended |
RFC 9101 JAR · JARM · RFC 9701 | Signed requests, responses, introspection | Only with Message Signing |
Authorization server: the "shall" list (FAPI 2.0)
Clients, grants, tokens
- Confidential clients only; password grant rejected
- Only sender-constrained access tokens (mTLS or DPoP)
- Client auth: mTLS or
private_key_jwtonly - No refresh-token rotation (except migrations, with retry)
- Metadata published; no open redirectors
- JWT
iat/nbf: accept ≤ 10 s future, reject > 60 s
Authorization endpoint
response_type=codeonly- PAR required and authenticated; non-PAR requests rejected
- PKCE S256 required;
redirect_urirequired in PAR issreturned in every response- No
httpredirect URIs (loopback excepted); codes single-use - No HTTP 307; 303 recommended; no CORS on
/authorize
Clients & resource servers
- Client: PAR always, fresh PKCE bound to the user agent, check
iss, endpoints from metadata only - Client: support refresh tokens,
mtls_endpoint_aliases, DPoP nonces - RS: tokens in the
Authorizationheader only, never query strings - RS: verify validity, expiry, revocation, scope and the sender constraint
Numbers & algorithms
| Item | Value |
|---|---|
| Authorization code lifetime | ≤ 60 s, single use |
PAR request_uriexpires_in | < 600 s, single use enforced at authorization |
Clock skew on iat / nbf | Must accept 0–10 s in the future; must reject > 60 s |
| Signed request object (Message Signing) | nbf ≤ 60 min old; exp ≤ 60 min after nbf; typ=oauth-authz-req+jwt; aud = issuer |
OIDC nonce | Servers support ≤ 64 characters |
| JWS algorithms | PS256, ES256, EdDSA (Ed25519); never none, RS256 or HS256 |
| Key sizes | RSA ≥ 2048 bits · EC ≥ 224 bits |
| Token / code entropy | ≥ 128 bits |
| TLS | 1.2+, BCP 195, RFC 9525 certificate checks; server-to-server endpoints use only recommended cipher suites; preloaded HSTS for browser endpoints |
| Access token | Short-lived (minutes) with refresh tokens for long grants (recommendation) |
FAPI 1.0 Advanced → 2.0 in one table
| FAPI 1.0 Advanced | FAPI 2.0 | Reason |
|---|---|---|
| JAR | PAR | Request integrity without a front-channel signature |
| JARM / hybrid flow | code only | Nothing left in the response worth signing |
s_hash + state | PKCE | PKCE carries the CSRF protection |
| Pre-registered redirect URIs | Redirect URI in PAR | Authenticated PAR makes pre-registration unnecessary |
| ID token as detached signature | PKCE | ID token no longer doubles as a signature |
exp/nbf in request object | Short-lived request_uri | Stops pre-generated requests |
| mTLS-bound tokens | mTLS or DPoP | DPoP deploys behind any TLS terminator |
x-fapi-* headers | Implementation & Deployment Advice | Not part of the security core |
The x-fapi-* headers
| Header | Direction | Meaning |
|---|---|---|
x-fapi-interaction-id | Request and response | UUID correlating one API interaction across client and server logs; the server echoes the client's value or mints one |
x-fapi-auth-date | Request | When the user last authenticated at the client (RFC 7231 date), for risk decisions |
x-fapi-customer-ip-address | Request | The user's IP when the user is present; its absence marks an unattended (batch) call, which ecosystems rate-limit |
Ecosystems & certification
| Ecosystem | Profile (Oct 2026) |
|---|---|
| UK Open Banking | FAPI 1.0 Advanced + FAPI-CIBA |
| Open Finance Brasil | FAPI 1.0 Advanced (FAPI-BR), migrating to 2.0 |
| Australia CDR | FAPI 1.0 Advanced; 2.0 under consultation |
| ConnectID (AU) · UAE Open Finance · US FDX | FAPI 2.0 |
| Saudi Arabia (SAMA) | FAPI 1.0 Advanced |
| EU PSD2 (Berlin Group / STET) | No FAPI mandate; eIDAS QWAC / QSealC; openFinance framework references FAPI 2.0 |
Certification. The OpenID Foundation's open-source conformance suite tests authorization servers and clients against FAPI 1.0 Advanced, FAPI 2.0 Security Profile (with mTLS /
private_key_jwt × mTLS / DPoP variants), FAPI 2.0 Message Signing and FAPI-CIBA; passing results are self-certified and published. Ecosystems generally require a current certificate for onboarding. Deep dive: who mandates which profile · the flow message by message. Related Tools
Use these tools to work with the cryptographic primitives that underpin terminal and card security.