Client authentication using private_key_jwt

Description of the ACP private_key_jwt based authentication flow

JWTs in a nutshell

JSON Web Tokens are an open standard that defines a compact and secure way of transmitting data between parties using a JSON object. Such information can be digitally signed with a secret (using the Hash Message Authentication Code (HMAC) algorithm) or a public and private key pair (using RSA or ECDSA), therefore it can be trusted and verified.

JWTs consist of three parts separated by dots:

  • Header that consists of two parts:

    • Type of the token (JWT)

    • Signing algorithm being used (HMAC, RSA, or ECDSA)

  • Payload with claims.

    Note

    Although JWTs are protected against tampering with them, they are readable by anyone. You should not store sensitive data inside the header and payload elements unless it is encrypted.

  • Signature which is used to verify if a token has not changed along the way and, when using a private key, that the sender of JWT is who it says it is. For the private_key_jwt method, a signature is made using an asymmetric keypair (a private and public keys).

JWT example

{
  "alg": "RS256",
  "typ": "JWT"
}

encoded to:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

Payload

{
  "client_id": "YzEzMGdoMHJnOHBiOG1ibDhyNTA=",
  "response_type": "code",
  "scope": "introscpect_tokens, revoke_tokens",
  "iss": "bjhIRjM1cXpaa21zdWtISnp6ejlMbk44bTlNZjk3dXE=",
  "sub": "YzEzMGdoMHJnOHBiOG1ibDhyNTA=",
  "aud": "https://localhost:8443/{tid}/{aid}/oauth2/authorize",
  "jti": "1516239022",
  "exp": "2021-05-17T07:09:48.000+0545"
}

encoded to:

eyJjbGllbnRfaWQiOiJZekV6TUdkb01ISm5PSEJpT0cxaWJEaHlOVEE9IiwicmVzcG9uc2Vf
dHlwZSI6ImNvZGUiLCJzY29wZSI6ImludHJvc2NwZWN0X3Rva2VucywgcmV2b2tlX3Rva2Vu
cyIsImlzcyI6ImJqaElSak0xY1hwYWEyMXpkV3RJU25wNmVqbE1iazQ0YlRsTlpqazNkWEU9
Iiwic3ViIjoiWXpFek1HZG9NSEpuT0hCaU9HMWliRGh5TlRBPSIsImF1ZCI6Imh0dHBzOi8v
bG9jYWxob3N0Ojg0NDMve3RpZH0ve2FpZH0vb2F1dGgyL2F1dGhvcml6ZSIsImp0aSI6IjE1
MTYyMzkwMjIiLCJleHAiOiIyMDIxLTA1LTE3VDA3OjA5OjQ4LjAwMCswNTQ1In0

Signature

RSASHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload), public key, private key
)

encoded to:

IxvaN4ER-PlPgLYzfRhk_JiY4VAow3GNjaK5rYCINFsEPa7VaYnRsaCmQVq8CTgddihEPPXe
t2laH8_c3WqxY4AeZO5eljwSCobCHzxYdOoFKbpNXIm7dqHg_5xpQz-YBJMiDM1ILOEsER8A
DyF4NC2sN0K_0t6xZLSAQIRrHvpGOrtYr5E-SllTWHWPmqCkX2BUZxoYNK2FWgQZpuUOD55H
fsvFXNVQa_5TFRDibi9LsT7Sd_az0iGB0TfAb0v3ZR0qnmgyp5pTeIeU5UqhtbgU9RnUCVmG
IK-SZYNvrlXgv9hiKAZGhLgeI8hO40utfT2YTYHgD2Aiufqo3RIbJA

Full JSON Web Token

Extra line breaks are added for display purposes.

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
eyJjbGllbnRfaWQiOiJZekV6TUdkb01ISm5PSEJpT0cxaWJEaHlOVEE9IiwicmVzcG9uc2Vf
dHlwZSI6ImNvZGUiLCJzY29wZSI6ImludHJvc2NwZWN0X3Rva2VucywgcmV2b2tlX3Rva2Vu
cyIsImlzcyI6ImJqaElSak0xY1hwYWEyMXpkV3RJU25wNmVqbE1iazQ0YlRsTlpqazNkWEU9
Iiwic3ViIjoiWXpFek1HZG9NSEpuT0hCaU9HMWliRGh5TlRBPSIsImF1ZCI6Imh0dHBzOi8v
bG9jYWxob3N0Ojg0NDMve3RpZH0ve2FpZH0vb2F1dGgyL2F1dGhvcml6ZSIsImp0aSI6IjE1
MTYyMzkwMjIiLCJleHAiOiIyMDIxLTA1LTE3VDA3OjA5OjQ4LjAwMCswNTQ1In0.
IxvaN4ER-PlPgLYzfRhk_JiY4VAow3GNjaK5rYCINFsEPa7VaYnRsaCmQVq8CTgddihEPPXe
t2laH8_c3WqxY4AeZO5eljwSCobCHzxYdOoFKbpNXIm7dqHg_5xpQz-YBJMiDM1ILOEsER8A
DyF4NC2sN0K_0t6xZLSAQIRrHvpGOrtYr5E-SllTWHWPmqCkX2BUZxoYNK2FWgQZpuUOD55H
fsvFXNVQa_5TFRDibi9LsT7Sd_az0iGB0TfAb0v3ZR0qnmgyp5pTeIeU5UqhtbgU9RnUCVmG
IK-SZYNvrlXgv9hiKAZGhLgeI8hO40utfT2YTYHgD2Aiufqo3RIbJA

Note

The JWT MUST be digitally signed. ACP rejects JWTs with invalid signatures.

private_key_jwt authentication flow

One of the methods of client authentication supported by ACP is using the private_key_jwt. This method uses a client-generated JWT signed with an asymmetric key to confirm the client’s identity. ACP can extract client assertion from the request and verify it with the public key.

Used standards

ACP processes requests for client authentication using the following standards:

Prerequisites

  1. The client is registered with the private_key_jwt method as the token authentication method.

  2. A public and a private key pair set is prepared on the client-side.

  3. The client’s public key is converted from the PEM format to a jwks (JSON Web Key Set)

    Note

    You can put your jwks on a server of your choice to enable using jwks_uri.

  4. jwks or jwks_uri public key is added to ACP in the client’s Oauth configuration.

Process

  1. The client prepares a JSON with the request data.

    Example

    {
    "iss" : "YzEzMGdoMHJnOHBiOG1ibDhyNTA=",
    "sub" : "YzEzMGdoMHJnOHBiOG1ibDhyNTA=",
    "aud" : "https://localhost:8443/{tid}/{aid}/oauth2/authorize",
    "jti" : "1516235555",
    "exp" : "2021-05-17T07:09:48.000+0545" }
    
  2. Prepared data is signed using the private key.

    Result

    A JSON Web Token is created.

  3. The client makes a request for an access token to the token endpoint including the following parameters:

    parameter value type
    client_assertion_type urn:ietf:params:oauth:client-assertion-type:jwt-bearer Required
    client_assertion Must contain a single JSON Web Token. Required
    grant_type Type of the grant used, for example, client_credentials Required

    Request example

    Extra line breaks are added for display purposes.

    curl --request
    -F "grant_type=client_credentials"
    -F "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
    -F "client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.
    eyJpc3N1ZXIiOiJZekV6TUdkb01ISm5PSEJpT0cxaWJEaHlOVEE9Iiwic3ViamVjdCI6Ill6RXpN
    R2RvTUhKbk9IQmlPRzFpYkRoeU5UQT0iLCJzY29wZSI6ImludHJvc2NwZWN0X3Rva2VucywgcmV2
    b2tlX3Rva2VucyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMve3RpZH0ve2FpZH0vb2F1
    dGgyL2F1dGhvcml6ZSIsImp3dElEIjoiMTUxNjIzOTAyMiIsImV4cGlyYXRpb25UaW1lIjoiMjAy
    MS0wNS0xN1QwNzowOTo0OC4wMDArMDU0NSJ9.
    PkkBvc1oPLdSXCqKdf5r2-is51CFvLVbdM9GYmzRvGqnxFK7MyKgSEqA0wZzC0rc8q7TAx2AwpFQ
    E-Ea1MKQEW1qViyl2MwUcbg8QHN1dSZez_eMpmQiQUiIuZKJYbrjlbKypXPCGcTL8YVkDrA2F6ny
    El1BpVvT8s-yeQX7VpfiKcKHApF0d_jnDizGCpwxnsSlobgjXRftMKoeyChKnF3y-KI33LrcP3n-
    Mvr9Y12vN39PV4JTzcBSqU4g8rjDtPt2Z1swXjEO4X6DQmso5L09a_Wb7vf9umaOJfP3luye7Uyj
    4fMTCNchZu0pFxq98-Dq13rdiXHOGsV0f0SkJw"  POST \
    --url <https://localhost:8443/{tid}/{aid}/oauth2/token> \
    --header 'accept: application/x-www-form-urlencoded'
    
  4. ACP generates an access token and provides it to the client after a successful request validation.

    ACP can extract the client’s assertion and verify it using the public key.

Result

The client is authenticated using the private_key_jwt flow.

When to use

In general, client authentication using the private_key_jwt method should be used by companies that need to use secure client authentication flows. This may be the case, for example, for businesses that must comply with the Financial-Grade API (FAPI) standards.

Info

FAPI is an industry-led specification of JSON data schemas, security and privacy protocols that were designed mostly for commercial and investment banking accounts, or insurance, and credit card accounts.