Exploring FAPI 2.0: The Latest in API Security Technology
This post explores FAPI standards, which enhance secure data exchange in high-risk sectors, evolving from OAuth 2.0-based FAPI 1.0 to the more secure FAPI 2.0.
Join the DZone community and get the full member experience.
Join For FreeFAPI 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 the security of financial APIs, presented through four key components:
1. Security Profile
The security profile defines the fundamental requirements in FAPI 2.0, utilizing the latest security specifications such as “PAR”, “DPoP”, etc. (was previously called “Baseline Profile”).
2. Message Signing Profile
The message signing profile provides interoperable support for non-repudiation across OAuth 2.0-based requests and responses (was previously called “Advanced Profile”).
3. Attacker Model
The attacker model details potential threats, guiding the development of robust security measures.
4. Grant Management
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 (March 2021)
- Financial-grade API Security Profile 1.0 — Part 1: Baseline
- Financial-grade API Security Profile 1.0 — Part 2: Advanced
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."
Certification Program
As of February 2024, The Certification Program for FAPI OpenID Providers 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
- Australia FAPI 2.0 ConnectId Implementer’s Draft
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
The articles below may help understand some of these specifications.
- Illustrated PAR: OAuth 2.0 Pushed Authorization Requests
- Illustrated DPoP (OAuth Access Token Security Enhancement)
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_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.
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's 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 proof of possession for it.
MTLS for Sender-Constrained Access Tokens
Section 3 of RFC 8705 defines a sender-constraining 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 an 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 the FAPI 2.0 Security Profile. Here’s how it works.
- The client creates a DPoP-proof JWT, which is a signed JWT, using a client’s 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 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)," linked earlier.
Authorization Code Binding to DPoP Key
RFC 9449 also introduces the dpop_jkt
request parameter in authorization requests. This parameter ensures proof of possession of 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.
- The client computes a thumbprint of the public key.
- The client sends an authorization request including the thumbprint as the
dpop_jkt
parameter. - The authorization server binds the
dpop_jkt
value with the authorization code. - The authorization server issues the authorization code.
- The client creates a DPoP-proof JWT, which is a signed JWT, using a client’s 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
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.
- The client creates a DPoP proof JWT including a server-provided nonce value.
- The client sends a token request including the DPoP proof JWT.
- The authorization server verifies the signature of the DPoP-proof JWT.
- The authorization server ensures the nonce value in the DPoP proof JWT matches the one it provided earlier.
- An attacker steals the DPoP-proof JWT from the client.
- The attacker sends a request including the DPoP proof JWT to the authorization server.
- The authorization server verifies the signature of the DPoP-proof JWT.
- 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.
Security Profile
In the following sections, we will explore the FAPI 2.0 Security Profile (ID2).
Introduction
As described in “5.1. Introduction”, the FAPI 2.0 Security Profile is based on OAuth 2.0 (RFC 6749) and designed to meet the security objectives specified in the Attacker Model. 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, FAPI CIBA, Grant Management, and RAR (RFC 9396, Rich Authorization Requests). It also notes the current limitations in securing public clients to these standards.
Network Layer Protections
“5.2. Network Layer Protections” 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’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, is required.
- Despite the use of higher validation certificates, the risk of impersonation via rogue certificates exists, with CAA records (RFC 8659) 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
andTLS_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, 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 are permitted.
Requirements for Authorization Servers
“5.3.1. Requirements for Authorization Servers” lists requirements for authorization servers.
General Requirements
“5.3.1.1. General Requirements” 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 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 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.
While the use of response_type=none
is not explicitly prohibited here, “5.5. Main Differences to FAPI 1.0” 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)
3. Shall support confidential clients as defined in [RFC6749]
Authorization servers must support confidential clients as defined in RFC 6749.
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 (RFC 8705) or DPoP (RFC 9449) 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 the FAPI 2.0 Security Profile are as follows.
tls_client_auth
(defined in section 2.1 of RFC 8705)self_signed_tls_client_auth
(defined in section 2.2 of RFC 8705)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 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, 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]) 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.
10. If using DPoP, may use the server provided nonce mechanism (as defined in section 8 of [I-D.ietf-oauth-dpop])
If DPoP is used as a sender-constrained access token mechanism, the authorization server may employ a 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.
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 the authorization server requirements listed in “5.3.1.2. Authorization Code Flow”.
1. Shall support the authorization code grant (
response_type=code
andgrant_type=authorization_code
) described in [RFC6749]
Authorization servers must support the authorization code grant as described in RFC 6749.
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 clause 6.
For more details about PAR, refer to “Illustrated PAR: OAuth 2.0 Pushed Authorization Requests,” linked earlier.
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] with
S256
as the code challenge method
Authorization servers must mandate RFC 7636, PKCE (Proof 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_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. 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).
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 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.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
withexpires_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. Requirements for Clients” lists requirements for clients.
General Requirements
In this section, we walk through the general requirements for clients listed in “5.3.2.1. General Requirements”.
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)self_signed_tls_client_auth
(defined in section 2.2 of RFC 8705)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]
According to Section 2.1 of “RFC 6750, OAuth 2.0 Bearer Token Usage”, clients must send an access token in the HTTP Authorization
request header using the bearer token format as specified in RFC 6750. 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, 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 theaud
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 a fallback mechanism 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 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.
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 the client requirements listed in “5.3.2.2. Authorization Code Flow”.
1. Shall use the authorization code grant described in [RFC6749]
Clients must use the authorization code grant (response_type=code
and grant_type=authorization_code
) as specified in RFC 6749.
2. Shall use pushed authorization requests according to [RFC9126]
Clients must use PAR (RFC 9126, Pushed Authorization Requests). For more details about PAR, refer to “Illustrated PAR: OAuth 2.0 Pushed Authorization Requests,” linked earlier.
3. Shall use PKCE [RFC7636] with
S256
as the code challenge method
Clients must use PKCE (RFC 7636) 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 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 matches the issuer URL of the authorization server according to RFC 9207.
Requirements for Resource Servers
“5.3.3. Requirements for Resource servers” 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. 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 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.
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” 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, 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 the 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
, orEdDSA
(using theEd25519
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” 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 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 the 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” 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”.
Security Consideration
“5.7. 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” 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.
Updates
April 11, 2024: This document was initially published, exclusively focusing on FAPI 2.0 Security Profile (ID2).
Published at DZone with permission of Hideki Ikeda. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments