Exploring FAPI 2.0: The Latest in API Security Technology
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
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
FAPI 1.0 Final Version
- Financial-grade API Security Profile 1.0 — Part 1: Baseline (March, 2021)
- Financial-grade API Security Profile 1.0 — Part 2: Advanced (March, 2021)
For a deeper understanding of FAPI 1.0, “Financial-grade API (FAPI), explained by an implementer” is very helpful.
FAPI 2.0 Implementer’s Draft 1
- FAPI 2.0 Baseline Profile (July, 2021)
- FAPI 2.0 Attacker Model (July, 2021)
- Grant Management for OAuth 2.0 (July, 2021)
- FAPI 2.0 Message Signing Profile (March, 2023)
Note: “Advanced Profile” was renamed to “Message Signing Profile”.
FAPI 2.0 Implementer’s Draft 2
- FAPI 2.0 Security Profile (December, 2022)
- FAPI 2.0 Attacker Model (December, 2022)
Note: “Baseline Profile” was renamed to “Security Profile”.
FAPI 2.0 Final
- FAPI 2.0 Security Profile (Feburary, 2025)
- FAPI 2.0 Attacker Model (Feburary, 2025)
Certification Program
As of April 2025, The OpenID Certification offers the following FAPI 2.0 certification programs for both providers and relying parties.
For Providers:
- FAPI 2.0 Security Profile Second Implementer’s Draft & Message Signing First Implementer’s Draft
- Australia FAPI 2.0 ConnectID Implementer’s Draft
- CBUAE FAPI 2.0 Message Signing
For Relying Parties:
Basics
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 — OAuth 2.0 Authorization Framework
- RFC 6750 — OAuth 2.0 Authorization Framework: Bearer Token Usage
- RFC 7636 — Proof Key for Code Exchange by OAuth Public Clients (PKCE)
- RFC 8705 — OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (MTLS)
- RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- RFC 9126 — OAuth 2.0 Pushed Authorization Requests (PAR)
- RFC 8414 — OAuth 2.0 Authorization Server Metadata
- RFC 9207 — OAuth 2.0 Authorization Server Issuer Identification
- OpenID Connect Core 1.0
Articles below may help understand some of these specifications.
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 defines two client authentication methods utilizing MTLS.
tls_client_authIn 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_authIn 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.
If you are interested in the mechanism of X.509 certificates, refer to “Illustrated X.509 Certificate”.
Client Authentication using Private Key Signed JWT
This authentication method refers to the following method listed in Section 9 of OIDC Core.
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.
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) 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 defines a sender-constraning mechanism for access tokens utilizing MTLS. Here’s how it works.
- A client requests an access token (to the token endpoint).
- The authorization server obtains a client certificate during the process of establishing MTLS connection with the client.
- The authorization server binds the client certificate to the access token when issuing an access token.
- The client sends a request to the resource server with the access token and the client certificate.
- The resource server ensures the access token is bound to the client certificate.
DPoP (RFC 9449: OAuth 2.0 Demonstrating Proof of Possession)
DPoP (RFC 9449: OAuth 2.0 Demonstrating Proof of Possession) is another access token sender-constraining mechanism allowed in FAPI 2.0 Security Profile. Here’s how it works.
- The client creates a DPoP proof JWT, which is a signed JWT, using a private key possessed by the client.
- The client sends a token request including the DPoP proof JWT.
- Upon receiving the request, the authorization server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
- Then the authorization server binds the thumbprint of the public key to the issued access token.
- The authorization server issues the access token.
- Before accessing resources, the client creates a new DPoP proof JWT using the same private key.
- The client sends a request to the resource server with the access token and the DPoP proof JWT.
- Upon receiving the request, the resource server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
- 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)”.
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 a public key possessed by the client. This mechanism can enable end-to-end binding of the entire authorization flow. Here’s how it works.
- The client computes a thumbprint of the public key.
- The client sends an authorization request including the thumbprint as the
dpop_jktparameter. - The authorization server binds the
dpop_jktvalue with the authorization code. - The authorization server issues the authorization code.
- The client creates a DPoP proof JWT, which is a signed JWT, using the corresponding private key.
- The client sends a token request including the DPoP proof JWT.
- Upon receiving the request, the authorization server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
- Then, the authorization server ensures the authorization code is bound to the thumbprint of the public key in the DPoP proof JWT.
- Then, the authorization server binds the public key to the issued access token.
- The authorization server issues the access token.
- Before accessing resources, the client creates a new DPoP proof JWT using the same private key.
- The client sends a request to the resource server with the access token and the DPoP proof JWT.
- Upon receiving the request, the resource server verifies the signature of the DPoP proof JWT, using the public key contained in the proof.
- 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.
DPoP Nonce
DPoP nonce is a mitigation to prevent DPoP proof pre-generation attack.
Without DPoP nonce, a pre-generation attack could be executed as follows:
An attacker is a bank employee who has access to a computer at work (a legitimate client application).
- The attacker creates a DPoP proof on the computer at work for later use.
- The attacker sends the DPoP proof to their personal computer at home.
- Some time later, the attacker sends a token request (from home) including the stolen DPoP proof.
- The authorization server checks the DPoP proof contained in the token request. Because the proof is correctly signed by the private key possessed by the client, it passes the verification.
- The authorization server binds the thumbprint of the public key contained in the DPoP proof to the issued access token.
- The authorization server issues the new access token to the attacker.
With DPoP nonce, the attack can be mitigated by its limited lifetime as follows:
- The authorization server provides a DPoP nonce, ”nonce-1”, which has a short lifetime (e.g., 10 minutes).
- The attacker generates a DPoP proof JWT that contains “nonce-1” and is signed by the client’s private key.
- The attacker copies the DPoP proof to their computer at home for later use.
- Some time later, the attacker sends a token request including the DPoP proof JWT to the authorization server.
- The authorization server verifies the proof’s signature. Because the proof is correctly signed by the private key possessed by the client, it passes the verification.
- The authorization server validates the nonce in the proof (“nonce-1”). This results in an error because “nonce-1” has already expired.
Security Profile
In the following sections, we’ll go through each part of FAPI 2 Security Profile (Final) in detail.
5.1. Overview
5.1.1. Introduction
FAPI 2.0 Security Profile is a security profile built on OAuth 2.0 (RFC 6749), aiming to meet the security goals in the Attacker Model and follow OAuth Security BCP (RFC9700) recommendations. It excludes public clients from its scope, as no mechanism is currently known to secure them to the same degree. While it is possible to implement from scratch, implementers are encouraged to build on top of existing OpenID Connect or OAuth 2.0 implementations for completeness and correctness.
5.1.2. Profiling this document
This document defines a general-purpose, high-security OAuth 2.0 profile that has been formally proven to meet the attacker model. While it allows some flexibility for implementers and ecosystems, making choices based on specific use cases can further improve security or interoperability. However, mandatory behaviors must not be removed or overridden, as this would undermine the formal security guarantees.
5.2. Network Layer Protections
5.2.1. Requirements for all endpoints
To protect against network attacks, clients, authorization servers, and resource servers must:
- use only TLS-protected endpoints and establish all connections via TLS.
- use TLS version 1.2 or later.
- follow the secure usage recommendations in BCP195.
- consider using DNSSEC to prevent DNS spoofing and rogue certificate issuance.
- perform TLS server certificate validation as specified in RFC9525.
Note: Using OV or EV TLS certificates alone does not prevent man-in-the-middle attacks, as attackers can still exploit rogue domain-validated (DV) certificates. CAA records (RFC8659) help mitigate this risk.
5.2.2. Requirements for endpoints not used by web browsers
For communication between servers (i.e. endpoints not accessed by web browsers):
- Servers using TLS 1.2 must only allow the cipher suites recommended in BCP195.
- Clients using TLS 1.2 should also limit cipher suites to those recommended in BCP195.
5.2.2.1. MTLS ecosystems
Some ecosystems use Mutual TLS (MTLS) as an added transport-layer security measure for server-to-server communication involving sensitive data. For interoperability:
- MTLS ecosystems should provide a list of trusted certificate authorities.
- Authorization servers may use
mtls_endpoint_aliasesmetadata (per RFC8705) to help clients discover both MTLS and non-MTLS endpoints. - Clients must use
use_mtls_endpoint_aliasesmetadata, if provided, to determine how to communicate with endpoints.
5.2.2.1.1. Client Metadata
Dynamic Client Registration Protocol (RFC7591) defines how OAuth 2.0 clients register metadata with authorization servers. Even without dynamic registration, the metadata model can support client configuration via a user interface.
This specification adds a new optional client metadata field:
use_mtls_endpoint_aliasesA boolean flag indicating whether the client must use MTLS endpoint aliases defined by the authorization server (per RFC8705), including cases beyond MTLS client authentication and certificate-bound tokens. The default value is false.
5.2.3. Requirements for endpoints used by web browsers
For endpoints accessed by web browsers, the following additional security requirements apply:
- Servers must prevent TLS downgrade attacks. A preloaded HTTP Strict Transport Security (HSTS) policy (RFC6797) can be used. Some top-level domains, like
.bankand.insurance, enforce this by default. - When using TLS 1.2, servers must use only the cipher suites allowed in BCP195.
- Servers must not support Cross-Origin Resource Sharing (CORS) as defined in CORS.Protocol on the authorization endpoint, since clients must use HTTP redirects rather than direct access.
NOTE 1: For TLS 1.2, browser-based endpoints may use any cipher suite allowed in BCP195, while non-browser endpoints may only use the recommended ones.
NOTE 2: Implementers are expected to comply with new versions of BCP195 within 12 months of publication.
5.3. Profile
5.3.1. General
This profile is related to the following specifications.
- RFC6749: OAuth 2.0 Authorization Framework
- RFC6750: OAuth 2.0 Bearer Tokens
- RFC7636: Proof Key for Code Exchange by OAuth Public Clients (PKCE)
- RFC8705: OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (MTLS)
- RFC9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- RFC9126: OAuth 2.0 Pushed Authorization Requests (PAR)
- RFC8414: OAuth 2.0 Authorization Server Metadata
- RFC9207: OAuth 2.0 Authorization Server Issuer Identification
- OpenID Connect Core 1.0 incorporating errata set 1
5.3.2. Requirements for authorization servers
5.3.2.1. General requirements
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 and RFC 8414.
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;
This profile prohibits the use of the Resource Owner Password Credentials Grant. On the other hand, the following grant types are not prohibited:
authorization_coderefresh_tokenclient_credentialsurn:openid:params:grant-type:ciba
3. shall only support confidential clients as defined in [RFC6749]
Authorization servers must support only confidential clients as defined in RFC6749.
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 [RFC9449];
This requires authorization servers to support MTLS (RFC 8705) or DPoP (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], or
•private_key_jwtas specified in Section 9 of [OIDC];
Specifically, the authentication methods allowed in this profile are as follows.
tls_client_auth(defined in Section 2.1 of RFC8705)self_signed_tls_client_auth(defined in Section 2.2 of RFC8705)private_key_jwt(defined in Section 9 of OIDC Core)
The table below shows client authentication methods allowed in FAPI 1.0 and FAPI 2.0 Security Profile.
See this for more details about these authentication methods.
7. shall not expose open redirectors (see Section 4.11 of [I-D.ietf-oauth-security-topics]);
This refers to Section 4.11 of OAuth 2.0 Security Best Current Practice, 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 only accept its issuer identifier value (as defined in [RFC8414]) as a string in the
audclaim received in client authentication assertions;
When the authorization server authenticates clients using private_key_jwt, it must accept its own issuer identifier as the value of the aud claim in the client assertion. In this case, the aud claim in the client assertion must be a string that exactly matches the authorization server’s issuer identifier (e.g., “https://as.example.com”).
Note: String arrays containing the issuer identifier (e.g., [“https://as.example.com”]) are not allowed.
✅ aud = "https://as.example.com"❌ aud = ["https://as.example.com"]9. shall not use refresh token rotation except in extraordinary circumstances (see Note 1 below);
Authorization servers must prohibit refresh token rotation (a mechanism where a new refresh token is issued each time an access token is refreshed), except in exceptional circumstances. See NOTE 1 for details.
10. if using DPoP, may use the server provided nonce mechanism (as defined in section 8 of [I-D.ietf-oauth-dpop]).
When DPoP is used as a sender-constraining access token mechanism, the authorization server can adopt the DPoP nonce mechanism to prevent attacks such as replay attacks (where an attacker steals a valid DPoP proof and reuses 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 [RFC9449]);
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”.
13. to accommodate clock offsets, shall accept JWTs with an iat or nbf timestamp between 0 and 10 seconds in the future but shall reject JWTs with an
iatornbftimestamp greater than 60 seconds in the future. See Note 3 for further details and rationale;
To accommodate clock skew, the authorization server must accept JWTs with iat or nbf claim values up to 10 seconds in the future. However, if the iat or nbf value is more than 60 seconds ahead of the current time, the JWT must be rejected.
14. should restrict the privileges associated with an access token to the minimum required for the particular application or use case.
As stated, unnecessary privileges should not be granted beyond what is required for the particular application or use case.
NOTE 1: The use of refresh token rotation does not provide security benefits when used with confidential clients and sender-constrained access tokens. This specification prohibits the use of refresh token rotation for security reasons as it causes user experience degradation and operational issues whenever the client fails to store or receive the new refresh token and has no option to retry.
However, as refresh token rotation may be required from time to time for infrastructure migration or similar extraordinary circumstances, this specification allows it, provided that authorization servers offer clients the time-limited option to retry with the old refresh token in case of failure. Implementers need to consider a secure mechanism for clients to recover from a loss of a new refresh token on issue. The details of this mechanism are outside the scope of this specification.
Refresh token rotation is prohibited except in exceptional circumstances. If refresh token rotation is implemented, a mechanism must be provided to allow the use of the old refresh token for a limited time period, as shown below.
NOTE 2: This document is structured to support a variety of grants to be used with the general requirements above. For example the client credentials grant or the CIBA grant [CIBA]. Implementers should note that as of the time of writing only the authorization code flow and CIBA flows have been through a detailed security analysis [FAPI2SEC].
The authorization server may support grant types that are not prohibited in the second requirement, such as the client credential grant and the CIBA grant.
NOTE 3: Clock skew is a cause of many interoperability issues. Even a few hundred milliseconds of clock skew can cause JWTs to be rejected for being “issued in the future”. The DPoP specification [RFC9449] suggests that JWTs are accepted in the reasonably near future (on the order of seconds or minutes). This document goes further by requiring authorization servers to accept JWTs that have timestamps up to 10 seconds in the future. 10 seconds was chosen as a value that does not affect security while greatly increasing interoperability. Implementers are free to accept JWTs with a timestamp of up to 60 seconds in the future. Some ecosystems have found that the value of 30 seconds is needed to fully eliminate clock skew issues. To prevent implementations switching off iat and nbf checks completely this document imposes a maximum timestamp in the future of 60 seconds.
As stated in the 13th requirement, the maximum acceptable value for iat and nbf in a JWT is “current time + 60 seconds”. If a greater value is set, the JWT must be rejected.
5.3.2.2. Authorization endpoint flows
1. shall require the value of response_type described in [RFC6749] to be code;
The authorization server must require response_type=code. Other response types are not allowed.
2. shall support client-authenticated pushed authorization requests according to [RFC9126];
Authorization servers must support “RFC 9126, OAuth 2.0 Pushed Authorization Requests (PAR)” and must authenticate clients at the pushed authorization request endpoint using one of the client authentication methods listed in 5.3.2.1.6.
For more details about PAR, refer to “Illustrated PAR: OAuth 2.0 Pushed Authorization Requests”.
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 the second requirement, authorization servers must authenticate clients at the PAR endpoint using one of the client authentication methods listed in 5.3.2.1.6.
5. shall require PKCE [RFC7636] with
S256as the code challenge method;
Authorization servers must mandate RFC 7636, PKCE (Proof Key of Code Exchange) to prevent the authorization code interception attack and require the code_challenge_method parameter to be set to S256.
6. shall require the
redirect_uriparameter in pushed authorization requests;
Authorization servers must require PAR requests to contain the redirect_uri parameter.
7. shall return an
issparameter 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. This helps prevent mix-up attacks. See this for more details.
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).
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 Section 7.3 of [RFC8252];
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 RFC8252 as follows.
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”.
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.12 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_uriwithexpires_invalues 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.
13. should provide end-users with all necessary information to make an informed decision about whether to consent to the authorization request, including the identity of the client and the scope of the authorization;
As stated.
14. if supporting [OIDC], shall support nonce parameter values up to 64 characters in length, may reject nonce values longer than 64 characters.
As mentioned earlier, nonce is effective as a countermeasure against replay attacks. In this profile, authorization servers must support nonce values up to 64 characters. Whether to reject nonce values longer than 64 characters depends on the authorization server’s implementation.
NOTE 1: 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 2: The
request_uriexpires_intime 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.
NOTE 3: It is recommended that authorization servers that enforce one-time use of
request_urivalues ensure the enforcement takes place at the point of authorization, not at the point of loading an authorization page. This prevents user software that preloads urls from invalidating therequest_uri.
As stated in RFC9126, a request URI should be invalidated after it has been used. The question is: at what point should this invalidation occur? The conclusion is that it should happen when the user completes the authorization. Another possible timing would be when the authorization page is loaded, but this approach has a drawback: if the user’s software (e.g., a browser) preloads the authorization page, the request URI may be invalidated prematurely, resulting in an error when the user actually loads the page.
NOTE 4: In this document the
stateparameter is not used for CSRF protection, but may be used to by the client for application state. In circumstances where clients encode application state in a JWT the length of the `state` parameter value could be in excess of 1000 characters.
This specification does not require the use of the state parameter as a countermeasure against CSRF attacks. This is because PKCE (RFC7636) is mandatory in this specification, and it also provides protection against CSRF attacks.
NOTE 5: The use of OAuth 2.0 Rich Authorization Requests (RAR) [RFC9396] is recommended when the
scopeparameter is not expressive enough to convey the authorization that a client may want to obtain.
It is not easy to express an authorization request such as “I want to access bank account 1234 to make a payment of up to $500” using only a scope like payments. In such cases, the authorization_details parameter defined in RAR (RFC9396) can be used to express the request as shown below:
"authorization_details": [
{
"type": "payment_initiation",
"debtorAccount": {
"accountNumber": "1234"
},
"instructedAmount": {
"currency": "USD",
"amount": "500.00"
},
"creditorName": "Merchant A",
"creditorAccount": {
"iban": "DE02100100109307118603"
}
}
]5.3.3. Requirements for Clients
5.3.3.1. General Requirements
1. shall support sender-constrained access tokens using one or both of the following methods:
•MTLS as described in [RFC8705],
•DPoP as described in [RFC9449];
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 or both 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 RFC8705)self_signed_tls_client_auth(defined in Section 2.2 of RFC8705)private_key_jwt(defined in Section 9 of OIDC Core)
3. shall send access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750] or Section 7.1 of DPoP [RFC9449];
Below are examples of how to send access tokens the Bearer and DPoP methods.
Get hidebike712’s stories in your inbox
Join Medium for free to get updates from this writer.
Bearer Access Token (RFC6750)
Authorization: Bearer {Access Token}DPoP Access Token (RFC9449)
Authorization: DPoP {Access Token}
DPoP: {DPoP Proof JWT}4. shall not expose open redirectors (see Section 4.11 of [I-D.ietf-oauth-security-topics]);
This refers to Section 4.11 of OAuth 2.0 Security Best Current Practice, 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 theaudclaim 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 (RFC6749) and its rotation as described in 5.3.1.2.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” URI.
8. if using DPoP, shall support the server provided nonce mechanism (as defined in Section 8 of [RFC9449]);
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, which exposes server metadata as specified in OpenID Connect Discovery 1.0 incorporating errata set 1 and RFC 8414.
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.
12. shall initiate an authorization process only with the end-user’s explicit or implicit consent and protect initiation of an authorization process against cross-site request forgery, thereby enabling the end-user to be aware of the context in which a flow was started;
13. should request authorization with the least privileges necessary for the specific application or use case.
As stated.
NOTE 1: This profile may be used by confidential clients on a user-controlled device where the system clock may not be accurate, causing
private_key_jwtclient authentication to fail. In such circumstances a client should consider using the HTTP date header returned from the server to synchronize its own clock when generating client assertions.
Some confidential clients may operate on user-controlled devices. In such cases, inaccurate system time may cause client authentication using private_key_jwt to fail. To address this, it is recommended that the client refer to the HTTP Date header returned by the server to synchronize its own time. This is especially important when generating values such as the exp claim in client assertions.
NOTE 2: Although authorization servers are required to support “Authorization Code Binding to DPoP Key” (as defined by Section 10.1 of [RFC9449]), clients are not required to use it.
As stated in 5.3.2.1.12, when an authorization server uses DPoP as a sender-constraining mechanism for access tokens, it is required to support “Authorization Code Binding to DPoP Key”. However, this does not mean that the client is required to use “Authorization Code Binding to DPoP Key”.
5.3.3.2. Requirements for Authorization Code Flow
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.
2. shall use pushed authorization requests according to [RFC9126];
Clients must use PAR (RFC9126, Pushed Authorization Requests).
For more details about PAR, refer to “Illustrated PAR: OAuth 2.0 Pushed Authorization Requests”.
3. shall use PKCE [RFC7636] with
S256as the code challenge method;
Clients must use PKCE (RFC7636) to prevent the authorization code interception attack and set the code_challenge_method parameter to S256.
4. shall generate the PKCE challenge specifically for each authorization request and securely bind the challenge to the client and the user agent in which the flow was started;
The PKCE challenge value must be freshly generated for each authorization request.
5. shall check the
issparameter 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 also describes how the attack is executed specifically, which is illustrated in the diagram below.
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 RFC9207.
6. shall only send
client_idandrequest_urirequest parameters to the authorization endpoint (all other authorization request parameters are sent in the pushed authorization request according to [RFC9126]);
When sending an authorization request to the authorization endpoint, only client_id and request_uri are allowed to be included.
7. if using [OIDC], should not use nonce parameter values longer than 64 characters.
When using OIDC, the length of the nonce parameter should be no more than 64 characters.
NOTE 1: The recommended restrictions on the nonce parameter value length is to aid interoperability.
As stated.
5.3.4. Requirements for Resource Servers
1. shall accept access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750] or Section 7.1 of DPoP [RFC9449];
Resource servers must accept access tokens contained in the HTTP Authorization request header using the bearer token format as specified in RFC6750 or the DPoP token format as specified in RFC9449.
2. shall not accept access tokens in the query parameters stated in Section 2.3 of OAuth 2.0 Bearer Token Usage [RFC6750];
Servers must not accept access tokens sent in the query parameters because URLs can easily leak. Sending tokens in the Authorization header is much safer, as headers are not automatically exposed or logged.
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 RFC6750.
5. shall support and verify sender-constrained access tokens using one or both of the following methods:
•MTLS as described in [RFC8705],
•DPoP as described in [RFC9449].
Refer to 5.3.1.1.1.
5.4. Cryptography and Secrets
5.4.1. General requirements
1. Authorization servers, clients, and resource servers when creating or processing JWTs shall
1. adhere to [RFC8725];
2. usePS256,ES256, orEdDSA(using theEd25519variant) algorithms; and
3. not use or accept thenonealgorithm.
RFC8725 explains best practices for JWTs. The summary is as follows:
- Algorithm Verification: Libraries must be designed to allow users to select supported algorithms and must prohibit cryptographic operations using unsupported algorithms.
- Use of Appropriate Algorithms: Applications must use cryptographic algorithms that meet their security requirements and are considered secure at the current time. Since the security of algorithms can change over time due to newly discovered vulnerabilities, applications must be designed to adapt flexibly.
- Verification of Cryptographic Operations: All results of cryptographic operations related to JWTs must be verified, and if any verification fails, the JWT must be rejected.
- Validation of Cryptographic Inputs: Inputs to cryptographic operations must be validated.
- Key Entropy: Keys must have sufficient entropy to avoid weaknesses such as vulnerable symmetric keys.
- Use of UTF-8 Encoding: In compliance with the JSON specification, UTF-8 must be used for encoding and decoding.
- Verification of Issuer and Subject: Applications must verify the issuer and subject claims and reject the JWT if they do not match the expected values.
- Verification of Audience: Applications must verify the JWT’s audience and reject the JWT if it does not match the expected audience.
- Avoiding Compression Before Encryption: To prevent information leakage, data should not be compressed before encryption.
- Attention to Received Claims: Applications must be cautious about vulnerabilities in received claims such as the
kidfield and URLs in the header. - Explicit JWT Typing: To prevent confusion between different types of JWTs, the use of the
typheader parameter is recommended. - Separate Validation Rules: If the same issuer issues multiple types of JWTs, separate validation rules should be applied to each type to prevent misuse.
Additionally, in order to generate verifiable signatures for JWTs such as client assertions, it is required to use secure and modern signature algorithms like PS256, ES256, and EdDSA (using the Ed25519 format).
The use or acceptance of the none algorithm is not permitted.
2. RSA keys shall have a minimum length of 2048 bits.
3. Elliptic curve keys shall have a minimum length of 224 bits.
- RSA keys must be at least 2048 bits long.
- EC Keys must be at least 224 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, refresh 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.
5.4.2. JSON Web Key Sets
This profile supports the use of private_key_jwt and OpenID Connect, where clients and authorization servers must verify payloads using keys provided by another party.
- Authorization servers are strongly recommended to distribute public keys through JWKS URI endpoints.
- Clients are recommended to manage their keys either through JWKS URI endpoints or the
jwksparameter with RFC7591 and RFC7592.
The definitions of authorization server jwks_uri and client jwks_uri are provided in RFC8414 and RFC7591, respectively.
Any server providing a jwks_uri endpoint:
- Must serve it over TLS.
- Should not use JOSE headers like
x5uorjku. - Should not serve a JWK set with multiple keys sharing the same
kid.
5.4.3. Handling Duplicate Key Identifiers
If a JWK set contains multiple keys with the same kid, it is not recommended. However, to improve interoperability, when there are duplicate kid values, verifiers must consider other JWK attributes such as kty, use, and alg when selecting a key to verify the JWS message. For example, the process of selecting a key for signature verification could follow an algorithm like this:
- Search the JWK set for keys whose
kidmatches the one in the JOSE header. - If only one matching key is found, use that key.
- If multiple matching keys are found, sequentially check other attributes such as
alg,use,kty, andcrv, andusethe key that matches the message.
5.5. Main differences to FAPI 1.0
1. JAR (FAPI 1.0 Advanced) v.s. PAR (FAPI 2.0)
In FAPI 1.0 Advanced, JAR was used to prevent request tampering. However, creating and signing JWTs burdened client implementations and caused interoperability issues.
In FAPI 2.0, PAR is mandatory. It sends authorization requests through the backchannel beforehand, avoids front-channel dependency, improves request integrity, reduces the need for JWTs, lowers implementation burden, and improves interoperability.
2. JARM (FAPI 1.0 Advanced) v.s. Only code in authorization response (FAPI 2.0)
In FAPI 1.0 Advanced, authorization responses could include meaningful information like ID tokens, so JARM was used to protect the integrity of the whole response.
In FAPI 2.0, authorization responses are limited to returning only an authorization code, and information like ID tokens is conveyed via the backchannel (token endpoint).
As a result, JARM became unnecessary, simplifying implementations and improving interoperability.
3. BCM principle-based design (FAPI 1.0 Advanced) v.s.Design based on attacker models and BCP (FAPI 2.0)
In FAPI 1.0 Advanced, security was implemented by individually addressing threats based on the Basin-Cremers-Meier (BCM) principles.
In FAPI 2.0, security is based on defining attacker models and security goals first, then designing according to OAuth Security BCP (RFC9700), making the overall design more consistent.
4. s_hash (FAPI 1.0 Advanced) v.s. PKCE (FAPI 2.0)
In FAPI 1.0 Advanced, CSRF protection was provided by verifying the integrity of the state parameter using s_hash.
In FAPI 2.0, CSRF protection is handled via PKCE, and the integrity of the state parameter is indirectly ensured through PAR.
5. Pre-registration of redirect URIs (FAPI 1.0 Advanced) v.s. Specifying redirect URIs via PAR (FAPI 2.0)
In FAPI 1.0 Advanced, redirect URIs had to be pre-registered with the authorization server.
In FAPI 2.0, using PAR combined with client authentication removes the need for pre-registering redirect URIs, allowing for more flexibility.
6. code or code id_token (FAPI 1.0 Advanced) v.s. only code (FAPI 2.0)
In FAPI 1.0 Advanced, authorization responses could include an ID token alongside the authorization code. Therefore, clients were required to perform ID token signature verification and nonce validation to protect against response tampering and replay attacks.
In FAPI 2.0, authorization responses are limited to only returning an authorization code, and ID tokens can be retrieved later through a backchannel request to the token endpoint. As a result, clients are no longer required to perform ID token signature or nonce checks at the authorization response stage and these checks can be skipped by clients. However, PKCE verification is mandatory, as it is enforced by the authorization server to protect the authorization code.
7. Using ID token for signature verification (FAPI 1.0 Advanced) v.s. PKCE (FAPI 2.0)
In FAPI 1.0 Advanced, ID tokens were used to verify the integrity of requests and responses (detached signatures).
In FAPI 2.0, PKCE alone ensures authorization code integrity, and ID tokens are no longer used for this purpose.
8. Encrypting ID tokens over the front channel (FAPI 1.0 Advanced) v.s. ID tokens only via the backchannel (FAPI 2.0)
In FAPI 1.0 Advanced, encrypting ID tokens was sometimes necessary to securely transmit them over the front channel.
In FAPI 2.0, all ID tokens are retrieved via the backchannel, so encryption is no longer needed, simplifying implementation.
9. Including nbf and exp in the request object (FAPI 1.0 Advanced) v.s. Expiry set on request_uri (FAPI 2.0)
In FAPI 1.0 Advanced, the validity period of a request was managed by including nbf (not before) and exp (expiration) claims.
In FAPI 2.0, the server automatically assigns an expiration time to the request_uri issued by PAR, preventing abuse of pre-generated requests.
10. x-fapi-* headers included in the profile (FAPI 1.0 Advanced) v.s. Separated into implementation guidelines (FAPI 2.0)
In FAPI 1.0 Advanced, the x-fapi-* headers were part of the security profile.
In FAPI 2.0, implementation details like x-fapi-* headers have been moved to a separate document (Implementation and Deployment Advice), with the main profile now focusing solely on security requirements.
11. Sender-constrained tokens via MTLS (FAPI 1.0 Advanced) and Sender-constrained tokens via MTLS or DPoP (FAPI 2.0)
In FAPI 1.0 Advanced, sender-constrained tokens were enforced using MTLS.
In FAPI 2.0, DPoP (RFC9449) is also allowed, offering a flexible method that doesn’t rely solely on TLS client certificates.
For more details about FAPI 1.0, refer to “Financial-grade API (FAPI), explained by an implementer”.
6. Security Consideration
6.1. Access token lifetimes
- It is recommended to make access tokens short-lived. This reduces the amount of time an attacker can misuse a token if it is leaked.
- Ideally, a combination of refresh tokens and short-lived access tokens should be used. Refresh tokens allow clients to continuously obtain new access tokens.
- Using refresh tokens also enables regular rotation of sender-constraining keys. This is effective for mitigating key leaks and for routine security enhancements through key updates.
- Even when maintaining authorization over a long period (several days to several weeks), it is preferable to keep access tokens short-lived (several minutes to several hours) and use refresh tokens to manage longer sessions.
Note
If the lifetime of access tokens is set too short, the frequency of refresh operations will increase. This raises the load and dependency on the authorization server, creating a trade-off with performance and fault tolerance.
6.2. DPoP Proof Replay
An attacker (Type A5) may obtain a user’s DPoP proof and reuse (replay) it. Since DPoP does not sign the HTTP request body or many headers, there is also a risk that the attacker could modify the request contents and resend it. For example, in a payment request, the attacker might substitute the payment amount or the destination account.
Countermeasures
1. Use of Short-lived DPoP Nonces
Resource servers can issue short-lived DPoP nonces to limit the window during which a request can be replayed.
2. Replay Prevention with jti
Assign a unique ID (jti) to each DPoP proof and have the server track and reject proofs that have already been used (RFC9449).
3. Use of FAPI Message Signing
By including the request body in the signature (FAPI Message Signing), tampering and replay of the request can be prevented.
4. Use of MTLS
MTLS (RFC8705) can be considered as a stricter sender-constraining alternative to DPoP.
Note
These mitigations may increase implementation complexity and affect performance or scalability. Type A5 represents a sophisticated attacker model, and it may not be necessary for all ecosystems to implement all of these countermeasures.
6.3. Injection of stolen access tokens
Attackers may inject a stolen access token into a client and make it appear as if it was legitimately obtained through the authorization flow, thereby bypassing sender-constraining mechanisms like MTLS (RFC8705) or DPoP (RFC9449). This corresponds to the “Cuckoo’s Token Attack” described in FAPI 1.0.
Preconditions
For this attack to succeed, the attacker must take control of an authorization server trusted by the client through one of the following methods:
- Compromising a different authorization server trusted by the client.
- Acting as an authorization server and establishing a trust relationship with the client through social engineering.
- Compromising the client itself.
If a centralized directory or another resource server discovery mechanism exists, the attack may become easier. This could allow the attacker to trick the client into sending the stolen access token obtained from the attacker-controlled authorization server to a legitimate resource server.
Countermeasures
Although the prerequisites for this attack are strict and may not apply to all ecosystems, the following measures can be effective:
- Use different DPoP keys or MTLS certificates for each authorization server.
- Have the client send the issuer (authorization server identifier) of the access token to the resource server, and verify it on the resource server side.
*Currently, there is no standardized specification for this. - Shorten the lifetime of access tokens and use them together with refresh tokens to minimize the attack window.
Whether to implement these countermeasures should be carefully decided based on the threat model of each ecosystem.
6.4. Authorization request leaks lead to CSRF
If an attacker (Type A3) is able to intercept an authorization request, the following attacks become possible:
- The attacker logs into the authorization server using the intercepted request and obtains their own access token or authorization code.
- Then, through a Cross-Site Request Forgery (CSRF) attack, the attacker redirects the legitimate user to the client, making the client use the attacker’s authorization code.
- As a result, the legitimate user may unknowingly access the attacker’s resources, breaking session integrity.
Preconditions
This attack assumes the attacker has the ability to:
- Read authorization requests (e.g., via log files or side channels).
- Launch a CSRF attack against the user.
Because redirect-based authorization flows cannot strictly bind the session between the user and the client, and between the user and the authorization server, they are structurally vulnerable to this type of attack.
Countermeasures
The following methods can help mitigate this attack:
- Enforce single-use of
request_uriat the authorization server
Even if the attacker reads the request, the attack will fail if the legitimate user has already used the corresponding request_uri. - Allow only a single use of an authorization code per authorization endpoint call on the client side
If the attacker cannot send the authorization code to the token endpoint before the legitimate user does, the attack will fail. - Shorten the authorization code’s expiration time
Limiting the time available for the attacker to complete the attack reduces the likelihood of success.
Note
If the attacker can completely block the legitimate user’s request, the first two countermeasures may be bypassed.
However, in practice, attackers can typically only read authorization requests (e.g., via logs or side channels), and fully blocking a legitimate user’s request is difficult.
That said, if the user’s internet connection is slow, there is a slightly increased chance that the attacker could succeed by acting faster.
6.5. Browser-swapping attacks
When an attacker is able to access the authorization response sent through a victim’s browser, a “browser swap attack” becomes possible.
- The attacker initiates an authorization flow using their own browser and the client, sending a pushed authorization request (PAR) to the authorization server.
- The authorization server returns a
request_uri, and the client redirects the attacker’s browser to the authorization server. - The attacker intercepts the redirect URL and forwards it to the victim (e.g., embedded in a phishing site, email, or QR code).
- Believing it to be a legitimate authentication/authorization flow, the victim logs in and grants access at the authorization server.
- The attacker obtains the authorization response displayed in the victim’s browser and transfers it back to their own browser.
- Since the client believes the flow was initiated from the attacker’s browser, it accepts the authorization response as valid and obtains the access token or user information.
- As a result, the attacker gains access to the client as if they were the victim or obtains authorization to access the victim’s resources.
Difficulty of Defense
Under current redirect-based protocols, there is no complete way to prevent this attack if the authorization response leaks.
Therefore, this specification emphasizes protecting the confidentiality of the authorization response using measures such as:
- Prohibiting open redirectors.
- Pre-registering and validating redirect_uri values.
- Using authenticated and encrypted channels (e.g., HTTPS) for exchanging redirect_uri.
- Eliminating request information from the front channel by using PAR.
Caution for Implementers
This attack assumes leakage of the authorization response. Especially when applying this profile in different contexts like mobile applications, protecting the confidentiality of the authorization response must be treated as a top priority.
6.6. Incomplete or incorrect implementations of the specifications
Implementing this document, as well as its underlying specifications of OpenID Connect and OAuth, completely and accurately is critically important to maximize the benefits of security and interoperability.
Validation Tools
The OpenID Foundation provides testing tools to verify whether implementations are correctly performed:
A list of already certified implementations is also publicly available:
Recommendation
Systems utilizing this profile should use implementations certified by the OpenID Foundation. Doing so helps prevent security risks and problems caused by inconsistencies in implementation.
6.7. Client Impersonating Resource Owner
In Section 4.15 of OAuth 2.0 Security Best Current Practice, an attack is described in which a malicious client manipulates its client_id to be mistaken for the resource owner’s subject identifier.
The following conditions must be met for this attack to succeed:
- The client is able to freely control or set the value of its
client_id. - The authorization server issues access tokens to both the client and the end-user with equivalent privileges.
Recommendation
To prevent such attacks, authorization servers should:
- Ensure that clients cannot freely set or manipulate their
client_id. - Design the
client_idformat so that it cannot be confused with the end-user’s subject (sub).
Implementing these measures can reduce the risk of clients impersonating resource owners.
6.8. Key Compromise
To minimize the impact in case a cryptographic key is compromised, the following measures are recommended:
Key Rotation
Regular and automated key rotation shortens the window in which a leaked key can be exploited. By using a jwks_uri endpoint, keys can be updated safely and efficiently without the need for manual distribution or synchronization.
Key Usage
It is recommended to use keys for a single purpose only. For example, the same key should not be used for both signing and encryption. For more details, see NIST Special Publication 800–57 Part 1 Revision 5, Section 5.2.
Stateful Credentials
When using stateless tokens signed by a key, if the signing key is leaked, attackers may forge tokens. By designing systems to use stateful tokens and centrally managing their validity, this risk can be reduced.
On the other hand, stateless tokens have the following advantages:
- Resource servers can validate the token without referring to a database, as all necessary information is contained within the token itself.
- Token verification can be done independently of the authorization server, leading to better performance and scalability.
- Particularly effective in environments where authorization servers and resource servers are separated. (See RFC9068)
When designing tokens, careful evaluation of the trade-offs between security and operational efficiency is necessary.
Relationships Between Credentials
When multiple credentials are issued through a single authorization process, it is recommended to clearly establish their relationships. This allows related credentials to be collectively revoked if one credential is compromised or misused.
7. Privacy Considerations
When implementing this document, various privacy factors must be considered. Since it is a profile of OAuth 2.0 and OpenID Connect, the privacy concerns are not unique to this document but common across OAuth and OpenID Connect. Implementers are encouraged to conduct a thorough Privacy Impact Assessment (PIA) and address any identified risks. (References: ISO29100, ISO29134)
Key Privacy Threats
- Inadequate or insufficient privacy notices.
- Lack of real choice on consent screens.
- Misuse of data beyond the agreed purpose by servers or clients.
- Clients requesting more data than necessary (collection minimization violation).
- Resource servers returning unsolicited personal data.
- Processing of more data than needed (data minimization violation).
- Authorization servers tracking end-users and their data sharing.
- Clients colluding to track users via token correlation.
- End-users misidentifying clients due to unclear displays.
- End-users not fully understanding what data they are sharing.
- Personal data leakage in authorization requests/responses.
- Data breaches at authorization servers, resource servers, or clients.
This profile reduces the amount of data sent but cannot fully eliminate risks of data exposure.
8. IANA Considerations
8.1. Registration of OAuth Dynamic Client Registration Metadata
This specification requests the registration of the following client metadata into the IANA “OAuth Dynamic Client Registration Metadata” registry as defined by RFC7591.
8.1.1. Registration Details
use_mtls_endpoint_aliasesA flag indicating that the client is required to use the MTLS endpoint aliases declared in the authorization server’s metadata (see RFC8705). If this flag is set to true, the use of MTLS endpoint aliases is expected not only for client authentication and sender-constraining access tokens but also for broader purposes.
Finally
Thank you for engaging with the detailed article. Stay tuned for subsequent information about FAPI 2.0.
In closing, Authlete, Inc., a company I co-founded, proudly supports both FAPI 1.0 and FAPI 2.0, recognized by FAPI OpenID Provider Certification Program.
Please feel free to reach out to us through the web form or via email for any inquiries:
- For Licensing and Contracts: sales@authlete.com
- For Partnership Opportunities: bizdev@authlete.com
- For Technical Support: support@authlete.com
We welcome any inquiries about our solution or potential collaboration/partnership opportunities. Also, please follow our social channels:
Updates
- February 11, 2024: This document was initially published, exclusively focusing on FAPI 2.0 Security Profile (ID2).
- June 2, 2025: Updated for FAPI 2.0 Security Profile (Final).





