# API Authentication
source: https://developer.mastercard.com/open-finance-data/documentation/api-basics/authentication/index.md

Note: This API is currently available for Sandbox testing. [Contact us](mailto:openbankingeu_support@mastercard.com%3E) for details of Production environment availability.

Mastercard Open Finance uses [OAuth 2.0 authorization](https://datatracker.ietf.org/doc/html/rfc6749#page-1) framework with [Client Credentials Grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4). In this flow, the Integrator needs to authenticate towards the Authorization Server to gain an Access Token that will be used to access the API.

A description of the steps necessary to implement the authentication is detailed below.

## 1: Generate asymmetric cryptography keys {#1-generate-asymmetric-cryptography-keys}

As a pre-requisite, you need to generate an asymmetric cryptography public-private key pair and certificate.

When you authenticate on our authorization server, we want to make sure that only you can obtain access tokens for your clientId. For that we will validate that your requests are signed with a private key that only you have.

At the moment we only support RSA keys. We recommend an RSA key of 4096 bits of length and valid for at least one year. In the future, you will need to provide a new certificate to us before this expires, or face possible downtime in your applications.

#### Example {#example}

For testing, you can use [OpenSSL](https://openssl-library.org/) to generate these.

Write the following in the terminal:

    openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout private.key -days 730 -out public.pem

This will create two files:

* private.key: The private key used for signing the JWT.
* public.pem: The public certificate that can be used to verify the JWT.

Note: **Do not share your Private Key.** Store the Private Key securely and use it to sign your JWT token before requesting an access token from us (find more details in the sections below).  
You will need to share the public certificate with us (see below).

In a production environment, we suggest generating the private key in an HSM or similar, exporting the public key and sharing that with us.

## 2: Share the Public Certificate with us {#2-share-the-public-certificate-with-us}

Before you can start using the Mastercard Open Finance authentication we need to add your Public Certificate to our list of trusted certificates. Please contact your onboarding officer.
Note: It is important to note that self-signed certificates are only supported in our Sandbox/MTF environment. When you are ready to move to Production, you will need to acquire a certificate from a supported Certificate Authority (CA). For more information, refer to [Moving to Production](https://developer.mastercard.com/open-finance-data/documentation/api-basics/authentication/index.md#moving-to-production).

After that, you can call the `oauth2/token` endpoint to obtain an access token, necessary to use the Mastercard Open Finance Data API.
* Sandbox
* Production

```Sandbox
https://mtf.auth.openbanking.mastercard.eu/oauth2/token
```

```Production
https://auth.openbanking.mastercard.eu/oauth2/token
```

## 3: Generate and sign the JWT token {#3-generate-and-sign-the-jwt-token}

You will need to populate the `client_assertion` field with a JWT used by the Auth Service for verifying the caller. The details necessary to generate and sign the JWT token are shown below.

The JSON Web Token (JWT) is an open standard ([RFC7519](https://datatracker.ietf.org/doc/html/rfc7519)) that allows transmitting security information between two parties in a compact way as a JSON object.

In this documentation, we will cover how to generate a JWT with specific claims, sign it using a certificate generated by OpenSSL, and provide a C# example for the implementation.

### The JWT format {#the-jwt-format}

JWT consists of three parts: a header, a payload, and a signature.

#### The JWT header {#the-jwt-header}

The header specifies the type of token (JWT) and the signing algorithm (RS256) along with the kid of the certificate.

**Example**

```json
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "<thumbprint-of-certificate>"
}
```

The `kid` (Key ID) is a unique identifier for the public certificate that you shared with us.
This is the SHA-256 thumbprint of the certificate in base64url encoding.

#### The JWT Payload {#the-jwt-payload}

The JWT Payload must have the following claims:

| **Field** |    **Name**     |    **Type**    |                                     **Description**                                      |
|-----------|-----------------|----------------|------------------------------------------------------------------------------------------|
| `sub`     | Subject         | string         | The ID of the client. This is the ID that you receive during onboarding your Integrator. |
| `iss`     | Issuer          | string         | The ID of the client (must be the same value as "Subject").                              |
| `exp`     | Expiration time | Unix timestamp | The expiration time of the JWT. Must be a date in future.                                |
| `aud`     | Audience        | string         | The audience of the JWT. Must be set to "auth.mastercard.com".                           |
| `jti`     | JWT ID          | string         | Must be a unique GUID per request.                                                       |

**Example**

```json
{
  "sub": "<client-id>",
  "iss": "<client-id>",
  "exp": 1723125616,
  "aud": "auth.mastercard.com",
  "jti": "27edbf3f-c5a1-460d-8248-0af06f93200b"
}
```

#### The JWT Signature {#the-jwt-signature}

To understand how this works, you can use [JWT.io](https://jwt.io/) and the pair of public certificate with private key in order to quickly sign a JWT. Make sure to use the right algorithm (RS256). To sign the JWT, you only need to provide the private key. If you want to validate that the signing went correctly, you can provide the public certificate as well, and you should see the "Signature verified" text.

### Example: Generate JWT and Sign with Private Key using C# {#example-generate-jwt-and-sign-with-private-key-using-c}

Below is a C# example for generating a JWT. The signed JWT should then be passed as the client_assertion to the oauth2/token endpoint.
Tip: This code serves to illustrate the core functionality. Make sure to add proper error handling, logging, validation, removing hardcoded values, and unit test it before putting it into production.

```C#
public string CreateJwtToken()
{
    // Create the RSA security key from the private key          
    var privateKey = File.ReadAllText("path/to/your/private.key");

    using var rsa = RSA.Create();
    rsa.ImportFromPem(privateKey);
    var rsaSecurityKey = new RsaSecurityKey(rsa)
    {
        KeyId = GetKidFromCertificate()
    };

    // Define token parameters
    var tokenHandler = new JwtSecurityTokenHandler();

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, "<client-id>"),
            new Claim(JwtRegisteredClaimNames.Iss, "<client-id>"),
            new Claim(JwtRegisteredClaimNames.Aud, "auth.mastercard.com"),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        }),
        Expires = DateTime.UtcNow.AddHours(1),
        SigningCredentials = new SigningCredentials(rsaSecurityKey, SecurityAlgorithms.RsaSha256)
    };

    // Create the JWT token
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}
```

The above example calls a private method to add the key id. Mastercard Open Finance calculates the expected KID as follows, so your implementation should be functionally equivalent:

```C#
private static string GetKidFromCertificate()
{
    const string pemCertPath = "path/to/your/certificate.pem";
    var pemContent = File.ReadAllText(pemCertPath);

    // Remove PEM headers/footers and whitespace
    var cleanedPem = pemContent
        .Replace("-----BEGIN CERTIFICATE-----", "")
        .Replace("-----END CERTIFICATE-----", "")
        .Replace("\r", "")
        .Replace("\n", "")
        .Replace(" ", "")
        .Replace("\t", "");

    // Compute SHA-256 hash
    var certBytes = Convert.FromBase64String(cleanedPem);
    var hash = SHA256.HashData(certBytes);

    // Convert to base64url encoding
    var base64 = Convert.ToBase64String(hash);

    return base64.TrimEnd('=')
        .Replace('+', '-')
        .Replace('/', '_');
}
```

## 4: Request an access token {#4-request-an-access-token}

Once you have the JWT token signed, you can call Authentication Service in order to obtain a Mastercard Open Finance Access Token.

Note that you need to use the following URL for the Authentication Service endpoints:

`POST /oauth2/token`

Find below details on how to populate the fields:

|        **Field**        |                                                                                                                                 **Description**                                                                                                                                 |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `grant_type`            | Set to client_credentials grant type.                                                                                                                                                                                                                                           |
| `client_assertion_type` | Set to JWT Bearer Token assertion type                                                                                                                                                                                                                                          |
| `client_assertion`      | Set to the signed JWT bearer token you created in previously.                                                                                                                                                                                                                   |
| `scope`                 | There are three possible values that you can set here - `ob_data`, `ob_providers`, and `ob_theming`. We also support setting multiple scopes. You can do this by passing an array indicating all of the scopes you want to use. Example: `"scope": ["ob_data", "ob_providers"]` |

Note: You cannot reuse a JWT after you already used it to obtain an Access Token.

In response, you will receive the following:

|   **Field**    |                                                 **Description**                                                 |
|----------------|-----------------------------------------------------------------------------------------------------------------|
| `access_token` | Set to client_credentials grant type.                                                                           |
| `token_type`   | The type of the Access Token. This is always "bearer".                                                          |
| `expires_in`   | This is the Access Token that you need to use as a bearer token in all API requests to Mastercard Open Finance. |

## 5: Use the access token to access the API {#5-use-the-access-token-to-access-the-api}

Send the Access Token that you received above as a bearer token (Authorization header) in each API request to us to enable us to validate your access.

**Accessing the API example**

    GET /consents/d4ed1ee2-bf8e-4611-8507-55f4c410ce25 HTTP/1.1
    Host: mtf.api.openbanking.mastercard.com
    Content-Type: application/json
    Authorization: Bearer <Access Token>

## Managing the access tokens {#managing-the-access-tokens}

The Access Tokens issued by Mastercard Open Finance have an expiration period. The expiration period is set to 1 hour. Note that this value may change in the future.

Always check the value in `expires_in` property of the received access token to understand the validity period. You will need to generate and sign a new JWT token and request a new Access Token when the current one expires.

## Updating your Keys {#updating-your-keys}

If your Public Certificate is due to expire, or your Private Key has been compromised, you will need to generate a new private-public key pair. For this go through the same steps as above.
Note: Begin signing your JWTs with your new Private Key only after confirmation that your new Public Certificate has been added to our trusted certificates.

## Moving to Production {#moving-to-production}

Once you are ready to make the move from testing in our Sandbox/MTF environment to our Production environment, it is essential that you acquire an SSL/TLS OV certificate from one of our Supported Certificate Authorities. Once you have received your certificate, you can contact your onboarding officer for more information on how to proceed.

Supported Certificate Authorities:

* DigiCert
* GoDaddy
* NETS AS
* VeriSign
