Support & Downloads

Quisque actraqum nunc no dolor sit ametaugue dolor. Lorem ipsum dolor sit amet, consyect etur adipiscing elit.

j j

Contact Info
New York +(123) 456 -7890 innovio@mikado-themes.com 184 Main Street Victoria 8007
Folow us on social

Guest Blog: Financial-grade API (FAPI) Explained by an Implementer

Introduction

Financial-grade API (FAPI) is a technical specification that Financial-grade API Working Group of OpenID Foundation has developed. It uses OAuth 2.0 and OpenID Connect (OIDC) as its base and defines additional technical requirements for the financial industry and other industries that require higher security.

OpenID Foundation Working Groups and Financial-grade API stack

The latest version is Implementer’s Draft 2 which was approved in October, 2018. Part 1 and Part 2 are freely viewable at the website of OpenID Foundation. Part 1 is a security profile for read-only APIs, and Part 2 is a security profile for read-and-write APIs.

The difference from the Implementer’s Draft 1 (which was approved in February and July, 2017) is not so small, so FAPI implementers have to check it.

History of Financial-grade API specification

It should be noted that the foreword of FAPI Implementer’s Draft 2 indicates that Client Authentication Backchannel Authentication (CIBA) is positioned as Part 3 of FAPI. For details about CIBA, please read the following article.

This article explains Financial-grade API security profile.

Certification Program

The certification program for FAPI officially started on April 1, 2019 (announce). Two vendors were granted certification on the start day.

Certified Financial-grade API OpenID Providers as of April 1, 2019

Authlete, Inc., the company founded by the author of this article (me), is one of the two vendors. Please contact Authlete, Inc. (sales@authlete.com) if you are interested in a certified implementation of Financial-grade API OpenID Provider.


0. Prior Knowledge

0.1. Basic Specifications

The format of the FAPI specification is a terse list of technical requirements, so the document is not long. In exchange, a lot of prior knowledge is required to read it smoothly. Especially, you have to learn RFC 6749 and RFC 6750 (the core of OAuth 2.0) and OpenID Connect Core 1.0 (the core of OpenID Connect) by heart.

In addition, because specifications related to JWT (JWSJWEJWKJWA and JWT) are prior knowledge to understand OIDC Core, they are of course prior knowledge to read the FAPI specification. Therefore, you need to understand them perfectly.

Furthermore, PKCE (RFC 7636) which was published in September, 2015 is now regarded as a part of the basic set of OAuth 2.0 specifications as well as RFC 6749 and RFC 6750.

The following is a list of specifications that you should read at least once before the FAPI specification.

Articles below may help understanding these specifications.

0.2. Mutual TLS

In general, “Mutual TLS” means that a client is also required to present its certificate in a TLS connection. However, in the context of FAPI, Mutual TLS means the following two which are defined in “OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens” (MTLS).

  1. OAuth client authentication using a client certificate
  2. Tokens bound to a client certificate

0.2.1. OAuth Client Authentication using a Client Certificate

When a confidential client (RFC 6749, 2. Client Types) accesses a token endpoint (RFC 6749, 3.2. Token Endpoint), client authentication (RFC 6749, 2.3. Client Authentication) is required. Client authentication is a process where a client application proves it has its confidential authentication information.

Client Authentication at Token Endpoint

There are several ways for client authentication. The following are client authentication methods listed in OIDC Core, 9. Client Authentication (except none).

  • client_secret_basic — Basic Authentication using a pair of client ID and client secret
  • client_secret_post — Embedding a pair of client ID and client secret in a request body
  • client_secret_jwt — Passing a JWT signed by a key based on a client secret with a symmetric algorithm
  • private_key_jwt — Passing a JWT signed by a private key with an asymmetric algorithm

In client_secret_basic and client_secret_post, a client application directly shows the server its client secret to prove that it has the confidential information.

In client_secret_jwt, a client application indirectly proves that it has the client secret by signing a JWT with the client secret and passing the JWT to the server. On the other hand, in private_key_jwt, signing is performed with an asymmetric private key and the server verifies the signature with the public key corresponding to the private key.

Apart from the above, “2. Mutual TLS for OAuth Client Authentication” of MTLS introduces new client authentication methods below.

  • tls_client_auth — Utilizing a PKI client certificate used in a TLS connection
  • self_signed_tls_client_auth — Utilizing a self-signed client certificate used in a TLS connection

These two utilize the client certificate used in a TLS connection between the client and the token endpoint for client authentication.

Client Certificate for Client Authentication

In tls_client_auth, the PKI client certificate used in a TLS connection established between a client and a server is used for client authentication. The server verifies the client certificate (this should be done even in a context irrelevant to OAuth) and then checks whether the Subject Distinguished Name or Subject Alternative Name matches the pre-registered one. For this process, client applications that want to use tls_client_auth for client authentication must register Subject Distinguished Name or Subject Alternative Name into the server in advance. The specification newly defines the following client metadata for this purpose.

  • tls_client_auth_subject_dn
  • tls_client_auth_san_dns
  • tls_client_auth_san_uri
  • tls_client_auth_san_ip
  • tls_client_auth_san_email

In self_signed_tls_client_auth, a self-signed client certificate is used instead of a PKI client certificate. To use this client authentication method, client applications have to register a self-signed client certificate into the server in advance.

The following table is the list of client authentication methods mentioned in FAPI.

Client Authentication Methods

0.2.2. Certificate-Bound Tokens

Once a traditional access token is leaked, an attacker can access APIs with the access token. Traditional access tokens are just like a train ticket which anyone can use once it is stolen.

An idea to mitigate this vulnerability is to check whether the API caller bringing an access token matches the legitimate holder of the access token when an API call is made. This is just like the boarding procedure for international flights where passengers are required to show not only a plane ticket but also their passport.

FAPI calls this idea “holder of key mechanism” and lists “Mutual TLS” and “Token Binding” as possible deployment options for the mechanism. In this context, “Mutual TLS” means the specification defined in “3. Mutual TLS Client Certificate-Bound Access Tokens” of MTLS.

Because Mutual TLS has several meanings as explained above and I actually experienced a problematic conversation like below,

Me: The API management solution of your company does not support Mutual TLS (as a holder of key mechanism).
The company: Not correct. Our solution supports Mutual TLS (because it can be configured to request a client certificate for TLS communication).

I’ve personally decided to call Mutual TLS as a holder of key mechanism “Certificate Binding”. This naming is not so bad (at least for me) because it sounds symmetrical to Token Binding and because actual implementations will eventually become just binding a certificate to an access token and won’t care whether the certificate has been extracted from a mutual TLS connection or has come from somewhere else.

In an implementation of Certificate Binding, when the token endpoint of an authorization server issues an access token, it calculates the hash value of the client certificate presented by the client application in the TLS connection and remembers the binding between the access token and the hash value (or embeds the hash value into the access token if the implementation of the access token is a self-container-type JWT). When the client application accesses an API of the target resource server, it uses the same client certificate that was previously used in the communication with the token endpoint. The implementation of the API extracts an access token and a client certificate from the request, calculates the hash value of the client certificate and checks the hash value matches the one that is associated with the access token. If they match, the API implementation accepts the request. If not, it rejects the request.

Certificate Binding

It is relatively easy to implement Certificate Binding because it can be implemented only if the client certificate is accessible. On the other hand, Token Binding is relatively hard because it is necessary to modify multiple layers such as TLS layer and HTTP layer. In addition, the future is uncertain as Chrome has removed the Token Binding feature although the community strongly tried to urge Chrome team to rethink it (“Intent to Remove: Token Binding”). However, anyway, related specifications were promoted to RFCs at the beginning of October, 2018.

  • RFC 8471 — The Token Binding Protocol Version 1.0
  • RFC 8472 — Transport Layer Security (TLS) Extension for Token Binding Protocol Negotiation
  • RFC 8473 — Token Binding over HTTP

OAuth 2.0 Token Binding” (its status is still “draft” as of April 2019) is a specification that defines rules to apply Token Binding to OAuth 2.0 tokens based on the specifications listed above.

0.3. JARM

JARM is a new specification which was approved at the same timing with FAPI Implementer’s Draft 2. JARM is referred to in FAPI Part 2.

The specification defines new values for the response_mode request parameter as shown below.

  1. query.jwt
  2. fragment.jwt
  3. form_post.jwt
  4. jwt

If one of the above is specified, response parameters of an authorization response are packed into a JWT and the JWT is returned as the value of a single response response parameter.

For example, a traditional authorization response in the authorization code flow looks like below. code and state response parameters are included separately.

HTTP/1.1 302 Found
Location: https://client.com/callback?code={CODE}&state={STATE}

On the other hand, if response_mode=query.jwt is added to an authorization request, the authorization response will become like below.

HTTP/1.1 302 Found
Location: https://client.com/callback?response={JWT}

JARM example

1. Part 1: Read-Only API Security Profile

As introduction of prior knowledge was done, let’s start the main part of this article. To begin with, “Part 1” which defines security profile for read-only APIs.

1.1. Part 1: Requirements for Authorization Server

5.2.2. Authorization server” in “Part 1” lists requirements for authorization server. Let’s take a look one by one.

Part 1: 5.2.2. Authorization server, 1.

shall support confidential clients;

Part 1: 5.2.2. Authorization server, 2.

should support public clients;

The definition of confidential clients and public clients is described in “2.1. Client Types” of RFC 6749. I don’t explain the difference between the client types here as it is prior knowledge for those who read the FAPI specification. However, the relationship between client types and OAuth 2.0 flows is often misunderstood even by those who are familiar with OAuth 2.0. It is only the combination of a public client and client credentials flow that RFC 6749 explicitly prohibits. Other combinations are allowed. Without this understanding, you would misread the FAPI specification.

Combinations of Flow and Client Type (RFC 6749)

Just FYI. It is confidential clients only that are allowed to make backchannel authentication requests which are defined in CIBA.

Combinations of Flow and Client Type (CIBA)

Part 1: 5.2.2. Authorization server, 3.

shall provide a client secret that adheres to the requirements in section 16.19 of [OIDC] if a symmetric key is used;

OIDC Core states that a value calculated based on a client secret must be used as the shared key when a symmetric algorithm is used for signing and encryption. If the entropy of the client secret is lower than the one required by the algorithm, the strength of the algorithm is weakened. Therefore, “16.19. Symmetric Key Entropy” requires that client secrets have entropy strong enough for used algorithms. For example, when HS256 (HMAC using SHA-256) is used for signing algorithm of ID tokens, client secrets must have 256-bit entropy at minimum.

Part 1: 5.2.2. Authorization server, 4.

shall authenticate the confidential client at the token endpoint using one of the following methods:

1. Mutual TLS for OAuth Client Authentication as specified in section 2 of [MTLS];

2.client_secret_jwt or private_key_jwt as specified in section 9 of [OIDC];

Note that client_secret_basic and client_secret_post defined in RFC 6749 are not allowed as client authentication methods at the token endpoint.

Client Authentication Methods allowed in FAPI Part 1 (Read-Only API Security Profile)

Part 1: 5.2.2. Authorization server, 5.

shall require a key of size 2048 bits or larger if RSA algorithms are used for the client authentication;

Part 1: 5.2.2. Authorization server, 6.

shall require a key of size 160 bits or larger if elliptic curve algorithms are used for the client authentication;

For example, when private_key_jwt is used as client authentication method and RSA is used for signing the JWT, the key size must be 2048 or more. Likewise, when an elliptic curve algorithm is used, the key size must be 160 at minimum.

Part 1: 5.2.2. Authorization server, 7.

shall require [RFC7636] with S256 as the code challenge method;

It is required to implement RFC 7636 (PKCE) which is a countermeasure for “authorization code interception attack”.

Authorization Code Interception Attack

RFC 7636 adds code_challenge and code_challenge_method request parameters to the authorization request and code_verifier to the token request. Because the default value used when code_challenge_method is omitted is plain, authorization requests that comply with FAPI must include code_challenge_method=S256 explicitly.

Part 1: 5.2.2. Authorization server, 8.

shall require redirect URIs to be pre-registered;

In RFC 6749, registration of redirect URIs is not required under some conditions. For FAPI, registration of redirect URIs is always required.

Part 1: 5.2.2. Authorization server, 9.

shall require the redirect_uri parameter in the authorization request;

In RFC 6749, the redirect_uri request parameter of an authorization request can be omitted under some conditions. For FAPI, the request parameter must be always included. OIDC has the same requirement.

Part 1: 5.2.2. Authorization server, 10.

shall require the value of redirect_uri to exactly match one of the pre-registered redirect URIs;

When an authorization server checks whether the value of the redirect_uri request parameter matches a pre-registered one, the rule described in “6. Normalization and Comparison” of RFC 3986 (Uniform Resource Identifier (URI): Generic Syntax) is applied unless the pre-registered one is an absolute URI. On the other hand, FAPI (and OIDC also) requires that simple string comparison be always used to check whether the redirect URIs match.

Part 1: 5.2.2. Authorization server, 11.

shall require user authentication at LoA 2 as defined in [X.1254] or more;

It is required that user authentication performed during authorization process satisfy LoA (Level of Assurance) 2 which is defined in X.1254 (Entity authentication assurance framework). The following is the definition of LoA 2 described in “6.2 Level of assurance 2 (LoA2)” of X.1254.

At LoA2, there is some confidence in the claimed or asserted identity of the entity. This LoA is used when moderate risk is associated with erroneous authentication. Single-factor authentication is acceptable. Successful authentication shall be dependent upon the entity proving, through a secure authentication protocol, that the entity has control of the credential. Controls should be in place to reduce the effectiveness of eavesdroppers and online guessing attacks. Controls shall be in place to protect against attacks on stored credentials.

For example, a service provider might operate a website that enables its customers to change their address of record. The transaction in which a beneficiary changes an address of record may be considered an LoA2 authentication transaction, as the transaction may involve a moderate risk of inconvenience. Since official notices regarding payment amounts, account status, and records of changes are usually sent to the beneficiary’s address of record, the transaction additionally entails moderate risk of unauthorized release of PII. As a result, the service provider should obtain at least some authentication assurance before allowing this transaction to take place.

Part 1: 5.2.2. Authorization server, 12.

shall require explicit consent by the user to authorize the requested scope if it has not been previously authorized;

Of course.

Part 1: 5.2.2. Authorization server, 13.

should verify that the authorization code (section 1.3.1 of [RFC6749]) has not been previously used;

Prohibiting reuse of authorization codes and ensuring that authorization codes have never been used previously are different things. If the verification were mandatory (if the specification used “shall” instead of “should”), and if the current implementation of an authorization server used randomly-generated strings as authorization codes and removed them from the database after they are used, the authorization codes would have to be kept in the database even after they are used just only for the verification. If strings that represent authorization codes are generated randomly enough, it is wasteful to keep authorization codes in the database even after their use. A certain famous engineer says “Most implementations prevent reuse of authorization codes by deleting corresponding database records and don’t check if they have been used previously, and such implementations are sufficient enough.”

Part 1: 5.2.2. Authorization server, 14.

shall return token responses that conform to section 4.1.4 of [RFC6749];

This is not a FAPI-specific requirement. Every authorization server implementation that claims it supports OAuth 2.0 must conform to section 4.1.4 of RFC 6749.

Part 1: 5.2.2. Authorization server, 15.

shall return the list of granted scopes with the issued access token;

In RFC 6749, the scope response parameter is optional unless requested scopes and granted scopes are different (RFC 6749, 5.1. Successful Response). In FAPI, the scope response parameter must be always included.

“scope” Response Parameter

Part 1: 5.2.2. Authorization server, 16.

shall provide opaque non-guessable access tokens with a minimum of 128 bits of entropy where the probability of an attacker guessing the generated token is less than or equal to 2^(-160) as per [RFC6749] section 10.10;

Entropy of access tokens must be 128 bits or more. For example, as 128-bit data becomes 22 characters when encoded by base64url, if an access token generated by your authorization server consists of ASCII letters only and its length is less than 22, it indicates that the authorization server implementation does not satisfy the requirement of Part 1, 5.2.2., 16.

Part 1: 5.2.2. Authorization server, 17.

should clearly identify long-term grants to the user during authorization as in 16.18 of [OIDC]; and

For example, if a given permission lasts long, an explanation like “The client application is requesting a permission to access your bank account to refer to your transaction history” is not enough. The explanation should be followed by an additional note like “This permission will be valid for three months.”

Part 1: 5.2.2. Authorization server, 18.

should provide a mechanism for the end-user to revoke access tokens and refresh tokens granted to a client as in 16.18 of [OIDC].

It should be noted that, if the format of access tokens is self-contained-type (e.g. JWT), the access tokens cannot be revoked unless the system implements and operates a mechanism like CRL (Certificate Revocation List) or OCSP (Online Certificate Status Protocol) of PKI (Public Key Infrastructure). If the system does not provide such mechanism, it means that the system has decided to give up revocation of access tokens. In this case, the duration of access tokens must be short enough to mitigate damage of access token leakage. See “OAuth Access Token Implementation” for further discussion.

Part 1: 5.2.2. Authorization server, 19.

shall return an invalid_client error as defined in 5.2 of [RFC6749] when mis-matched client identifiers were provided through the client authentication methods that permits sending the client identifier in more than one way;

FAPI Part 1 requires MTLS (tls_client_authself_signed_tls_client_auth) or JWT (client_secret_jwtprivate_key_jwt) for client authentication.

MTLS uses a client certificate but a certificate does not include the client identifier of the client which tries to authenticate itself with the certificate. Therefore, the client_id request parameter needs to be given explicitly.

On the other hand, JWT-based client authentication methods present a JWT as the value of the client_assertion request parameter and the JWT contains the client identifier as the value of the iss claim. Therefore, the client_id request parameter is not necessary. In addition, according to RFC 7523, 3. and OIDC Core, 9., the sub claim also holds the client identifier when a JWT is used for client authentication.

JWT-based Client Authentication and Client Identifiers

In MTLS, it is only the client_id request parameter that represents a client identifier. On the other hand, in JWT-based client authentication, both the iss claim and the sub claim hold a client identifier. The values of the claims must match. Also, if the client_id request parameter is redundantly given although JWT-based client authentication is used, the value of the request parameter must match the client identifier, too.

Part 1: 5.2.2. Authorization server, 20.

shall require redirect URIs to use the https scheme;

This sentence added by FAPI Implementer’s Draft 2 is short but has a big impact. Because of this sentence, developers cannot use custom schemes in FAPI any more. To process redirection on client side only without preparing an external Web server, developers have to use the method described in “7.2. Claimed “https” Scheme URI Redirection” of BCP 212 (OAuth 2.0 for Native Apps).

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server

Further, if it is desired to provide the authenticated user’s identifier to the client in the token response, the authorization server:

Section 5.2.2.1. lists requirements that an authorization server must follow when the authenticated user’s identifier is requested. In other words, when an ID token is requested.

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 1.

shall support the authentication request as in Section 3.1.2.1 of [OIDC];

3.1.2.1. Authentication Request” of OIDC Core is the definition of a request to an authorization endpoint in the context of OpenID Connect. RFC 6749 calls a request to an authorization endpoint “authorization request”. OIDC Core calls it “authentication request”. Aside from the names, considering that the specification of an authorization endpoint is the main part of OIDC Core, the FAPI’s requirement is almost equal to stating “shall support OIDC Core”.

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 2.

shall perform the authentication request verification as in Section 3.1.2.2 of [OIDC];

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 3.

shall authenticate the user as in Section 3.1.2.2 and 3.1.2.3 of [OIDC];

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 4.

shall provide the authentication response as in Section 3.1.2.4 and 3.1.2.5 of [OIDC] depending on the outcome of the authentication;

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 5.

shall perform the token request verification as in Section 3.1.3.2 of [OIDC]; and

Part 1: 5.2.2.1. Returning authenticated user’s identifier Authorization server, 6.

shall issue an ID Token in the token response when openid was included in the requested scope as in Section 3.1.3.3 of [OIDC] with its sub value corresponding to the authenticated user and optional acr value in ID Token.

Summary of the requirements above is “shall follow OIDC Core specification.” Nothing special for FAPI.

1.2. Part 1: Requirements for Public Client

5.2.3. Public client” of “Part 1” lists requirements for public clients. Let’s take a look one by one.

Part 1: 5.2.3. Public client, 1.

shall support [RFC7636] or the mechanisms defined in Financial-grade API — Part 2;

RFC 7636 is PKCE, but what are “the mechanisms defined in Financial-grade API — Part 2”? This description is ambiguous.

Part 1: 5.2.3. Public client, 2.

shall use S256 as the code challenge method for the [RFC7636];

This means “an authorization request must include code_challenge_method=S256.”

Part 1: 5.2.3. Public client, 3.

shall use separate and distinct redirect URI for each authorization server that it talks to;

Part 1: 5.2.3. Public client, 4.

shall store the redirect URI value in the resource owner’s user-agents (such as browser) session and compare it with the redirect URI that the authorization response was received at, where, if the URIs do not match, the client shall terminate the process with error;

Part 1: 5.2.3. Public client, 5.

shall adhere to the best practice stated by [BCP212]; and

These requirements are clear enough.

Part 1: 5.2.3. Public client, 6.

shall implement an effective CSRF protection.

In normal cases, CSRF protection is implemented on server side. What is CSRF protection as a requirement for public clients? This is CSRF protection for redirect URIs. The following is an excerpt from “10.12. Cross-Site Request Forgery” of RFC 6749.

The client MUST implement CSRF protection for its redirection URI. This is typically accomplished by requiring any request sent to the redirection URI endpoint to include a value that binds the request to the user-agent’s authenticated state (e.g., a hash of the session cookie used to authenticate the user-agent). The client SHOULD utilize the “state” request parameter to deliver this value to the authorization server when making an authorization request.

In addition to the requirements from “Public client, 1” to “Public client, 6”, “if it is desired to obtain a persistent identifier of the authenticated user”, that is, if an ID token is requested, an authorization request by a public client:

Part 1: 5.2.3. Public client, 7.

shall include openid in the scope value; and

Part 1: 5.2.3. Public client, 8.

shall include nonce parameter defined in Section 3.1.2.1 of [OIDC] in the authentication request.

On the other hand, “If openid is not in the scope value”, an authorization request by a public client:

Part 1: 5.2.3. Public client, 9.

shall include the state parameter defined in section 4.1.1 of [RFC6749].

1.3. Part 1: Requirements for Confidential Client

5.2.4. Confidential client” of “Part 1” lists requirements for confidential clients. The requirements are positioned as additions to the requirements for public clients. Therefore, confidential clients must follow not only the requirements in 5.2.4. but also the requirements in 5.2.3.

Part 1: 5.2.4. Confidential client, 1.

shall support the following methods to authenticate against the token endpoint:

1. Mutual TLS for OAuth Client Authentication as specified in section 2 of [MTLS];

2.client_secret_jwt or private_key_jwt as specified in section 9 of [OIDC];

Note that client authentication methods defined in RFC 6749 (client_secret_basic and client_secret_post) cannot be used.

Part 1: 5.2.4. Confidential client, 2.

shall use RSA keys with a minimum 2048 bits if using RSA cryptography;

Part 1: 5.2.4. Confidential client, 3.

shall use elliptic curve keys with a minimum of 160 bits if using Elliptic Curve cryptography; and

Part 1: 5.2.4. Confidential client, 4.

shall verify that its client secret has a minimum of 128 bits if using symmetric key cryptography.

These requirements apply when encrypted JWTs are used.

1.4. Part 1: Requirements for Read-Only API

6.2.1. Protected resources provisions” of “Part 1” lists requirements for read-only protected resource endpoints.

Part 1: 6.2.1. Protected resource provisions, 1.

shall support the use of the HTTP GET method as in Section 4.3.1 of [RFC7231];

Part 1: 6.2.1. Protected resource provisions, 2.

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

That is, protected resource endpoints must support HTTP GET method and be able to accept an access token in the format of Authorization: Bearer {AccessToken}.

Request to Read-Only Protected Resource Endpoint

Part 1: 6.2.1. Protected resource provisions, 3.

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

That is, protected resource endpoints must not accept a query parameter in the format of access_token={AccessToken}.

Part 1: 6.2.1. Protected resource provisions, 4.

shall verify that the access token is neither expired nor revoked;

Part 1: 6.2.1. Protected resource provisions, 5.

shall verify that the scope associated with the access token authorizes the reading of the resource it is representing;

Part 1: 6.2.1. Protected resource provisions, 6.

shall identify the associated entity to the access token;

Part 1: 6.2.1. Protected resource provisions, 7.

shall only return the resource identified by the combination of the entity implicit in the access and the granted scope and otherwise return errors as in section 3.1 of [RFC6750];

These are general steps of access token verification that protected resource endpoints are expected to take.

3.1. Error Codes” of RFC 6750 defines three error codes. They are invalid_requestinvalid_token and insufficient_scope. One point those who are not familiar with RFC 6750 may feel strange is that an error code is embedded not in the response body but in the WWW-Authenticate HTTP header.

RFC 6750 Error Response

Part 1: 6.2.1. Protected resource provisions, 8.

shall encode the response in UTF-8 if applicable;

Part 1: 6.2.1. Protected resource provisions, 9.

shall send the Content-type HTTP header Content-Type: application/json; charset=UTF-8 if applicable;

Protected resource endpoints in FAPI are expected to return their responses in JSON format.

Part 1: 6.2.1. Protected resource provisions, 10.

shall send the server date in HTTP Date header as in section 7.1.1.2 of [RFC7231];

The format of Date header is defined in “7.1.1.1. Date/Time Formats” of RFC 7231. Below is an example.

Date: Sun, 06 Nov 1994 08:49:37 GMT

Part 1: 6.2.1. Protected resource provisions, 11.

shall set the response header x-fapi-interaction-id to the value received from the corresponding fapi client request header or to a [RFC4122] UUID value if the request header was not provided to track the interaction, e.g., x-fapi-interaction-id: c770aef3-6784-41f7-8e0e-ff5f97bddb3a; and

This is a requirement specific to FAPI. Responses from FAPI protected resource endpoints must include an x-fapi-interaction-id header.

Part 1: 6.2.1. Protected resource provisions, 12.

shall log the value of x-fapi-interaction-id in the log entry.

This is also specific to FAPI. This requirement doesn’t have any impact on request and response formats, but this can make it easy to correlate server-side logs and client-side logs.

Part 1: 6.2.1. Protected resource provisions, 13.

should support the use of Cross Origin Resource Sharing (CORS) [CORS] and or other methods as appropriate to enable JavaScript clients to access the endpoint if it decides to provide access to JavaScript clients.

For example, if a protected resource endpoint wants to allow JavaScript clients to access it from anywhere, the endpoint should include an Access-Control-Allow-Origin: * header in responses.

1.5. Part 1: Requirements for Clients to Access Read-Only API

6.2.2. Client provisions” of “Part 1” lists requirements for clients to follow in accessing read-only protected resource endpoints.

Part 1: 6.2.2. Client provisions, 1.

shall send access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750]; and

That is, clients send an access token in the format of Authorization: Bearer {AccessToken}.

Part 1: 6.2.2. Client provisions, 2.

(withdrawn);

Part 1: 6.2.2. Client provisions, 3.

may send the last time the customer logged into the client in the x-fapi-auth-date header where the value is supplied as a HTTP-date as in section 7.1.1.1 of [RFC7231], e.g., x-fapi-auth-date: Tue, 11 Sep 2012 19:43:31 GMT; and

Part 1: 6.2.2. Client provisions, 4.

may send the customer’s IP address if this data is available in the x-fapi-customer-ip-address header, e.g., x-fapi-customer-ip-address: 198.51.100.119; and

Part 1: 6.2.2. Client provisions, 5.

may send the x-fapi-interaction-id request header whose value is a [RFC4122] UUID to the server to help correlate log entries between client and server, e.g., x-fapi-interaction-id: c770aef3-6784-41f7-8e0e-ff5f97bddb3a.

These are FAPI-specific HTTP headers. It is up to clients whether to send the headers or not.

FAPI-specific HTTP Headers

1.6. Part 1: Security Considerations

7. Security considerations” of “Part 1” lists security considerations. Summary is as follows.

7.1. — Follow BCP 195. Use TLS 1.2 or newer. Follow RFC 6125.

7.2. — Part 1 doesn’t authenticate authorization request and response.

7.3. — Part 1 doesn’t assure message integrity of authorization request.

7.4.1. — Part 1 doesn’t discuss encryption of authorization request.

7.4.2. — Be careful not to leak information through logs.

7.4.3. — Be careful not to leak information through referrer. Make duration of access tokens short.

7.5. — Native applications also must use https for the scheme of redirect URI.

7.6. — Both FAPI implementation and underlying OAuth/OIDC implementation must be complete and correct. See OpenID Certification.

“Part 2” provides solutions for security considerations listed in “Part 1”, for example, by making “request object” and “ID token as detached signature” (described later) mandatory. “Part 2” is recommended when higher security than “Part 1” is needed.


2. Part 2: Read and Write API Security Profile

Next, let’s read “Part 2” which is a security profile for read-and-write APIs.

2.1. Detached Signature

5.1. Introduction” of “Part 2” states that it uses “ID token” as “detached signature”.

An ID token is signed by an authorization server, so even if an attacker tampered the content of the ID token, it could be detected. A client application that has received an ID token can confirm that the ID token has not been tampered by verifying the signature of the ID token.

If an authorization server embeds hash values of response parameters (such as code and state) into an ID token, a client application can confirm that the values of the response parameters have not been tampered by computing hash values of the response parameter values and comparing them to the hash values embedded in the ID token. In the context, the ID token is regarded as a detached signature.

ID Token as Detached Signature

For the code response parameter that represents an authorization code, c_hash has already been defined in OIDC Core as a claim that represents the hash value of code. Likewise, at_hash has been defined as a claim that represents the hash value of access_token.

What is missing is a claim that represents the hash value of the state response parameter. So, “5.1. Introduction” defines s_hash for that purpose.

s_hash
State hash value. Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the state value, where the hash algorithm used is the hash algorithm used in the alg header parameter of the ID Token’s JOSE header. For instance, if the alg is HS512, hash the state value with SHA-512, then take the left-most 256 bits and base64url encode them. The s_hash value is a case sensitive string.

Because “Part 2” uses ID tokens as detached signatures, even if client applications don’t need ID tokens for the original usage, they have to send authorization requests that require an ID token. To be exact, they have to include id_token in the response_type request parameter. This is the reason that the second requirement in “5.2.2. Authorization Server” is saying “shall require the response_type values code id_token or code id_token token.

However, because of the section, “5.2.5. JWT Secured Authorization Response Mode”, which was newly added by Implementer’s Draft 2, ID tokens don’t have to be used as detached signatures when JARM is used. It is because the entire set of response parameters is packed into a JWT. This is mentioned later again.

2.2. Part 2: Requirements for Authorization Server

5.2.2. Authorization server” of “Part 2” lists requirements for authorization server.

Part 2: 5.2.2. Authorization server, 1.

shall require the request or request_uri parameter to be passed as a JWS signed JWT as in clause 6 of [OIDC];

The request and request_uri parameters are defined in “6. Passing Request Parameters as JWTs” of OIDC Core. To use these parameters, the first step is to pack request parameters into a JWT. This JWT is called “request object”. An authorization request (1) passes the request object as the value of the request parameter directly or (2) puts the request object somewhere accessible from the authorization server and passes the URI pointing to the location as the value of the request_uri parameter.

Passing a Request Object by Value

Signing a request object is not mandatory in OIDC Core, but signing is mandatory in FAPI Part 2. If request objects are signed, authorization servers can confirm that the request parameters have not been tampered by verifying signatures of the request objects.

To be honest, what surprised me most when I read the FAPI specification for the first time is this requirement. It’s because I knew from my experience it is very hard to implement the request object feature on authorization server side. As the feature is hard to implement and optional in OIDC, there are many authorization server implementations that claim they support OIDC but don’t support request object. Be careful not to choose an authorization server implementation that doesn’t support request object if you want to build a system that supports FAPI Part 2.

Part 2: 5.2.2. Authorization server, 2.

shall require the response_type values code id_token or code id_token token;

To use ID token as detached signature, even if an ID token is not needed for the original usage, id_token must be included in the response_type request parameter.

But, as mentioned in the previous section, id_token doesn’t have to be included in the response_type request parameter when JARM is used. “When JARM is used” is, to be concrete, “when the response_mode request parameter is included and its value is one of query.jwtfragment.jwtform_post.jwt and jwt.

Part 2: 5.2.2. Authorization server, 3.

shall return ID Token as a detached signature to the authorization response;

This requires that an authorization server issue an ID token, but because the previous requirement requires that id_token be included in response_type and so an ID token is issued as a general consequence, this requirement doesn’t have to exist. Like the above requirement, an ID token doesn’t have to be issued when JARM is used (unless the client wants an ID token for the original usage).

Part 2: 5.2.2. Authorization server, 4.

shall include state hash, s_hash, in the ID Token to protect the state value if the client supplied a value for states_hash may be omitted from the ID Token returned from the Token Endpoint when s_hash is present in the ID Token returned from the Authorization Endpoint;

When JARM is used, this requirement doesn’t have to be followed, either.

Part 2: 5.2.2. Authorization server, 5.

shall only issue authorization code, access token, and refresh token that are holder of key bound;

This requirement has a problem.

In the next requirement (Authorization server, 6), MTLS and Token Binding are listed as allowed options for HoK (Holder-of-Key) mechanism. This won’t cause any issue for access tokens and refresh tokens that are issued from a token endpoint. However, This brings up a problem for authorization codes that are issued from an authorization endpoint.

Suppose that MTLS is used as HoK. For this, network communication with an authorization endpoint has to be Mutual TLS. The program that communicates with an authorization endpoint is not a client application but a web browser. As a consequence, network communication between a web browser and an authorization endpoint has to be Mutual TLS. To achieve this, a client certificate needs to be installed into a web browser in advance and the web browser needs to be configured to use the client certificate for communication with the target authorization endpoint.

Part 2, 8.3.2. also states as follows:

When the FAPI client uses [MTLS] or [OAUTB], the authorization code is bound to the TLS channel, any phished client credentials and authorization codes submitted to the token endpoint cannot be used since the authorization code is bound to a particular TLS channel.

Because the specification explicitly states “since the authorization code is bound to a particular TLS channel”, I cannot help interpreting the requirement of Part 2, 5.2.2., 5 in this way.

I found a person who had reached the same interpretation in the group discussing “Consumer Data Right Information Security Profile”.

However, if we adopt this interpretation, we have to (1) install a client certificate into a web browser, (2) make the web browser use the client certificate in the mutual TLS connection to an authorization endpoint, and at the same time, (3) make the client application use the same client certificate in the mutual TLS connection to a token endpoint. The thread of “Issue 31” has reached a conclusion that it is impractical.

The tone of the argument in FAPI WG also seems like “it’s not our intention.”

  • fapi Issue 202: authorization code and refresh token must be holder of key bound

It seems everyone thinks the requirement of Part 2, 5.2.2., 5. has a problem, so probably this requirement will be amended in future.

Part 2: 5.2.2. Authorization server, 6.

shall support [OAUTB] or [MTLS] as a holder of key mechanism;

Token Binding and MTLS can be applied to access tokens and refresh tokens. However, regarding authorization codes, there is the same concern as mentioned above. In “fapi Issue 202”, I suggested that the spec state like “PKCE shall be used as HoK mechanism for authorization codes while MTLS or OAUTB shall be used as HoK mechanism for access tokens and refresh tokens” to solve confusion, inconsistency and contradiction, but it is unclear where the discussion will go.

Part 2: 5.2.2. Authorization server, 7.

shall support user authentication at LoA 3 or greater as defined in [X.1254];

FAPI Part 2 requires LoA 3 or higher for user authentication while FAPI Part 1 requires LoA 2 or higher. The following is the definition of LoA 3 excerpted from “6.3 Level of assurance 3 (LoA3)” of X.1254.

At LoA3, there is high confidence in the claimed or asserted identity of the entity. This LoA is used where substantial risk is associated with erroneous authentication. This LoA shall employ multifactor authentication. Any secret information exchanged in authentication protocols shall be cryptographically protected in transit and at rest (although LoA3 does not require the use of a cryptographic-based challenge-response protocol). There are no requirements concerning the generation or storage of credentials; they may be stored or generated in general purpose computers or in special purpose hardware.

For example, a transaction in which a company submits certain confidential information electronically to a government agency may require an LoA3 authentication transaction. Improper disclosure could result in a substantial risk for financial loss. Other LoA3 transaction examples include online access to accounts that allow the entity to perform certain financial transactions, or use by a third party contractor of a remote system to access potentially sensitive client personal information.

Part 2: 5.2.2. Authorization server, 8.

shall support signed ID Tokens;

Because “2. ID Token” of OIDC Core says “ID Tokens MUST be signed”, it is ensured that every ID token is signed. Therefore, this requirement is not necessary.

Part 2: 5.2.2. Authorization server, 9.

should support signed and encrypted ID Token;

Encryption of ID tokens is mentioned in OIDC Core, too. Because this requirement uses “should” instead of “shall”, encryption support is not mandatory.

Part 2: 5.2.2. Authorization server, 10.

shall require that all parameters are present inside the signed request object passed in the request or request_uri parameter;

Actually, OIDC Core does not require that request objects be signed. Because of this requirement, it becomes mandatory to sign request objects to comply with FAPI Part 2.

In addition, it should be noted that a request object must include all request parameters to comply with FAPI Part 2. In OIDC Core, request parameters can be put inside or outside a request object. It is also allowed to put the same request parameters both inside and outside.

Part 2: 5.2.2. Authorization server, 11.

may support the request object endpoint as described in section 7;

7. Request object endpoint” of “Part 2” defines a new endpoint called “request object endpoint”. Request objects can be registered at the endpoint and the endpoint issues unique URIs which point to the registered request objects. Client applications can use the URIs as a value of the request_uri request parameter.

Part 2: 5.2.2. Authorization server, 12.

shall require [RFC7636] with S256 as the code challenge method for public clients only, if it supports public clients;

That is, public clients must include code_challenge_method=S256 in authorization requests.

Part 2: 5.2.2. Authorization server, 13.

shall require the request object to contain an exp claim; and

OIDC Core does not require that request objects include the exp claim. In contrast, FAPI Part 2 requires exp as a mandatory claim.

Part 2: 5.2.2. Authorization server, 14.

shall authenticate the confidential client at the token endpoint using one of the following methods (this overrides FAPI part 1 clause 5.2.2.4):

1. Mutual TLS for OAuth Client Authentication as specified in section 2 of [MTLS];

2.private_key_jwt as specified in section 9 of [OIDC];

It should be noted that client_secret_jwt is not allowed in Part 2. This is different from Part 1.

Client Authentication Methods in FAPI

2.3. Part 2: Requirements for Public Client

5.2.3. Public client” of “Part 2” lists requirements for public clients. The requirements are positioned as additions to the requirements listed in “Part 1”.

Part 2: 5.2.3. Public client, 1.

shall support [OAUTB] or [MTLS] as a holder of key mechanism; Note: [MTLS] shall be used with instance-specific keys and (self-signed) certificates to bind access tokens to the particular instance of a public client. It is NOT used as client authentication mechanisms.

Before reading this sentence, it is necessary to understand the difference between using a client certificate for client authentication (MTLS, 2. Mutual TLS for OAuth Client Authentication) and using a client certificate for HoK (MTLS, 3. Mutual TLS Client Certificate-Bound Access Tokens).

Part 2: 5.2.3. Public client, 2.

shall include the request or request_uri parameter as defined in Section 6 of [OIDC] in the authentication request;

As listed in the list of requirements for authorization server, either the request parameter or the request_uri parameter must be included. Note that OIDC Core says “If one of these parameters is used, the other MUST NOT be used in the same request.”

Part 2: 5.2.3. Public client, 3.

shall request user authentication at LoA 3 or greater by requesting the acr claim as an essential claim as defined in section 5.5.1.1 of [OIDC];

When a client wants to require claims as essential ones, the acr_values request parameter cannot be used. Instead, a client must use the claims request parameter, pass JSON as its value, and include {“essential":true} inside the JSON. The following is an example of JSON that needs to be given as the value of the claims request parameter in order to mark urn:mace:incommon:iap:silver as an essential ACR.

Claims for Essential ACR

BTW, this requirement is loosened in UK Open Banking which is based on FAPI Part 2. That is, clients don’t have to require ACRs as essential. Probably, it is not intentional. I guess that the snapshot of FAPI specification which was referred to when Open Banking Profile (OBP) was developed didn’t contain the sentence, “by requesting the acr claim as an essential claim”.

The official Financial-grade API conformance test suite (fapi-conformance-suite) developed and maintained by FinTechLabs.io contains test cases for OBP. When FinTechLabs ran the OBP test cases using Authlete to test the test suite itself, they encountered an error. Because Authlete strictly follows FAPI specification, Authlete reported acr claim is not required as essential.” However, the expected behavior in the context of OBP is to ignore the FAPI requirement.

The right approach for the error was to amend OBP (to make OBP compliant with the latest FAPI specification). However, I was given explanation like “if the official conformance test suite did it, all the existing OBP implementations wouldn’t be able to pass the official tests. Changing the tests at this timing might cause delay in the officially-announced schedule of Open Banking.”

Therefore, I decided to tweak Authlete and added OPEN_BANKING option in addition to FAPI option.

Supported Service Profiles (in Service Owner Console provided by Authlete)

If OPEN_BANKING is enabled, Authlete dare not to check if the acr claim is required as essential even in the context of FAPI Part 2. The code snippet below is the actual implementation excerpted from Authlete’s source code.

Code to judge whether acr should be required as an essential claim

As a result of this, Authlete is listed as a platform vendor that has passed “Open Banking Security Profile Conformance”.

Authlete listed in Open Banking Security Profile Conformance

Part 2: 5.2.3. Public client, 4.

shall require JWS signed ID Token be returned from endpoints;

Part 2: 5.2.3. Public client, 5.

shall verify that the acr claim in an ID Token indicates that user authentication was performed at LoA3 or greater;

Part 2: 5.2.3. Public client, 6.

shall verify that the amr claim in an ID Token contains values appropriate for the LoA indicated by the acr claim;

Part 2: 5.2.3. Public client, 7.

shall verify that the authorization response was not tampered using ID Token as the detached signature

This requirement is not explicitly mentioned in “5.2.5. JWT Secured Authorization Response Mode”, but it can be logically deduced that this requirement doesn’t have to apply when JARM is used.

Part 2: 5.2.3. Public client, 8.

shall send all parameters inside the authorization request’s signed request object

Part 2: 5.2.3. Public client, 9.

shall additionally send duplicates of the parameters/values using the OAuth 2.0 request syntax where required by the OAuth specification

If request parameters are all put into a request object, either the request parameter or the request_uri parameter is enough. However, if parameters that are mandatory in OAuth 2.0 / OIDC Core (e.g. client_id and response_type) are omitted, the request is no longer compliant with OAuth 2.0 / OIDC Core. Therefore, parameters that are mandatory in OAuth 2.0 / OIDC Core must be put outside the request object duplicately even if they exist inside the request object.

In addition to the above requirements from 1. to 9., section 5.2.3. has a sentence at the end. The sentence says as follows:

To verify that the authorization response was not tampered using ID Token as the detached signature, the client shall verify that s_hash value is equal to the value calculated from the state value in the authorization response in addition to all the requirements in 3.3.2.12 of [OIDC].

No. 10 should be assigned to this sentence. I created “fapi Issue 210” to suggest it.

2.4. Part 2: Requirements for Confidential Client

5.2.4. Confidential client” of “Part 2” lists requirements for confidential clients. In addition to the requirements listed in 5.2.3. except ones related to PKCE, confidential clients must follow the requirements below to become compliant with FAPI Part 2.

Part 2: 5.2.4. Confidential client, 1.

shall support [OAUTB] or [MTLS] as a holder of key mechanism (this overrides clause 5.2.3.1); Note: In case of confidential clients, [MTLS] can also be used as client authentication mechanism.

Part 2: 5.2.4. Confidential client, 2.

should require both JWS signed and JWE encrypted ID Tokens to be returned from endpoints to protect any sensitive personally identifiable information (PII) contained in the ID Token provided as a detached signature in the authorization response

The feature of ID token encryption has existed since OIDC Core. When the encryption algorithm for ID tokens is an asymmetric one, the authorization server must either (1) manage public keys of client applications directly in its database or (2) fetch JWK Set documents from the locations pointed to by clients’ jwks_uri metadata and extract public keys from the documents.

For signing ID tokens, it is server-side keys only that an authorization server has to handle.

ID Token Signing

In contrast, if an authorization wants to support encryption of ID tokens, the authorization server has to handle client-side keys, too.

ID Token Encryption

This is the reason that not a small number of authorization server implementations don’t support ID token encryption.

2.5. Part 2: JARM

5.2.5. JWT Secured Authorization Response Mode” of “Part 2” is a section about JARM which has been newly added by Implementer’s Draft 2.

If JARM is used (if one of query.jwtfragment.jwtform_post.jwt and jwt is used as the value of the response_mode request parameter), response parameters are packed into a JWT and the JWT is returned as the value of the response response parameter. Because the JWT is signed by a key of the server, a client can confirm that the response has not been tampered by verifying the signature of the JWT.

In the first version of Implementer’s Draft, “ID token as detached signature” is the only method to detect response tampering. Implementer’s Draft 2 has added JARM as another method. Therefore, section 5.2.5. states as follows:

If [JARM] is used to secure the authorization responses, the clauses 2, 3, and 4 of section 5.2.2. do not apply. For example, clients may use [JARM] in conjunction with the response type code.

In addition to the clauses through 5.2.2.2 to 4., apparently some others also don’t have to apply when JARM is used. For example, the clause of 5.2.3. Public client, 7. which says “shall verify that the authorization response was not tampered using ID Token as the detached signature.” The specification will be amended so that it can be more consistent.

2.5.1. Client Metadata for JARM

Client applications have to set a value to the authorization_signed_response_alg metadata in advance before using JARM. The metadata represents an algorithm for signature of response JWTs. If the value of the response_mode request parameter is *.jwt although the metadata is not set, the authorization request fails because the specification requires response JWTs be always signed.

To encrypt response JWTs, algorithms have to be set in advance to the authorization_encrypted_response_alg metadata and the authorization_encrypted_response_enc metadata. To use an asymmetric algorithm, configuration about client’s public key is necessary, too.

The screenshot below is client-side settings for JARM in Authlete’s web console that is provided for client management.

Authorization Response Algorithms (in Developer Console provided by Authlete)

2.5.2. Server Metadata for JARM

Discovery information of authorization servers that support JARM includes one or more of query.jwtfragment.jwtform_post.jwt and jwt in the list of supported response modes (response_modes_supported). Also, discovery information includes the following metadata related to algorithms used for response JWTs.

authorization_signing_alg_values_supported — supported algorithms for signing

authorization_encryption_alg_values_supported — supported algorithms for key encryption

authorization_encryption_enc_values_supported — supported algorithms for payload encryption

Discovery information of authorization servers that support JARM completely will include data as shown below.

Server Metadata related to JARM

2.6. Part 2: Request Object Endpoint

When a request object is used in an authorization request, it is passed by value using the request request parameter (OIDC Core, 6.1) or passed by reference using the request_uri request parameter (OIDC Core, 6.2).

To use request_uri, a client application developer prepares a server and puts request objects there. There is an idea to make an authorization server itself host such request objects.

7. Request object endpoint” of “Part 2” defines a new endpoint called “request object endpoint”. It is an endpoint at which client application developers register request objects. After accepting registration of a request object, the endpoint stores it somewhere in the authorization server, issues a URI that can identify the request object, and returns a JSON that contains the URI.

The following are examples of a request and a response listed in “7.2. Request” and “7.3. Successful response”. Pay attention to the request_uri claim in the response.

Request to and Response from Request Object Endpoint

Discovery information of authorization servers that support Request Object Endpoint includes metadata named request_object_endpoint.

2.7. Part 2: Security Considerations

8. Security considerations” of “Part 2” lists security considerations. Summary is as follows.

8.1 — This specification references security considerations in section 10 of RFC 6749 and RFC 6819.

8.2 — Protected resource endpoints shall accept only certificate-bound or token-bound access tokens.

8.3.1 — Clients should use a different redirect URI per authorization server.

8.3.2 — Authorization codes and client secrets are passed to attackers if developers are deceived into using a fake token endpoint.

Section 8.3.2 includes the following sentence.

When the FAPI client uses [MTLS] or [OAUTB], the authorization code is bound to the TLS channel, any phished client credentials and authorization codes submitted to the token endpoint cannot be used since the authorization code is bound to a particular TLS channel.

As discussed for Part2–5.2.2–5, this sentence has a problem and will be amended in future.

8.3.3 — Hybrid flow can be used as a countermeasure for IdP mix-up attack.

8.3.4 — Requests objects containing confidential information are passed to attackers if developers are deceived into using a fake request object endpoint.

8.3.5 — Because access tokens are bound to TLS channels in FAPI Part 2, attackers cannot use stolen access tokens.

8.4.1 — RFC 6749 doesn’t assure message integrity of authorization request and response.

8.4.2 — Using request objects prevents authorization request parameter injection attack.

8.4.3 — Using hybrid flow prevents authorization response parameter injection attack.

2.8. Part 2: TLS Considerations

8.5. TLS considerations” of “Part 2” permits only the following cipher suites for TLS communication.

  1. TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
  2. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  3. TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
  4. TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

But, from a viewpoint of interoperability of web browsers, additional cipher suites allowed in the latest BCP 195 are permitted for authorization endpoints.

Well, because I couldn’t find any good reasons to exclude the following cipher suites,

5. TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

6.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

I created Issue 216 (TLS_ECDHE_ECDSA cipher suites) to suggest adding them to the list of permitted cipher suites.

2.9. Part 2: JWS Algorithm Considerations

Signing algorithms of JWS are listed in “3.1. “alg” (Algorithm) Header Parameter Values for JWS” of RFC 7518 (JSON Web Algorithms). Among the 13 algorithms, “8.6. JWS algorithm considerations” of “Part 2” permits PS256 and ES256 only. The section explicitly states that RSASSA-PKCS1-v1_5 (e.g. RS256) should not be used and none must not be used.

JWS algorithms permitted by Financial-grade API, Part 2

JWT is used at the following places in an authorization server implementation.

JWT Usage in Authorization Server Implementation

Personally, I think there is room for discussion as to whether the JWT algorithm restriction applies to UserInfo response. However, apparently, client_assertion, ID token, request object and authorization response are affected by the restriction.

Regarding backchannel authentication request, we have to watch discussion about “CIBA FAPI profile” in MODRNA Working Group.


3. FAPI implementation

This chapter picks up some topics related to FAPI implementation.

3.1. Read-Only or Read-and-Write?

For authorization requests and token requests to get an access token to access read-only APIs and for the APIs themselves hosted on resource servers, FAPI Part 1: Read-Only API Security Profile applies.

Likewise, for authorization requests and token requests to get an access token to access read-and-write APIs and for the APIs themselves hosted on resource servers, FAPI Part 2: Read and Write API Security Profile applies.

APIs hosted on resource servers know whether they themselves are read-only APIs or read-and-write APIs. Therefore, it is apparent for the API implementations which security profile they should follow.

On the other hand, how does the authorization endpoint of an authorization server judge whether an incoming request is for read-only APIs or for read-and-write APIs, or for APIs irrelevant to FAPI?

Actually, FAPI specification mentions nothing about how to judge.

A simple solution would be “Regard all authorization requests as ones for read-and-write APIs.” Actually, UK Open Banking has adopted this approach. A hard-coded implementation like this may be acceptable if the system development is a one-time work.

However, this approach is not appropriate for a generic authorization server implementation. It’s because a hard-coded implementation hinders flexibility of system design too much. Therefore, in a generic implementation, it is better to judge dynamically at runtime whether an authorization request is for FAPI read-only or for FAPI read-and-write (or for normal OAuth 2.0 / OIDC).

If so, how to judge dynamically? The conclusion everyone will eventually reach after thinking will be just one. It is judged by checking the requested scopes.

(Note: Another possible way would be to utilize the resource request parameter defined in “Resource Indicators for OAuth 2.0”, but I’m not sure whether the specification can gain strong support from the community.)

For example, (1) prepare scopes named read and write, (2) adopt a rule which requires the read scope for read-only APIs and the write scope for read-and-write APIs, and (3) implement APIs so. If APIs are implemented in this way, the implementation of an authorization endpoint can change its behavior dynamically by (a) applying FAPI Part 2 requirements when the scope request parameter includes the write scope, (b) applying FAPI Part 1 requirements when the scope request parameter does not include the write scope but includes the read scope, and (c) applying normal OAuth 2.0 and OIDC requirements when the scope request parameter includes neither the read scope nor the write scope.

How to implement the scope-based switch? For example, regard scopes whose name starts with read as scopes for read-only APIs? However, this approach imposes heavy restrictions on scope names. So, what is the approach Authlete has adopted?

First, Authlete implemented a generic mechanism to set arbitrary attributes to each scope. On the mechanism, Authlete treats the attribute name fapi in a special way. An attribute having name fapi and value r represents Read-Only. Likewise, an attribute having name fapi and value rw represents Read-and-Write.

The web console for FAPI-aware Authlete (version 2.0+) provides UI for scope attributes. The screenshot below defines a scope named read with an attribute of fapi=r.

Scope Settings for FAPI Read-Only

/api/auth/authorization, an Authlete API that parses an authorization request, checks scopes listed in the scope request parameter in the authorization request and regards the request as a request for FAPI Read-and-Write APIs if the scope list includes a scope that has an attribute of fapi=rw. If the scope list does not include any scope having an attribute of fapi=rw but includes a scope having an attribute of fapi=r, the authorization request is regarded as a request for FAPI Read-Only APIs. In other cases, the authorization request is treated as a normal OAuth 2.0 / OIDC request.

3.2. Mutual TLS

“Mutual TLS” has three meanings as listed below (as already explained previously).

  1. TLS communication using a client certificate
  2. Client authentication using a client certificate
  3. Certificate binding

The first part is handled by API management solutions. On the other hand, the second and the third parts don’t necessarily have to be handled by API management layer. Rather, a better system architecture would build them as systems independent from each other.

Because of its unique architecture, Authlete doesn’t take on any task in API management layer. That is, Authlete does nothing for the first part. On the other hand, Authlete supports the second and the third parts. Thanks to this, with Authlete, systems can support MTLS (OAuth 2.0 Mutual TLS Client Authentication and Certificate Bound Access Tokens) required by FAPI on any API management solution that developers want to use. Actually, it has already been confirmed that MTLS can be supported on Azure API Management and Apigee with Authlete. I’ve not tried AWS API Gateway yet, but any API management solution can support MTLS by using Authlete as long as it provides a mechanism which enables developers to access the client certificate used in TLS communication.

I’m afraid it would take time for existing API management solutions to implement MTLS directly. Above all, it is not a good system design to support the functionality directly in API management layer. At the time of this writing, if you use an API management solution provided by one of giant cloud vendors, Authlete is the best answer to support Financial-grade API.

The video below is a session in “Financial APIs Workshop” that took place in Tokyo on July 24, 2018. In the video, Justin Richer, one of the most famous software engineers in the community and the author of “OAuth 2 in Action”, is explaining Authlete’s MTLS implementation.

The presentation material used in the session is available here on SlideShare.

3.3. Access Token Duration

This is not related to FAPI, but I explain this feature here because I’m often consulted about the feature in the context of Bank API by customers who want to make duration of access tokens for remittance shorter than that of access tokens for other purposes.

The functionality can be achieved by making access token duration shorter when an authorization request contains a scope for remittance. For example, if an API for remittance requires a scope named remit, the authorization server would shorten access token duration when an authorization request contains the scope.

Authlete supports the functionality by treating a scope attribute named access_token.duration in a special way.

Authlete checks all scope attributes of requested scopes, picks up the smallest value among values of access_token.duration attributes, and uses it as the duration of an access token being issued. If none of the requested scopes has an access_token.duration attribute, Authlete uses the default value of access token duration set per authorization server instance. If the default value is smaller than the smallest value of access_token.duration attributes, the default value is used.

For example, definition of remit scope setting 300 seconds to access token duration is as follows.

Scope Settings for Access Token Duration

Likewise, duration of refresh tokens can be set by utilizing refresh_token.duration attributes.

3.4. Access Token with Transaction Information

This feature is not related to FAPI, either, but I explain it here as I’m often consulted about it in the context of Bank API by customers who want to associate detailed transaction information with an access token. I hear that some regulations in Europe require an access token be issued per transaction under some conditions.

This functionality cannot be achieved by “scope attribute” explained in “3.3. Access Token Duration”. Handling data per access token is required instead of data per scope.

Since old days, Authlete has provided a mechanism to set arbitrary key-value pairs to an access token. This feature can be utilized to associate transaction information with an access token. Technical details about this feature are explained in “Extra Properties”.

However, note that it is not a smart way to associate detailed information such as amount of money with an access token directly. Instead, a recommended way is to (1) store detailed transaction information into another database and (2) associate the unique identifier of the database record with an access token.

Finally

Thank you for reading this long post till the end.

I’ll give a talk titled “Financial-grade API (FAPI) and CIBA” in DeveloperWeek New York 2019 on June 20. Authlete, Inc. will have a booth at the event. Please come to the event and visit our booth.

Again, please contact Authlete, Inc. (sales@authlete.com) if you are interested in the world’s first certified implementation of Financial-grade API OpenID Provider.

Authlete has offices in Tokyo (FINOLAB) and London (Level39) and is thinking of expanding to other countries

About the Author

Takahiko Kawasaki  Takahiko Kawasaki is co-founder and representative director of OpenID Foundation member, Authlete, Inc.