Exploring FAPI 2.0: The Latest in API Security Technology
Tags: fapi, oauth, security, finance
Published: 2024-04-10 17:50:20

FAPI is a set of standards for ensuring secure and interoperable exchanges of information  especially in higher risk situations, for example, the healthcare, the financial industry, e-government and so on. Originating with FAPI 1.0, which utilized OAuth 2.0 and OpenID Connect to secure transactions, it has evolved into FAPI 2.0. This latest version enhances security by incorporating the newest protocols, offering advanced data protection — whilst also making the specification easier to implement.

## Components

![](https://res.cloudinary.com/practicaldev/image/fetch/s--9zVfYHiB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2A3lpcOix9n3uCp4m6WLFW6A.png)

FAPI 2.0 introduces a comprehensive framework for enhancing API security, presented through four key components:

**Security Profile**  
Defines the fundamental requirements in FAPI 2.0, utilizing the latest security specifications such as “PAR”, “DPoP”, etc. (This profile was previously called “Baseline Profile”.)

**Message Signing Profile**  
Provides interoperable support for non-repudiation across OAuth 2.0-based requests and responses. (This profile was previously called “Advanced Profile”.)

**Attacker Model**  
Details potential threats, guiding the development of robust security measures.

**Grant Management**  
Defines an extension of OAuth 2.0 to allow clients to explicitly manage their grants with the authorization server.

## History

![](https://res.cloudinary.com/practicaldev/image/fetch/s--egWRPBUy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2A--68Lh2qE8Y7JkgMzEgjNg.png)

**FAPI 1.0 Final Version** (March, 2021)

-   [**Financial-grade API Security Profile 1.0 — Part 1: Baseline**](https://openid.net/specs/openid-financial-api-part-1-1_0-final.html)
-   [**Financial-grade API Security Profile 1.0 — Part 2: Advanced**](https://openid.net/specs/openid-financial-api-part-2-1_0-final.html)

For a deeper understanding of FAPI 1.0, “[Financial-grade API (FAPI), explained by an implementer](https://darutk.medium.com/financial-grade-api-fapi-explained-by-an-implementer-d09fcf2ff932)” is very helpful.

**FAPI 2.0 Implementer’s Draft 1**

-   [**FAPI 2.0 Baseline Profile**](https://openid.net/specs/fapi-2_0-baseline-ID1.html) (July, 2021)
-   [**FAPI 2.0 Attacker Model**](https://openid.net/specs/fapi-2_0-attacker-model-ID1.html) (July, 2021)
-   [**Grant Management for OAuth 2.0**](https://openid.net/specs/fapi-grant-management-ID1.html) (July, 2021)
-   [**FAPI 2.0 Message Signing Profile**](https://openid.net/specs/fapi-2_0-message-signing-ID1.html)  (March, 2023)

NOTE: “**Advanced Profile**” was renamed to “**Message Signing Profile**”.

**FAPI 2.0 Implementer’s Draft 2**

-   [**FAPI 2.0 Security Profile**](https://openid.net/specs/fapi-2_0-security-profile-ID2.html)  (December, 2022)
-   [**FAPI 2.0 Attacker Model**](https://openid.net/specs/fapi-2_0-attacker-model-ID2.html)  (December, 2022)

NOTE: “**Baseline Profile**” was renamed to “**Security Profile**”.

## Certification Program

As of February 2024,  [The Certification Program for FAPI OpenID Providers](https://openid.net/certification/)  offers the following FAPI 2.0 certification programs for both OpenID providers and relying parties.

-   [FAPI 2.0 Security Profile Second Implementer’s Draft & Message Signing First Implementer’s Draft](https://openid.net/certification/#FAPI2-SECURITY)
-   [Australia FAPI 2.0 ConnectId Implementer’s Draft](https://openid.net/certification/#FAPI2-CONNECTID-AUS)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--hB2pSNAh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AL_aDOhz6-6GeXVu5LOnPpw.png)
![](https://res.cloudinary.com/practicaldev/image/fetch/s--hB2pSNAh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AL_aDOhz6-6GeXVu5LOnPpw.png)

Before walking through FAPI 2.0, it is recommended to understand the following specifications, which are leveraged by FAPI 2.0 as its basis.

- [RFC 6749](https://www.rfc-editor.org/info/rfc6749)  — OAuth 2.0 Authorization Framework
- [RFC 6750](https://www.rfc-editor.org/info/rfc6750)  — OAuth 2.0 Authorization Framework: Bearer Token Usage
- [RFC 7636](https://www.rfc-editor.org/info/rfc7636)  — Proof Key for Code Exchange by OAuth Public Clients (PKCE)
- [RFC 8705](https://www.rfc-editor.org/info/rfc8705)  — OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (MTLS)
- [RFC 9449](https://www.rfc-editor.org/info/rfc9449)  — OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- [RFC 9126](https://www.rfc-editor.org/info/rfc9126)  — OAuth 2.0 Pushed Authorization Requests (PAR)
- [RFC 8414](https://www.rfc-editor.org/info/rfc8414)  — OAuth 2.0 Authorization Server Metadata
- [RFC 9207](https://www.rfc-editor.org/info/rfc9207)  — OAuth 2.0 Authorization Server Issuer Identification
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)

Articles below may help understand some of these specifications.

-   [The Simplest Guide To OAuth 2.0](https://darutk.medium.com/the-simplest-guide-to-oauth-2-0-8c71bd9a15bb)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--FWGA6yTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2Aw0hTIKZuTprM509dWpixkg.png)

-   [Diagrams And Movies Of All The OAuth 2.0 Flows](https://darutk.medium.com/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--V26u-wVi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AylwGO216W7nF77aeJJY7bA.png)

-   [Diagrams of All The OpenID Connect Flows](https://darutk.medium.com/diagrams-of-all-the-openid-connect-flows-6968e3990660)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--TB22n8Y0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AOdpeFh9AwfemDl39BrvsGw.png)

-   [Understanding ID Token](https://darutk.medium.com/understanding-id-token-5f83f50fa02e)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--hVKT1uOm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2ARbmtOhGqkbJNpXma4I_Exg.png)

-   [Illustrated PAR: OAuth 2.0 Pushed Authorization Requests](https://darutk.medium.com/illustrated-par-oauth-2-0-pushed-authorization-requests-652d71ed5cfb)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--Vo-S-q47--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2A_9Z4cNV1FxjUjGegf5BGyg.png)

-   [Illustrated DPoP (OAuth Access Token Security Enhancement)](https://darutk.medium.com/illustrated-dpop-oauth-access-token-security-enhancement-801680d761ff)

![](https://res.cloudinary.com/practicaldev/image/fetch/s--SC7DXYol--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AJm_cycF0DrCLqXmabIQQfw.png)

**Client Authentication**

FAPI 2.0 Security Profile allows the following methods as the client authentication methods.

**Client Authentication utilizing MTLS**

[Section 2 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-2)  defines two client authentication methods utilizing MTLS.

`tls_client_auth`  
In this method, the client presents its certificate (X.509 certificate) during the TLS handshake, which the authorization server verifies against a trusted Certificate Authority (CA). The server identifies the client using Subject Distinguished Name (DN) or Subject Alternative Name (SAN) from the certificate. This approach ensures the client not only has a valid certificate but also possesses the corresponding private key.

`self_signed_tls_client_auth`  
In this method, clients are authenticated using self-signed certificates. Unlike `tls_client_auth`, the client's certificate chain is not validated against a trusted CA. Instead, the client registers its certificate with the authorization server, and authentication is successful if the certificate presented during the TLS handshake matches the one registered for the client.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--zqrKibuz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2Ar3m3cPsKwYA0Fj0qKQselw.png)

If you are interested in the mechanism of X.509 certificates, refer to “[Illustrated X.509 Certificate](https://darutk.medium.com/illustrated-x-509-certificate-84aece2c5c2e)”.

**Client Authentication using Private Key Signed JWT**

This authentication method refers to the following method listed in  [Section 9 of OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication).

`private_key_jwt`  
  
In this method, the client creates a JSON Web Token (JWT) and signs it with its private key. This JWT contains claims such as issuer and audience and is sent to the authorization server as a client assertion. The server then verifies the JWT’s signature using the client public key and checks the JWT’s validity based on its claims. Utilizing asymmetric cryptography, this method ensures security, as the private key is never exposed.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--a3uV9RkK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2ADUojvo9mEY73ZqtrxHzK0Q.png)

**Sender-constrained access token mechanism**

FAPI 2.0 Security Profile mandates authorization servers must issue access tokens using MTLS or DPoP ([OAuth 2.0 Demonstrating Proof-of-Possession](https://www.rfc-editor.org/info/rfc9449)) as a sender-constraining mechanism for access tokens. This is a countermeasure against malicious use of access tokens in the case of token leakage by presenting an access token along with the proof-of-possession for it.

**MTLS for sender-constrained access tokens**

[Section 3 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-3) defines a sender-constraning mechanism for access tokens utilizing MTLS. Here’s how it works.

1.  A client requests an access token (to the token endpoint).
2.  The authorization server obtains a client certificate during the process of establishing MTLS connection with the client.
3.  The authorization server binds the client certificate to the access token when issuing an access token.
4.  The client sends a request to the resource server with the access token and the client certificate.
5.  The resource server ensures the access token is bound to the client certificate.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--r7t-gaNk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AgGApTrUS-Mte9QgeXSnZzQ.png)

**DPoP (RFC 9449: OAuth 2.0 Demonstrating Proof of Possession)**

DPoP ([RFC 9449: OAuth 2.0 Demonstrating Proof of Possession](https://www.rfc-editor.org/info/rfc9449)) is another access token sender-constraining mechanism allowed in FAPI 2.0 Security Profile. Here’s how it works.

1.  The client creates a DPoP proof JWT, which is a signed JWT, using a client’s private key.
2.  The client sends a token request including the DPoP proof JWT.
3.  Upon receiving the request, the authorization server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
4.  Then the authorization server binds the thumbprint of the public key to the issued access token.
5.  The authorization server issues the access token.
6.  Before accessing resources, the client creates a new DPoP proof JWT using the same private key.
7.  The client sends a request to the resource server with the access token and the DPoP proof JWT.
8.  Upon receiving the request, the resource server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
9.  The resource server verifies the DPoP proof and ensures the access token is bound to the public key. This process ensures the client who presented the access token to the resource server is the client to whom the access token is issued.

For more detailed information about DPoP, refer to “[Illustrated DPoP (OAuth Access Token Security Enhancement)](https://darutk.medium.com/illustrated-dpop-oauth-access-token-security-enhancement-801680d761ff)”.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--lhE_QsCr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AThHAcvgi6Hn65-cV0eukWA.png)

**Authorization Code Binding to DPoP Key**

RFC 9449 also introduces the  `dpop_jkt`  request parameter in authorization requests. This parameter ensures proof-of-possession for authorization codes by binding the authorization code to the thumbprint of the client’s public key. This mechanism can enable end-to-end binding of the entire authorization flow. Here’s how it works.

1.  The client computes a thumbprint of the public key.
2.  The client sends an authorization request including the thumbprint as the  `dpop_jkt`  parameter.
3.  The authorization server binds the  `dpop_jkt`  value with the authorization code.
4.  The authorization server issues the authorization code.
5.  The client creates a DPoP proof JWT, which is a signed JWT, using a client’s private key.
6.  The client sends a token request including the DPoP proof JWT.
7.  Upon receiving the request, the authorization server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
8.  Then, the authorization server ensures the authorization code is bound to the thumbprint of the public key in the DPoP proof JWT.
9.  Then, the authorization server binds the public key to the issued access token.
10.  The authorization server issues the access token.
11.  Before accessing resources, the client creates a new DPoP proof JWT using the same private key.
12.  The client sends a request to the resource server with the access token and the DPoP proof JWT.
13.  Upon receiving the request, the resource server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
14.  The resource server verifies the DPoP proof and ensures the access token is bound to the public key in the presented DPoP proof. This process ensures the client who presented the access token to the resource server is the client to whom the access token is issued.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--mUZdbKtT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AOUKd90eRIExZX8YgBzFlfg.png)

**DPoP Nonce**

The DPoP Nonce mechanism helps to limit the lifespan of DPoP proof JWTs, offering protection against the future misuse of intercepted proofs. Here’s how it works.

1.  The client creates a DPoP proof JWT including a server-provided nonce value.
2.  The client sends a token request including the DPoP proof JWT.
3.  The authorization server verifies the signature of the DPoP proof JWT.
4.  The authorization server ensures the nonce value in the DPoP proof JWT matches the one it provided earlier.
5.  An attacker steals the DPoP proof JWT from the client.
6.  The attacker sends a request including the DPoP proof JWT to the authorization server.
7.  The authorization server verifies the signature of the DPoP proof JWT.
8.  The authorization server checks the nonce in the DPoP proof JWT and finds that it is invalid due to its lifetime, the number of times it has been used, etc. Then the request is rejected.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--jTNzgLju--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2Afhdqne1ckbK8rOxzLV2Nvw.png)

## [](https://dev.to/new#security-profile)Security Profile

In the following sections, we will explore  [FAPI 2.0 Security Profile (ID2)](https://openid.net/specs/fapi-2_0-security-profile-ID2.html).

### [](https://dev.to/new#introduction)Introduction

As described in “[5.1. Introduction](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.1)”, FAPI 2.0 Security Profile is based on OAuth 2.0 ([RFC 6749](https://www.rfc-editor.org/info/rfc6749)) and designed to meet the security objectives specified in  [Attacker Model](https://openid.net/specs/fapi-2_0-attacker-model.html). It serves as a foundation for the FAPI 2.0 Framework. Other specifications that are part of this framework and may be used together with this profile include  [FAPI Message Signing](https://openid.net/specs/fapi-2_0-message-signing.html),  [FAPI CIBA](https://openid.net/specs/openid-financial-api-ciba.html),  [Grant Management](https://openid.net/specs/fapi-grant-management.html), and RAR ([RFC 9396, Rich Authorization Requests](https://www.rfc-editor.org/info/rfc9396)). It also notes the current limitations in securing public clients to these standards.

### [](https://dev.to/new#network-layer-protections)Network Layer Protections

“[5.2. Network Layer Protections](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.2)” outlines requirements for network layer protections. The summary is as follows:

**5.2.1. Requirements for all endpoints**

-   For all endpoints, TLS 1.2 or later is mandatory to shield against network threats, following  [RFC 7525](https://www.rfc-editor.org/info/rfc7525)’s secure TLS usage guidelines.
-   DNSSEC is recommended to prevent DNS spoofing that might enable rogue domain-validated TLS certificate issuance.
-   A crucial TLS server certificate verification, as outlined in  [RFC 6125](https://www.rfc-editor.org/info/rfc6125), is required.
-   Despite the use of higher validation certificates, the risk of impersonation via rogue certificates exists, with CAA records ([RFC 8659](https://www.rfc-editor.org/info/rfc8659)) suggested as a countermeasure.

**5.2.2. Requirements for endpoints not used by web browsers**  
  
For endpoints not accessed by web browsers and using TLS 1.2:

-   The server must only allow the cipher suites listed below.
-   The client should only allow the cipher suites listed below.
-   For the cipher suites  `TLS_DHE_RSA_WITH_AES_128_GCM_SHA256`  and  `TLS_DHE_RSA_WITH_AES_256_GCM_SHA384`, a minimum key length of 2048 bits is required.

Permitted TLS 1.2 cipher suites include:

-   `TLS_DHE_RSA_WITH_AES_128_GCM_SHA256`
-   `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`
-   `TLS_DHE_RSA_WITH_AES_256_GCM_SHA384`
-   `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`

**5.2.3. Requirements for endpoints used by web browsers**

-   For browser endpoints, methods preventing TLS Stripping attacks, like preloaded HTTP Strict Transport Security (HSTS) as per  [RFC 6797](https://www.rfc-editor.org/info/rfc6797), are required.
-   Domains such as  `.bank`  and  `.insurance`  enforce this protection for all subdomains. Additionally, when TLS 1.2 is in use, only cipher suites recommended in  [RFC 7525](https://www.rfc-editor.org/info/rfc7525)  are permitted.

### Requirements for Authorization Servers

“[5.3.1. Requirements for Authorization Servers](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.1)” lists requirements for authorization servers.

**General Requirements**

“[5.3.1.1. General Requirements](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.1)” lists general requirements for authorization servers. Let’s go through them.

> _1. shall distribute discovery metadata (such as the authorization endpoint) via the metadata document as specified in [OIDD] and [RFC8414]_

Authorization servers must support the “well-known” URI (e.g.  `https://as.example.com/.well-known/openid-configuration`) to expose server metadata as specified in  [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html)  and  [RFC 8414](https://www.rfc-editor.org/info/rfc8414).

Below is an example of the metadata of an authorization server.  

```
{  
  "issuer": "https://as.example.com",  
  "authorization_endpoint": "https://as.example.com/authz",  
  "token_endpoint": "https://as.example.com/token",
  "token_endpoint_auth_methods_supported": ["client_secret_basic", 
  "private_key_jwt"],  
  ...
}
```

> _2. shall reject requests using the resource owner password credentials grant or the implicit grant described in [RFC6749] or the hybrid flow as described in [OIDC]_

The table below shows all the response types and their corresponding requirements as stated in this clause.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--cJfXlzwd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2A5TRrxUF5yNvpujuGLRx07A.png)

While the use of  `response_type=none`  is not explicitly prohibited here, “[5.5. Main Differences to FAPI 1.0](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.5)” mandates the use of  `response_type=code`. Then, this requirement indirectly disallows the use of  `response_type=none`. Consequently,  `code`  is the only valid  `response_type`  value within FAPI 2.0 Security Profile.

Also, this clause disallows the resource owner password credentials grant or the implicit grant. Therefore,  `grant_type`  values including the following values are allowed:

- `authorization_code`  (Authorization Code Grant)
- `refresh_token`  (Refresh Token Flow)
- `client_credentials`  (Client Credential Grant)
- `urn:openid:params:grant-type:ciba`  ([CIBA](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html))

> _3. shall support confidential clients as defined in [RFC6749]_

Authorization servers must support confidential clients as defined in  [RFC 6749](https://www.rfc-editor.org/rfc/rfc6749.html).

> _4. shall only issue sender-constrained access tokens,_
> 
> _5. shall use one of the following methods for sender-constrained access tokens:_
> 
> _• MTLS as described in [RFC8705]_
> 
> _• DPoP as described in [I-D.ietf-oauth-dpop]_

This requires authorization servers to support  [MTLS](mtls-for-senderconstrained-access-tokens) ([RFC 8705](https://www.rfc-editor.org/info/rfc8705)) or DPoP ([RFC 9449](https://datatracker.ietf.org/doc/html/rfc9449)) as a sender-constraining mechanism for access tokens and issue sender-constrained access tokens using either of them. This prevents the use of intercepted access tokens.

> _6. shall authenticate clients using one of the following methods:_
> 
> _• MTLS as specified in section 2 of [RFC8705]_
> 
> _• private_key_jwt as specified in section 9 of [OIDC]_

Specifically, the authentication methods allowed in FAPI 2.0 Security Profile are as follows.

-   `tls_client_auth`  (defined in  [section 2.1 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.1))
-   `self_signed_tls_client_auth`  (defined in  [section 2.2 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.2))
-   `private_key_jwt`  (defined in  [section 9 of OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication))

The table below shows client authentication methods allowed in FAPI 1.0 and FAPI 2.0 Security Profile.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--Gy2p2ujT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AOYCRpIREa_XyP6Bizl1v5Q.png)

See the "Client Authentication" section for more details about these authentication methods.

> _7. shall not expose open redirectors (see section 4.10 of [I-D.ietf-oauth-security-topics])_

This refers to  [section 4.10 of OAuth 2.0 Security Best Current Practice](https://www.ietf.org/archive/id/draft-ietf-oauth-security-topics-21.html#section-4.10), which mandates that authorization servers and clients must not have open redirectors. An open redirector is a security vulnerability where a malicious actor can use a legitimate website to redirect users to a different, possibly malicious, site without their knowledge. This practice is often used in phishing attacks.

> _8. shall accept its issuer identifier value (as defined in [[RFC8414](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#RFC8414)]) in the `aud` claim received in client authentication assertions._

When an authorization server authenticates clients using  `private_key_jwt`, the authorization server must accept its issuer identifier value as the  `aud`  claim contained in client assertions. Technically, the value of the  `aud`  claim in client assertions must be either a string that matches the authorization server’s issuer identifier (e.g.  `"https://as.example.com"`) or a string array containing the issuer identifier value (e.g.  `["https://as.example.com"]`).

> _9. shall not use refresh token rotation unless, in the case a response with a new refresh token is not received and stored by the client, retrying the request (with the previous refresh token) will succeed._

If the authorization server employs refresh token rotation (a mechanism where a new refresh token is issued with each access token refresh), it must be implemented with a fallback mechanism where, if a client fails to receive or store a new refresh token, it is able to refresh an access token with the previous refresh token.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--nzGTRCA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AMhycEutVmbcZpcXZCl-wYg.png)

> _10. if using DPoP, may use the server provided nonce mechanism (as defined in section 8 of [I-D.ietf-oauth-dpop])._

If [DPoP](dpop-rfc-9449-oauth-20-demonstrating-proof-of-possession) is used as a sender-constrained access token mechanism, the authorization server may employ DPoP nonce mechanism to prevent certain types of attacks like replay attacks where an attacker could steal a valid DPoP proof and reuse it to gain authorization.

> _11. shall issue authorization codes with a maximum lifetime of 60 seconds_

The lifetime of authorization codes must not exceed 60 seconds.

> _12. if using DPoP, shall support “Authorization Code Binding to DPoP Key” (as required by section 10.1 of [I-D.ietf-oauth-dpop])._

If the authorization server supports DPoP as an access token sender-constraining mechanism, it also needs to support “Authorization Code Binding to DPoP Key”. This mechanism allows clients to attach their proof of possession to authorization codes, ensuring end-to-end binding throughout the authorization process.

Note: This does not mean clients must use “Authorization Code Binding to DPoP Key”.

> _**NOTE**: In order to facilitate interoperability the authorization server should also accept its token endpoint URL or the URL of the endpoint at which the assertion was received in the  `aud`  claim received in client authentication assertions._

Technically, this means the authorization server SHOULD accept client assertions in which the `aud` claim is either a string matching the token endpoint’s URL or the URL where the assertion was received, or a string array containing these URLs.

The table below outlines the  `aud`  claim requirements for client assertions as specified in this note and clause 8.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--pjYavxan--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2ATJ7x4CVZIOxLEskMFuuMPg.png)

> _**NOTE**: Refresh token rotation is an optional feature defined in [RFC6749] section 6 where the Authorization Server issues a new refresh token to the client as part of the  `refresh_token`  grant._

This specification discourages the use of this feature as it doesn't bring any security benefits for confidential clients, and can cause significant operational issues. However to allow for operational agility, Authorization Servers may implement it providing they meet the requirement in clause 20.

FAPI 2.0 Security Profile does not recommend “refresh token rotation” as it’s considered unnecessary for confidential clients and potentially problematic operationally. However, authorization servers may implement it if they employ a fallback mechanism as  described in clause 9. (The note above refers to “clause 20” at the end but this is incorrect; it should be “clause 9".)

> _**NOTE**: Other grants as appropriate may be supported, for example the client credentials grant, the Client Initiated Backchannel Authentication grant, etc._

Authorization servers may support other grants (e.g. CIBA grant, etc), which are not included in the grants stated in clause 2.

**Requirements for Authorization Code Flow**

Next, we walk through authorization server requirements listed in “[5.3.1.2.](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.1.2) [Authorization Code Flow](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#name-authorization-code-flow)”.

> _1. shall support the authorization code grant (`response_type=code`  &  `grant_type=authorization_code`) described in [RFC6749]_

Authorization servers must support the authorization code grant as described in  [RFC 6749](https://www.rfc-editor.org/info/rfc6749).

> _2. shall support client-authenticated pushed authorization requests according to [RFC9126]_

Authorization servers must support “[RFC 9126, OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/info/rfc9126)” (PAR) and must authenticate clients at the pushed authorization request endpoint using one of the client authentication methods listed in clause 6.

For more details about PAR, refer to “[Illustrated PAR: OAuth 2.0 Pushed Authorization Requests](https://darutk.medium.com/illustrated-par-oauth-2-0-pushed-authorization-requests-652d71ed5cfb)”.

> _3. shall reject authorization requests sent without [RFC9126]_

Authorization servers must reject authorization requests if they are sent without using PAR.

> _4. shall reject pushed authorization requests without client authentication_

As stated in clause 2, authorization servers must authenticate clients at the PAR endpoint using one of the client authentication methods listed in clause 6.

> _5. shall require PKCE [[RFC7636](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#RFC7636)] with  `S256`  as the code challenge method_

Authorization servers must mandate  [RFC 7636, PKCE (Proof of Code Exchange)](https://www.rfc-editor.org/info/rfc7636)  to prevent the authorization code interception attack and require the  `code_challenge_method`  parameter to be set to  `S256`.

> _6. shall require the  `redirect_uri`  parameter in pushed authorization requests_

Authorization servers must require PAR requests to contain the  `redirect_uri`  parameter.

> _7. shall return an  `iss`  parameter in the authorization response according to [RFC9207]_

An authorization server must include its issuer identifier value as the  `iss`  parameter in the authorization response, according to  [RFC 9207](https://www.rfc-editor.org/info/rfc9207). This helps prevent mix-up attacks.

NOTE: The issuer identifier value must be a URL that uses the “https” scheme without any query or fragment components (e.g.  [https://as.example.com](https://as.example.com/.well-known/openid-configuration)).

> _8. shall not transmit authorization responses over unencrypted network connections, and, to this end, shall not allow redirect URIs that use the “http” scheme except for native clients that use Loopback Interface Redirection as described in [RFC8252], Section 7.3,_

If a redirect URI uses the “http” scheme, the client must be a native client, and the redirect URI must be a loopback redirect URI. Loopback redirect URIs are defined in  [Section 7.3 of RFC 8252](https://www.rfc-editor.org/rfc/rfc8252.html#section-7.3)  as follows.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--OaxmR33P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AaMbL36EDNKpsMJmRyvA46Q.png)

NOTE: The authorization server must allow any port to be specified at the time of the request for loopback IP redirect URIs, to accommodate clients that obtain an available ephemeral port from the operating system at the time of the request.

For more details, refer to “[Loopback Interface Redirection](https://darutk.medium.com/loopback-interface-redirection-53b7b0dbefcb)”.

> _9. shall reject an authorization code (section 1.3.1 of [RFC6749]) if it has been previously used_

If the authorization server detects that an authorization code has been used previously, it must reject the authorization request.

> _10. shall not use the HTTP 307 status code when redirecting a request that contains user credentials to avoid forwarding the credentials to a third party accidentally (see section 4.11 of [I-D.ietf-oauth-security-topics]);_

Unlike some other redirects, using HTTP 307 means that a POST request will be resent as POST to the new location, potentially exposing sensitive data to unintended parties if the redirection target isn’t trusted. For example, if a user submits a login form to  `https://example.com/login`  and the server responds with a 307 redirect to  `https://otherdomain.com/process`, the browser will resend the original login request, including credentials, to the new URL. This could inadvertently expose the user's credentials if  `otherdomain.com`  is not intended to receive them or is less secure.

> _11. should use the HTTP 303 status code when redirecting the user agent using status codes;_

HTTP 303 status code is particularly used after a POST or PUT request to direct the client to a new location that should be retrieved with a GET request, effectively preventing the original POST or PUT request from being resubmitted if the user refreshes the page. For example, after submitting a form to  `https://example.com/submit`, the server might respond with a 303 status code and a  `Location`  header pointing to  `https://example.com/thank-you`. The client's browser will then automatically issue a GET request to the  `thank-you`  page, ensuring that refreshing the page won't resubmit the form data.

> _12. shall issue pushed authorization requests  `request_uri`  with  `expires_in`  values of less than 600 seconds._

Request URIs issued by the PAR endpoint must have a lifetime that is smaller than 600 seconds to mitigate security risks including replay attacks.

> **NOTE**: If replay identification of the authorization code is not possible, it is desirable to set the validity period of the authorization code to one minute or a suitable short period of time. The validity period may act as a cache control indicator of when to clear the authorization code cache if one is used

If an authorization code cannot be protected against replay attacks, it’s recommended to limit its validity to one minute or another brief duration. This timeframe can also serve as a signal for when to purge the code from any cache in use.

> **NOTE**: The  `request_uri`  `expires_in`  time must be sufficient for the user's device to receive the link and the user to complete the process of opening the link. In many cases (poor network connection or where the user has to manually select the browser to be used) this can easily take over 30 seconds.

The request URI’s expiration time must be long enough to account for potential delays, such as slow network connections or manual browser selection by the user, which could extend beyond 30 seconds.

### Requirements for Clients

[“5.3.2.](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.2) [Requirements for Clients](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#name-requirements-for-clients)” lists requirements for clients.

**General Requirements**

In this section, we walk through general requirements for clients listed in “[5.3.2.1. General Requirements](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.2.1)”.

> _1. shall support sender-constrained access tokens using one of the following methods:_
> 
> _• MTLS as described in [RFC8705]_
> 
> _• DPoP as described in [I-D.ietf-oauth-dpop]_

Refer to the discussion for 5.3.1.1.5.

Below is an example of a token request using DPoP. Note that the  `DPoP` request header contains a DPoP proof JWT.

```
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkc...

grant_type=authorization_code\&client_id={CLIENT_ID}\&code={AUTHORIZATION_CODE}\&redirect_uri={REDIRECT_URI}\...
```

> _2. shall support client authentication using one of the following methods:_
> 
> _• MTLS as specified in section 2 of [RFC8705]_
> 
> _•  `private_key_jwt`  as specified in section 9 of [OIDC]_

Specifically, clients must support one of the following authentication methods.

-   `tls_client_auth`  (defined in  [section 2.1 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.1))
-   `self_signed_tls_client_auth`  (defined in  [section 2.2 of RFC 8705](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.%EF%BC%92))
-   `private_key_jwt`  (defined in  [section 9 of OIDC Core](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication))

> _3. shall send access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750]_

According to  [Section 2.1 of “RFC 6750, OAuth 2.0 Bearer Token Usage”](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1), clients must send an access token in the HTTP  `Authorization`  request header using the bearer token format as specified in  [RFC 6750](https://www.rfc-editor.org/info/rfc6750). Below is an example of a bearer token in the  `Authorization`  header.

`Authorization: Bearer {Access Token}`

> _4. shall not expose open redirectors (see section 4.10 of [I-D.ietf-oauth-security-topics])_

This refers to  [section 4.10 of OAuth 2.0 Security Best Current Practice](https://www.ietf.org/archive/id/draft-ietf-oauth-security-topics-21.html#section-4.10), which mandates that authorization servers and clients must not have open redirectors. An open redirector is a security vulnerability where a malicious actor can use a legitimate website to redirect users to a different, possibly malicious, site without their knowledge. This practice is often used in phishing attacks.

> _5. if using  `private_key_jwt`, shall use the Authorization Server's issuer identifier value (as defined in [RFC8414]) in the  `aud`  claim sent in client authentication assertions. The issuer identifier value shall be sent as a string not as an item in an array._

If the client uses `private_key_jwt` for client authentication, the  `aud`  claim value in client assertions must be set to the authorization server’s issuer identifier value as a string (e.g.  `"https://as.example.com"`), not as an array containing the issuer value.

> _6. shall support refresh tokens and their rotation_

Clients must support the refresh token flow (RFC 6749) and its rotation as described in 5.3.1.1.9.

> _7. if using MTLS client authentication or MTLS sender-constrained access tokens, shall support the mtls_endpoint_aliases metadata defined in [RFC8705]_

If MTLS client authentication or MTLS sender-constrained access tokens are used, the client must be capable of recognizing and utilizing endpoint aliases, which are defined in the  `mtls_endpoint_aliases`  metadata in the server metadata (found in the server’s “well-known” URL).

> _8. if using DPoP, shall support the server provided nonce mechanism (as defined in section 8 of [I-D.ietf-oauth-dpop])_

If the client uses DPoP] as the access token sender-constraining mechanism, it must support the DPoP nonce mechanism.

> _9. shall only use authorization server metadata (such as the authorization endpoint) retrieved from the metadata document as specified in [OIDD] and [RFC8414]_

Clients must only use authorization server metadata that is found in the authorization server’s “well-known” URI (e.g. `https://as.example.com/.well-known/openid-configuration`), which exposes server metadata as specified in [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html) and [RFC 8414](https://www.rfc-editor.org/info/rfc8414).

> _10. shall ensure that the issuer URL used as the basis for retrieving the authorization server metadata is obtained from an authoritative source and using a secure channel, such that it cannot be modified by an attacker_

The source of the authorization server’s issuer URL (e.g.  `https://as.example.com`) must be trustworthy and authoritative, ensuring it is the correct and intended URL for the authorization server. Additionally, the process of obtaining this URL should be conducted over a secure channel (like HTTPS) to prevent any possibility of modification or tampering by attackers.

> _11. shall ensure that this issuer URL and the  `issuer`  value in the obtained metadata match_

Clients must ensure the authorization server’s issuer URL matches the issuer value in server metadata provided by the authorization server’s “well-known” URI.

> _**NOTE**:This profile may be used by Confidential Clients on a user-controlled device where the system clock may not be accurate, this may cause  `private_key_jwt` client authentication to fail. In such circumstances a Client should consider using the HTTP Date header returned from the server to synchronise it's own clock when generating client assertions._

The note indicates that confidential clients on user-controlled devices might encounter issues with  `private_key_jwt` client authentication due to potential inaccuracies in the system clock. To address this, it's recommended that clients use the HTTP  `Date`  header, which is returned from the server, as a reference to synchronize their own clock. This synchronization is important for generating values such as the  `exp`  claim value in client assertions.

> _**NOTE**:Although Authorization Servers are required to support “Authorization Code Binding to DPoP Key” (as defined by section 10.1 of [I-D.ietf-oauth-dpop]), clients are not required to use it._

As stated in 5.3.1.1.12, authorization servers are required to support “Authorization Code Binding to DPoP Key” if using  DPoP for an access token sender-constraining mechanism but it doesn’t mean clients must use it.

**Requirements for Authorization Code Flow**

In this section, we walk through client requirements listed in “[5.3.2.2. Authorization Code Flow](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.2.2)”.

> _1. shall use the authorization code grant described in [RFC6749]_

Clients must use the authorization code grant (`response_type=code`  &  `grant_type=authorization_code`) as specified in [RFC 6749](https://www.rfc-editor.org/info/rfc6749).

> _2. shall use pushed authorization requests according to [RFC9126]_

Clients must use PAR ([RFC 9126, Pushed Authorization Requests](https://www.rfc-editor.org/info/rfc9126)).

For more details about PAR, refer to “[Illustrated PAR: OAuth 2.0 Pushed Authorization Requests](https://darutk.medium.com/illustrated-par-oauth-2-0-pushed-authorization-requests-652d71ed5cfb)”.

> _3. shall use PKCE [RFC7636] with  `S256`  as the code challenge method_

Clients must use PKCE ([RFC 7636](https://www.rfc-editor.org/info/rfc7636)) to prevent the authorization code interception attack and set the  `code_challenge_method`  parameter to  `S256`.

> _4. shall check the  `iss`  parameter in the authorization response according to [RFC9207] to prevent Mix-Up attacks_

Mix-up attacks are a security threat, where a client is tricked into sending sensitive information like authorization codes or access tokens to a malicious authorization server, instead of the intended legitimate one. These attacks exploit scenarios where a client interacts with multiple authorization servers, and at least one is controlled by an attacker. The attacker’s goal is to intercept the credentials to gain unauthorized access to protected resources. [Section 4.4.1 of OAuth 2.0 Security Best Current Practice](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-25#section-4.4.1)  also describes how the attack is executed specifically, which is illustrated in the diagram below.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--VeNULorf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:2000/1%2AqKsL848WmGuXOFcKehpsXA.png)

To prevent mix-up attacks, clients must check that the authorization response contains the  `iss`  parameter and it matches the issuer URL of the authorization server according to [RFC 9207](https://www.rfc-editor.org/info/rfc9207).

### Requirements for Resource Servers

“[5.3.3. Requirements for Resource servers](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.3.3)” lists requirements for resource servers. Let’s walk through them.

> _1. shall accept access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750]_

Resource servers must accept access tokens contained in the HTTP  `Authorization`  request header using the bearer token format as specified in  [RFC 6750](https://www.rfc-editor.org/info/rfc6750). Below is an example of a bearer token in the  `Authorization`  header.

`Authorization: Bearer {Access Token}`

> _2. shall not accept access tokens in the query parameters stated in Section 2.3 of OAuth 2.0 Bearer Token Usage [RFC6750]_

While  [section 2.3 of RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750#section-2.3)  describes how to include access tokens in the query parameter, resource servers must reject such requests for security reasons.

> _3. shall verify the validity, integrity, expiration and revocation status of access tokens_

This means resource servers must check the following things regarding access tokens:

-   **Validity**: Confirming the token is authentic and issued by the authorization server.
-   **Integrity**: Ensuring the token hasn’t been tampered with or altered during transit.
-   **Expiration**: Checking the token hasn’t expired.
-   **Revocation Status**: Verifying whether the token has been revoked or invalidated before its expiration.

> _4. shall verify that the authorization represented by the access token is sufficient for the requested resource access and otherwise return errors as in section 3.1 of [RFC6750]_

Resource servers must verify that the access token covers the required scopes for the requested resource access. If the token is insufficient, they must return errors as specified in  [section 3.1 of RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1).

> _5. shall support and verify sender-constrained access tokens using one of the following methods:_
> 
> _• MTLS as described in [RFC8705]_
> 
> _• DPoP as described in [I-D.ietf-oauth-dpop]_

Refer to the discussion for 5.3.1.1.5.

### Cryptography and Secrets

“[5.4. Cryptography and Secrets](https://openid.bitbucket.io/fapi/fapi-2_0-security-profile.html#section-5.4)” lists requirements for cryptographic operations and secrets.

> _1. Authorization Servers, Clients, and Resource Servers when creating or processing JWTs shall_
> 
> _1. adhere to [RFC8725];_

This document,  [RFC 8725](https://www.rfc-editor.org/rfc/rfc8725.html), outlines the best current practices for implementing JSON Web Tokens (JWTs) to ensure secure deployment, including the following requirements and conditions:

-   **Algorithm Verification**: Libraries must allow specification of supported algorithms and not use others for cryptographic operations.
-   **Use of Appropriate Algorithms**: Applications must only use secure, current algorithms that meet their security needs and are designed for cryptographic agility.
-   **Validation of Cryptographic Operations**: All operations within a JWT must be validated; the JWT must be rejected if any fail.
-   **Validation of Cryptographic Inputs**: Inputs for operations, like those in elliptic curve key agreement, must be validated.
-   **Key Entropy**: Keys must have sufficient entropy, particularly to avoid weak symmetric keys.
-   **Use of UTF-8 Encoding**: Adhere to the JSON specifications and use UTF-8 for encoding and decoding.
-   **Issuer and Subject Validation**: The application must validate the issuer and subject, rejecting the JWT if they don’t match the expected values.
-   **Audience Validation**: The application must validate the intended audience of the JWT and reject it if it does not match.
-   **Avoidance of Compression Before Encryption**: To prevent information leakage, compression of data before encryption should be avoided.
-   **Care with Received Claims**: Applications should protect against vulnerabilities from received claims like  `kid`  or URLs in headers.
-   **Explicit Typing of JWTs**: Using the  `typ`  header parameter is recommended to prevent confusion between different kinds of JWTs.
-   **Mutually Exclusive Validation Rules**: Different kinds of JWTs from the same issuer should have mutually exclusive validation rules to prevent substitution attacks.

> _2. use  `PS256`,  `ES256`, or  `EdDSA`  (using the  `Ed25519`  subtype) algorithms; and_

This mandates using secure, modern digital signature algorithms —  `PS256`,  `ES256`, or  `EdDSA`  with  `Ed25519`  curve — for creating verifiable digital signatures in JWTs such as client assertions.

> _3. not use or accept the  `none`  algorithm._

The  `none`  algorithm is not allowed.

> _2. RSA keys shall have a minimum length of 2048 bits._
> 
> _3. Elliptic curve keys shall have a minimum length of 160 bits._

-   RSA keys must be at least 2048 bits long.
-   EC Keys must be at least 160 bits long.

> _4. Credentials not intended for handling by End-Users (e.g., access tokens, refresh tokens, authorization codes, etc.) shall be created with at least 128 bits of entropy such that an attacker correctly guessing the value is computationally infeasible. Cf. Section 10.10 of [RFC6749]._

This requirement specifies that security credentials not directly handled by end-users, such as access tokens and authorization codes, must be generated with a minimum of 128 bits of entropy. This level of entropy ensures that guessing these values is computationally impossible, providing a strong level of security against unauthorized access or attacks.

### MTLS Protection of all endpoints

“[5.5. MTLS Protection of all endpoints](https://openid.bitbucket.io/fapi/fapi-2_0-security-profile.html#section-5.5)” outlines the recommended approach for enhancing interoperability across certain endpoints utilizing TLS.

> _Some ecosystems are choosing to require clients accessing their endpoints to supply a TLS client certificate at endpoints that would not otherwise require a TLS client certificate (for example, the PAR endpoint when using private_key_jwt authentication)._
> 
> _This is outside of the scope of both [RFC8705] and the FAPI standards, however in the interests of interoperability this document states that when using TLS as a transport level protection in this manner, authorization servers should expect clients to call the endpoints located in the root of the server metadata, and not those found in mtls_endpoint_aliases._

Some ecosystems opt to require a TLS client certificate for accessing certain endpoints, even if those endpoints wouldn’t need one in some contexts (e.g. The PAR endpoint when using  `private_key_jwt`  authentication). This practice isn’t covered by  [RFC 8705](https://www.rfc-editor.org/info/rfc8705)  or FAPI standards. However, for better interoperability, it’s recommended that when TLS is used in this way, the authorization servers should require clients to use endpoints defined at the root level of their server metadata (found in the server’s “well-known” URL), rather than endpoints specified in  `mtls_endpoint_aliases`.

Below is an example of authorization server’s metadata containing  `mtls_endpoint_aliases`  .  

```
{  
  "issuer": "https://as.example.com",
  "authorization_endpoint": "https://as.example.com/authz",
  "token_endpoint": "https://as.example.com/token",
  "introspection_endpoint": "https://as.example.com/introspect",
  "revocation_endpoint": "https://as.example.com/revo",
  "jwks_uri": "https://as.example.com/jwks",
  "token_endpoint_auth_methods_supported": ["tls_client_auth","client_secret_basic"],
  "tls_client_certificate_bound_access_tokens": true,  
  ...  
  "mtls_endpoint_aliases": {    
    "token_endpoint": "https://mtls.example.com/token",
    "revocation_endpoint": "https://mtls.example.com/revo",     
    "introspection_endpoint": "https://mtls.example.com/introspect" 
  }
}
```

### Main Differences to FAPI 1.0

“[5.5. Main Differences to FAPI 1.0](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-5.5)” outlines key differences between FAPI 1.0 Read/Write (Advanced profile) and FAPI 2.0, highlighting the evolution towards enhanced security, privacy, and interoperability. For more details about FAPI 1.0, refer to “[Financial-grade API (FAPI), explained by an implementer](https://darutk.medium.com/financial-grade-api-fapi-explained-by-an-implementer-d09fcf2ff932)”.

### Security Consideration

“[5.7.](https://openid.bitbucket.io/fapi/fapi-2_0-security-profile.html#section-5.7) [Security Considerations](https://openid.bitbucket.io/fapi/fapi-2_0-security-profile.html#name-security-considerations)” outlines several security risks and their mitigations. The summary is as follows:

**5.7.1. Access Token Lifetimes**  
  
Risks involve longer-lived tokens leading to increased vulnerability windows. Mitigations include using short-lived tokens and refresh tokens for key rotation.

**5.7.2. DPoP Proof Replay**  Risks involve attackers replaying DPoP proofs. Mitigations include using short-lived DPoP nonces and implementing replay prevention techniques.

**5.7.3. JWKS URIs**  Risks involve potential vulnerabilities in key management for OAuth and OpenID Connect protocols. Mitigations include using JWKS URI for distributing public keys and TLS for securing  `jwks_uri`  endpoints. Additionally, this profile mandates TLS for  `jwks_uri`  endpoints and recommends not using JOSE headers  `x5u`  and  `jku`, and avoiding multiple keys with the same  `kid`  in a JWK set.

**5.7.4. Duplicate Key Identifiers**  
  
Risks involve confusion or errors when multiple keys share the same identifier (kid). Mitigations include carefully managing JWK sets to avoid duplicate kids and, if duplicates exist, using additional key attributes for selecting the correct key for verification.

**5.7.5. Injection of Stolen Access Tokens**  Risks involve attackers injecting stolen tokens. Mitigations focus on using different DPoP keys or MTLS certificates and verifying issuer identifiers.

**5.7.6. Authorization Request Leaks**  
  
Risks involve CSRF attacks using compromised authorization requests. Mitigations include one-time use of request URIs and limiting authorization code grant calls.

**5.7.7. Browser-Swapping Attacks**  
  
Risks involve attackers swapping browsers to intercept authorization responses. Mitigations emphasize keeping authorization responses confidential and secure handling of redirect URIs.

### Privacy Considerations

“[6. Privacy considerations](https://openid.net/specs/fapi-2_0-security-profile-ID2.html#section-6)” emphasizes the importance of addressing privacy risks, including:

-   Ensuring appropriate privacy notices and consent mechanisms.
-   Preventing data misuse and adhering to data minimization principles.
-   Avoiding unsolicited personal data transmission from resource servers.
-   Reducing tracking of end-users by authorization servers and clients.
-   Clarifying client identity and data access permissions to end-users.
-   Minimizing personal data in authorization requests/responses.
-   Securing personal data against leaks from authorization servers, resource servers, and clients.

Implementers are encouraged to consult standards like ISO 29100 and ISO 29134 for privacy impact assessments.

## Finally

Thank you for engaging with the detailed article. Stay tuned for subsequent information about FAPI 2.0.

![](https://res.cloudinary.com/practicaldev/image/fetch/s--ph-mCUn0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:1400/1%2AtMFkcmvj_U8ThXlKjJDr7w.png)

In closing,  [Authlete, Inc.](https://www.authlete.com/), a company I co-founded, proudly supports  **both FAPI 1.0 and FAPI 2.0**, recognized by  [FAPI OpenID Provider Certification Program](https://openid.net/certification/).

Please feel free to reach out to us through the  [web form](https://www.authlete.com/contact/)  or via email for any inquiries:

-   **For Licensing and Contracts**:  [sales@authlete.com](mailto:sales@authlete.com)
-   **For Partnership Opportunities**:  [bizdev@authlete.com](mailto:bizdev@authlete.com)
-   **For Technical Support**:  [support@authlete.com](mailto:support@authlete.com)

We welcome any inquiries about our solution or potential collaboration/partnership opportunities. Also, please follow our social channels:

-   [GitHub](https://github.com/authlete)
-   [Facebook](https://www.facebook.com/authlete)
-   [X (Twitter)](https://twitter.com/authlete)
-   [Linkedin](https://www.linkedin.com/company/authlete)
-   [YouTube](https://www.youtube.com/channel/UCERMcUO2vR7F96Qd-BZbiwA)

## [](https://dev.to/new#updates)Updates

April 10, 2024: This document was initially published, exclusively focusing on FAPI 2.0 Security Profile (ID2).