Singpass Developer Docs
Legacy Myinfo v3/v4
Legacy Myinfo v3/v4
  • Legacy Myinfo v3/v4
  • Data Catalog
  • Key Principles
  • Technical Specifications
    • Myinfo v4
      • Difference between v3 and v4
      • Technical Guidelines
      • Technical Concepts
        • OAuth 2.1 Concepts
        • Proof of Key Code Exchange (PKCE)
        • JSON Web Token (JWT)
        • Client Assertions
        • JSON Web Key Store (JWKS)
        • Demonstration of Proof-of-Possession (DPoP)
      • API Specifications
      • Tutorials
        • Tutorial 1: Myinfo Person sample Data
        • Tutorial 2: End-to-end Integration with Myinfo v4 APIs
      • Resources
        • Myinfo Connectors
        • Error Codes
      • FAQ
    • Myinfo v3
      • Technical Guidelines
      • API Specifications
      • Latest X.509 Public Key Certificate
      • Tutorials
        • Tutorial 1: Basic Person API
        • Tutorial 2: Using OAuth2
        • Tutorial 3: Implementing PKI Digital Signature
      • Resources
        • Myinfo Connectors
        • Error Codes
      • FAQ
Powered by GitBook
On this page

Was this helpful?

  1. Technical Specifications
  2. Myinfo v4
  3. Technical Concepts

Client Assertions

PreviousJSON Web Token (JWT)NextJSON Web Key Store (JWKS)

Last updated 1 month ago

Was this helpful?

A client assertion is a JWT directly produced by a client application using a cryptographic key and presented as proof of the client's identity. (Refer to )

Client Assertions provide a strong method of authenticating clients before returning an access_token for them to access the data.

  1. Client application invoke the Token API with a JWT client_assertion.

  2. AuthZ server will retrieve the client's trusted public key (JWK) from the client's onboarded JWKS URI. (As the JWKS endpoint only exposes public information, it does not need securing)

  3. AuthZ server will verify the signature of the client_assertion by extracting the matching public key from the client's JWKS with reference to the kid field in the client_assertion JWT header.

  4. AuthZ server returns the JWT access_token.

  5. Client application will retrieve AuthZ's trusted public key (JWK) from AuthZ's JWKS URI.

  6. Client application will verify the signature of the access_token by extracting the matching public key from AuthZ's JWKS with reference to the kid field in the access_token JWT header.

JSON Web Key (JWK) is a JSON object that represents a cryptographic public key that can be used to validate the signature of a signed JSON Web Token (JWT).

JSON Web Key Set (JWKS) is composed of 1 or more JSON Web Keys (JWK) in an array format.


Generate Client Assertion

An example JWT client assertion is shown below.

{
    "typ": "JWT",
    "alg": "ES256",
    "kid": "x0zDLIC9yNRIXu3gW8nTQDOMNe7sKMAjQnZj3AWTW2U"
}.
{
    "sub": "PROD2-MYINFO-SELF-TEST",
    "jti": "jNDZuyLw66gkTjmCNMawzrTJNlhS8wdjpU0DHTzo",
    "aud": "https://api.myinfo.gov.sg/com/v4/token",
    "iss": "PROD2-MYINFO-SELF-TEST",
    "iat": 1662365106,
    "exp": 1662365406,
    "cnf":{
        "jkt": "G_q8Qv9-xv_9xJo-esolTnvxVSobMER7O0LKGPBlTqY"
    }
}.
[signature]
PARAMETER
DESCRIPTION

sub

Subject - client_id issued by Myinfo upon onboarding

jti

JWT ID - random unique identifier

aud

Audience - URL that client application is calling

iss

Issuer - client_id issued by Myinfo upon onboarding

iat

Issued At - current timestamp

cnf.jkt

JWK Thumbprint - base64url encoding of the JWK SHA-256 Thumbprint of the client's ephemeral public signing key used to sign the DPoP Proof JWT

Sample Code:

// jktThumbprint: base64url encoding of the JWK SHA-256 Thumbprint of the client's ephemeral public signing key used to sign the DPoP Proof JWT
     
    async function generateClientAssertion (url, clientId, privateSigningKey, jktThumbprint) => {
      let now = Math.floor((Date.now() / 1000));
     
      let payload = {
        'sub': clientId,
        'jti': generateRandomString(40),
        'aud': url,
        'iss': clientId,
        'iat': now,
        'exp': now + 300,
        'cnf' : {
          'jkt': jktThumbprint
        }
      };
      let jwsKey = await jose.JWK.asKey(privateSigningKey, 'pem');
     
      let jwtToken = await jose.JWS.createSign({ 'format': 'compact', 'fields': { 'typ': 'JWT' } }, jwsKey).update(JSON.stringify(payload)).final();
      return jwtToken;
    };

The client_assertion is produced by generating the JSON payload and signing it with a private key. The signing and headers are produced by a JWT security library which uses a private key in JWK format.

The claims (Refer to ) expected in the signed assertion are:

https://www.rfc-editor.org/rfc/rfc7519#section-4.1
https://datatracker.ietf.org/doc/html/rfc7521