The purpose of a security profile
The printer's Pay by bank option has appeared throughout Advanced OAuth. By the end of Processing and validating a request, paying for your 42.50 EUR photo book worked like this: the printer's client photo-printer-pay pushed a payment_initiation request to Lakeside Bank's PAR endpoint, authenticated with a signed client assertion, and received a bearer token that allowed exactly one payment. You approved it at the bank, and the printer never saw your account details.
Every mechanism in that flow was a choice made for one integration: pushing the request, authenticating with a signed assertion, accepting a bearer token. The printer read Lakeside's documentation and built what Lakeside supports. That works for one bank. The printer wants Pay by bank to work with every bank its customers use.
One framework, many choices
OAuth 2.0 calls itself a framework, and the earlier lessons have met its choices again and again. A client can authenticate with a secret, a signed assertion, or a certificate. Tokens can be bearer tokens or bound with DPoP or mutual TLS. A server can return iss in its authorization responses or rely on distinct redirect URIs. Refresh tokens can be rotated or not. Even small details varied: Secrets and signed assertions described how servers once accepted their token endpoint's address, their issuer identifier, or a list of values in a client assertion's aud claim, until researchers showed how that flexibility could be abused.
Pay by bank is rarely a one-bank feature. In many countries, regulation or industry agreements require banks to let customers share account information or start payments through authorized third-party applications, using APIs. These open banking ecosystems involve many banks, each running its own authorization server and APIs, and many third parties, each connecting to many banks. A central directory often records which participants are authorized and which keys or certificates they use.
If every bank in such an ecosystem made its own choices, every third party would maintain a slightly different integration for each bank, and test each one separately. Worse, customers' money would be only as safe as the weakest combination any bank chose.
What a security profile does
A security profile is a specification that takes a framework and its extensions and makes the choices once, for everyone who adopts it. It says which mechanisms are required, which are forbidden, which algorithms and values are allowed, and what limits apply to lifetimes and key sizes. Where the underlying specifications say a server may do something, a profile often says it shall or shall not.
That serves two purposes at once. A client written to the profile works with every server that follows it, which is interoperability. And the weak or risky options are gone, leaving fewer combinations to get wrong, which is security. The assertion audience is a small example. A profile can require the issuer identifier, as a single string, and require servers to accept nothing else.
FAPI, developed by the OpenID Foundation's FAPI working group, is an OAuth security profile that open banking, open data, and identity initiatives in many countries have adopted. It began as the Financial-grade API Security Profile, finalized in 2021 in two parts, a baseline and an advanced version. Its successor, the FAPI 2.0 Security Profile, was published as a final specification in February 2025. It is simpler to implement than its predecessor and describes itself as a general-purpose, high-security profile, meant for any API whose data or actions need that level of protection, not only banking. A companion specification, FAPI 2.0 Message Signing, adds signed requests and responses for ecosystems that need to prove later who sent a particular message, such as a payment instruction.
Ecosystems usually build their own rules on top. An open banking ecosystem might allow only one of FAPI's options, require certificates from its directory's CA, and define its own payment API. Narrowing is allowed. Removing or overriding one of FAPI 2.0's mandatory behaviors is not, because the profile's security argument depends on all of them together.
Starting from an attacker model
Many security documents grow as lists: an attack is discovered, a defense is added. FAPI 2.0 starts from the other end. A separate document, the FAPI 2.0 Attacker Model, describes what attackers are assumed to be able to do and which goals must hold anyway. The profile's mechanisms were then chosen, and analyzed formally, to meet those goals against those attackers.
| Attacker | Assumed to be able to |
|---|---|
| Web attacker | Run their own websites and clients, take part in flows with their own accounts, and send people links. They cannot read other people's traffic or break cryptography. |
| Web attacker acting as an authorization server | Do all of that and also run an authorization server that clients in the ecosystem trust, like Pixel Vault in Authorization server mix-up. |
| Network attacker | Intercept, block, and change traffic, as a rogue Wi-Fi access point could, without breaking cryptography. |
| Reader of authorization requests | Read authorization requests as they pass through the browser, for example from browser history, an app registered for the same address, or software that inspects traffic. |
| Reader of resource requests | Read requests to an API after the API has processed them, for example from the logs of a proxy that inspects traffic. |
Attackers may combine these abilities and work together. Against all of them, three goals must hold. No attacker can obtain and use an access token for anyone's resources but their own. Where OpenID Connect is used for sign-in, no attacker can sign in to a client as someone else. And no attacker can trick you into using the attacker's resources or identity instead of your own, the kind of attack Request correlation and CSRF walked through, where your printer account ended up linked to the attacker's photo library.
The model is just as clear about what it leaves out. It assumes TLS itself is not broken, that the people using the system have browsers and devices that are not compromised, and that private keys have not leaked through human error. It does not cover breached servers, how people sign in to their bank, or bugs in an implementation. Those risks are real, and a deployment has to address them separately. A profile can only promise what its model covers.
Within that model, what FAPI 2.0 requires is mostly familiar. Its defenses are mechanisms from earlier lessons, most of them from the Advanced OAuth groups, each one made mandatory and fitted together with the others.