An overview of financial-grade or bank-grade security, to ensure that the strongest security design patterns are used when protecting data.

What is Financial-Grade Security?

On this page

Financial-grade API (FAPI) Explained

Financial-grade or bank-grade security is the process of using the strongest security design patterns when protecting data. The Financial-grade API (FAPI) working group provides guidance on constraining the OAuth 2.0 and OpenID Connect frameworks into a number of profiles suited to the financial sector, to help meet a particular set of regulatory requirements. These best practices can be used in any industry that requires the highest API security.

To be compliant and interoperable, companies in some sectors need to meet financial regulations such as:

  • Directive on Payment Services (PSD2)
  • Open Banking Implementation (OBIE) in the UK

Keeping user data private is another important regulatory requirement, which has a number of variations in different global locations:

  • Europe's General Data Protection Regulation (GDPR)
  • Australian Privacy Principles (APP)
  • Brazil's LGPD
  • South Korea's PIPA

An improved security model is also very relevant for protecting high-worth data outside the financial world. This articles teaches the main financial-grade security concerns and the best practices for dealing with them.

Modern Security Standards

OAuth and OpenID Connect are international standards that provide a framework for securing APIs. OAuth is commonly used for interoperability between companies, and can be integrated into any type of client application, including web and mobile.

FAPI Working Group

The FAPI Working Group (previously known as the "Financial-grade API Working Group") provides guidance on constraining the OAuth framework into a number of profiles suited to the financial sector to help meet a particular set of regulatory requirements.

The below documents illustrate how banking-grade applications need to go beyond normal application security to apply extra protection for sensitive data:

FAPI 2.0 is an advancement of FAPI 1.0. It takes into account the lessons learned, updated specifications and best practices regarding implementing OAuth and OpenID in high-security ecosystems. As a consequence, FAPI 2.0 aims to provide the same security as FAPI 1.0 but makes it simpler. For example, FAPI 2.0 includes an attacker model that provides an overview of the security goals of the profile and the kind of attackers it protects against. Beside the attacker model, FAPI 2.0 maintains two profiles:

Support for Evolving OAuth Standards

Some areas of the above documents are already mainstream and widely supported, whereas others are not or still under development. It is vital that the Authorization Server keeps up to date with security standards to implement financial profiles. Common extensions to the OAuth 2.0 and OpenID Connect Core standards that provide additional security and are referenced in the FAPI family of specifications are:

Security Goals

This articles outlines how to achieve the following security goals defined in the FAPI 2.0 attacker model. It includes listed and derived recommendations from the FAPI profiles.

Security GoalExample ThreatDescription
AuthorizationStolen Access Token, Leak of Authorization ResponseOnly authorized parties can access protected resources. This means, no attacker is able to successfully obtain and use an access token to access protected resources other than their own.
AuthenticationStolen IdentityUsers are who they claim to be and an attacker cannot log in under the identity of an honest user. Consequently, an attacker cannot obtain and use an ID token identifying another user for login.
Session IntegrityCSRF attacksUsers are and access what they are supposed to. Thus, an attacker cannot force a user to log in under the attacker's identity or use the resources of the attacker instead of her own.
Non-repudiationReplay attacksA sender cannot deny having sent a message. It must not be possible for an attacker to change request or response messages. A receiver must be able to verify that a message was created by a certain sender.

Components

The above threats need to be managed across all components. The following illustration shows the common components in a modern setup:

Threat management across components, APIs and clients

Strong Customer Authentication (SCA)

One of the main actions to strengthen authentication is to use Multi-Factor Authentication (MFA). MFA uses at least two of these areas:

  • Something the user knows (like a password)
  • Something the user has (like a phone or key fob)
  • Something the user is (like their voice-print or fingerprint)

With financial API transactions, the data is usually very valuable. Therefore, FAPI 1.0 guidelines indicate that users should sign in with a method of an appropriate Level of Assurance (LoA) which commonly implies MFA.

Authentication Policies

Authentication can be more complex than just a user providing credentials. There are advantages to implementing an authentication policy that can react to contextual information:

  • The user's current location may influence how they log in or whether login should be allowed.
  • A large number of prior login attempts may indicate a security threat.
  • The authentication policy may need hardening when there is an active threat.

Pairwise Pseudonymous Identifiers (PPIDs)

A financial-grade solution should aim to limit its use of personal user information. It's a good practice for the app (or a group of related apps) to receive only a generated identifier for the user and store any application-specific data against that ID.

Pairing of user IDs per sector

More sensitive values such as name and email can be stored in the Authorization Server, where they are audited and returned to the application in tokens. See the page on Pairwise Pseudonymous Identifiers for further details.

Curity Identity Server Authentication

The Curity Identity Server manages strong authentication in an extensible manner, where you can implement as many factors as you like, as a workflow, with rules based on runtime context.

Sender-Constrained Tokens

OAuth access tokens are typically bearer tokens. If a bearer token gets stolen, a malicious client can reuse the token easily to gain access to an API.

To maintain the authorization security goal, ensure that the client is the one for whom the token was issued. Enforce a proof of possession using an additional public and private key pair:

  • Proof of private key ownership is used when the client authenticates with the authorization server.
  • The authorization server then issues a hash of the public key in access tokens as a different claim.
  • Proof of private key ownership is sent whenever the client calls the API.
  • The API verifies every request's proof of ownership and ensures that the public key matches the claim in the access token.
Public Clients and DPoP

This design pattern ensures that, if an access token is stolen and a malicious client attempts to reuse the token, the API will deny access. For a successful attack, the malicious client also needs to get hold of the private key of the client to satisfy the proof of possession.

Certificate-bound Tokens

The most straightforward implementation of sender-constrained tokens is to use Mutual TLS and X509 client certificates, via Certificate-Bound Access Tokens, as described in RFC8705.

This is used for confidential client scenarios, such as API calls between companies, and relies on a Public Key Infrastructure (PKI), which most financial companies already have. In the below diagram, tokens are sent through a Mutual TLS tunnel:

Confidential Clients and Mutual TLS

The access token claim, in this case, includes a confirmation claim containing the certificate thumbprint at the time of authentication:

12345
{
"cnf": {
"x5t#S256": "FjeHcvJwiHXlr8dgnP7UvLQ7dLLMTe_3SgMYMuEpekc"
}
}

When APIs validate tokens, they also verify that the claim corresponds to the public key of the client certificate used to set up the Mutual TLS tunnel. An attacker who steals a token also needs have access to the client key for the attack to succeed.

This flow can be implemented quite easily with standard OAuth and HTTP libraries, since client certificate technology has been used between companies for many years. See the Mutual TLS Sender-Constrained Access Tokens article for further details.

DPoP-bound Tokens

Where it is not practical to use Mutual TLS and client certificates, clients may implement a technique called Demonstrable Proof of Possession (DPoP), as described in the DPoP Overview.

The client first generates a key pair that it encodes into a Json Web Key. Proof of possession is then provided by client-side code, which creates a signed JWT and includes the JWK public key in its header. The JWT is then sent in HTTP requests via a DPoP HTTP header.

Public Clients and DPoP

During authentication, the Authorization Server verifies the DPoP details and then writes an extra confirmation claim to access tokens it issues, containing the JWK's public key thumbprint.

12345
{
"cnf": {
"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
}
}

A DPoP JWT also provides claims to specify the HTTP endpoint and method that it is valid for. The DPoP JWT is a short-lived value, and a new value is sent on every API call, along with the access token, which is now a DPoP token and no longer a bearer token:

http
1234
GET /resource HTTP/1.1
Host: api.example.com
Authorization: DPoP eyJhbGci...hF1MQ
DPoP: eyJ0eXAi...4UCbQ

Implementing this flow is currently quite challenging, since standard OAuth libraries do not yet support DPoP, and you will need to write more security code than usual.

Authorization Code to Key Binding

As part of the code flow, the client redeems the authorization code from the authorization response for an access token. Though the authorization code is bound to a dedicated client ID, an attacker may use a leaked authorization code to instruct the same client to redeem the code for a token. However, the stolen authorization code was aimed for a different session and the final token represents the grant of a different user which violates the authorization security goal.

The authorization code injection attack works for both public and confidential clients. Therefore, always bind the authorization code to a one-time secret as specified by Proof Key for Code Exchange. In addition, the client may bind the authorization code to a DPoP key as drafted by Demonstration of Proof-of-Possession at the Application Layer.

API Gateway Role

A reverse proxy or API gateway is another essential part of a financial-grade solution. A key behavior we recommend is the Phantom Token Pattern, which ensures that access tokens exposed to the outside world are minimal and confidential, with the real security state stored in the Authorization Server.

The Authorization Server will support multiple routes for authentication, and one of them will terminate Mutual TLS to verify the client certificate for confidential clients:

API Gateway:Termination of Mutual TLS to verify the client certificate

Mutual TLS (if used) is terminated at the entry point to use the phantom token pattern. The reverse proxy verifies proof of possession for either Mutual TLS or DPoP clients, then forwards the public key to APIs.

API Gateway: Reverse proxy forwards the public key to APIs

APIs can also securely call each other inside the cluster when required, and on every API request, the access token's scopes and claims will be verified. For financial-grade security, this includes verifying the 'cnf' claim against the received public key.

Secure Requests and Responses

Without countermeasures the integrity of OAuth request and response parameters is not protected. An attacker, for example via a Man in the Browser (MITB) attack, can potentially intercept and tamper with OAuth request and response messages. This risk is addressed by the below specifications:

These standards provide message-level security via additional JWTs, in a similar manner to DPoP. The article on Signed Request Objects covers this topic in further depth.

Having requests signed by the client and approved by the user also provides non-repudiation. Non-repudiation is important for accountability.

Mobile Applications

Mobile applications are considered public OAuth clients. Public clients are clients without credentials. Whereas the FAPI 1.0 specification includes requirements for public clients, FAPI 2.0 completely leaves them out of scope. There are controls beyond FAPI requirements that improve the security of public clients and mobile applications as outlined in the following sections.

OAuth Best Practices

When developing OAuth mobile apps, there are risks that malicious apps could potentially intercept a login response or use the app's client ID to impersonate the genuine app.

Dealing with these risks requires some additional actions, as described in the OAuth for Mobile Apps Best Practices article, which recommends the following mitigations:

For a FAPI compliant setup, use DCR to register a per-instance OAuth client for a mobile application at the authorization server. Each instance can create its own key pair that it uses for client authentication (private_key_jwt). It registers the public key at the authorization server as part of the DCR flow. Consequently, the per-instance client becomes a confidential client that can run the code flow with PKCE and DPoP.

Alternatively, consider using the Token Handler pattern. This pattern simplifies setup significantly as the backend handles the whole OAuth flow in a secure manner. The backend client is then FAPI compliant.

Attestation

One of the weaknesses in traditional OAuth is that clients are not authenticated before user authentication begins. Consequently, any client can start a flow in the name of another.

It is possible to improve security by making additional checks against the client application before allowing an authentication attempt. See the below links for further details:

HAAPI

To make banking-grade implementations of web and mobile apps more seamlessly integrated, Curity provides a Hypermedia API Authentication (HAAPI) solution, which deals with the following concerns:

  • Client attestation is used to verify the public client's identity before authentication.
  • Sender-constrained DPoP tokens are used during the authentication flow to mitigate stolen token risks.
  • Authentication is implemented as a workflow that easily supports multiple factors.
  • The authentication policy can be dynamically updated without redeploying apps.
  • Login does not usually need to leave the app, for an improved user experience.
  • Integration is technically simple via SDKs, requiring only a moderate amount of code.

Implementing Financial-Grade

Financial-grade security requires implementations across several different components:

  • An Authorization Server that supports all of the above standards
  • An API Gateway that implements the phantom token pattern
  • A Public Key Infrastructure (PKI) for connections from confidential and attested public clients
  • Web and mobile apps must implement up-to-date flows in a best practice manner

Standard (non-financial-grade) OAuth flows are well-supported by OAuth libraries, but libraries often lack support for features such as DPoP, PAR, JAR, and JARM.

Conclusion

The Curity Identity Server has extensive support for the standards mentioned in this article. We continually improve our financial-grade capabilities for all types of OAuth clients and aim to be financial-grade by default. Find out how we can enable organizations to meet the key requirements for UK Open Banking.

For further details on the security topics in this article, see our whitepaper about Financial-Grade APIs.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial