4. Parsing the ID Token

The ID token returned during token exchange is a JSON Web Signature (JWS), which is also encrypted using JSON Web Encryption (JWE). The JWE and JWS components are represented using compact serialization form, as specified in section 3.1 of RFC 7516.

To reduce complexity, we recommend that you use a JWT parsing library to decrypt the token and to verify the signature, instead of implementing the decryption and signature verification yourself. You may refer to this list to look for a suitable JWT library for your programming language, though you must also ensure that your library of choice supports decryption of JWTs encrypted using JWE.

JWT Claims

The decrypted JWT will have the following claims:

Claim
Description
Data Type

sub

The principal that is the subject of the JWT. Contains a globally unique identifier for the user.

String

sub_type

A property to describe what is the type of the subject of the JWT.

For Singpass, this is always the string "user"

sub_attributes

This contains some information related to the user's identifiers. This is only returned if the user.identity , name, email, or mobileno scope is requested.

Object containing key-value pairs. See the section below for full details.

act

An object describing actor acting on behalf of the sub. This is currently unused, but this may be used in the future for delegation (e.g. a child acting on behalf of their parent, or vice-versa). This object will contain a sub claim, which contains the UUID of the actor. If the user.identity , name, email, or mobileno scope is requested, it will also contain the respective data for the actor in the sub_attributes claim. If the sub_attributes claim is returned, the format of sub_attributes is described in the section below.

An object containing sub and sub_attributes (if requested).

aud

The client ID of your registered client, provided by Singpass during app onboarding.

A 32-character case-sensitive alphanumeric string.

iss

The issuer identifier of our authorization server.

String

iat

The unix timestamp, in seconds, at which we issued this JWT.

Number

exp

The unix timestamp, in seconds, on or after which this JWT must not be accepted for processing.

Number

amr

An array of authentication method references. This refers to the form factors used by the user to authenticate themselves. The array will contain all the form factors used for this authentication. For example, if the user authenticated themselves using their password and SMS OTP, then this array will contain both pwd and otp-sms.

Array of strings. The possible values are:

  • face

  • pwd

  • otp-sms

  • face-alt

  • swk (software key)

  • hwk (hardware key)

Note that this list is non-exhaustive, and we reserve the right to introduce new values without prior notice to you.

nonce

This is the same nonce that you used in your authorization request.

String

Sample ID token
{
  "aud" : "gnY6Erichpb5t4NFRP9R4L7aEC9N0FQH",
  "iss" : "https://id.singpass.gov.sg/fapi",
  "exp" : 1727322545,
  "iat" : 1727321945,
  "nonce" : "L5nmQfcetDDIeincoqvCrFyGv+nHobkv4XocNYPCXaQ=",
  "sub" : "1c0cee38-3a8f-4f8a-83bc-7a0e4c59d6a9",
  "sub_type": "user",
  "sub_attributes": {
    "account_type": "standard",
    "identity_number": "S1234567G",
    "identity_coi": "SG"
  }
}

The sub_attributes Claim

The sub_attributes claim is an object that will contain the following properties:

Property
Description
Data Type

account_type

The Singpass account type for this user.

For Singpass Foreign Account (SFA) holders, this will be "foreign".

For all other Singpass accounts (i.e. those belonging to Singapore Citizens, Permanent Residents, or FIN holders), this will be "standard".

A string, which is either "foreign" or "standard".

identity_number

A string which contains a referencable identifier for the user. For Singapore Citizens and Permanent residents, this will be their NRIC. For FIN holders, this will be their FIN. For Singpass Foreign Account holders, this will be their foreign ID.

String

identity_coi

The country code for the of issuance of the identity. For Singapore Citizens, Permanent Residents, and FIN holders, this will be "SG". For Singpass Foreign Account holders, this will be the country code of the country which issued the user's foreign ID.

2-letter country code

name

The user's principal name

non-empty string, only present if the name scope is requested

email

The user's email address

String, only present if the email scope is requested. Note that this could be an empty string even if the email scope is requested, if Singpass does not have the user's email.

mobileno

The user's mobile number. This will always be a Singapore mobile number, and it will not include the country code.

Numeric string, only present if the mobileno scope is requested. Note that this could be an empty string even if the mobileno scope is requested, if Singpass does not have the user's mobile number. For Singpass Foreign Account (SFA) users, this will always be an empty string.

Sample sub_attributes for Singapore Citizen, Permanent Resident, or FIN holder
Sample sub_attributes for Singpass Foreign Account holder

Verification Checks

If you are using a certified OIDC Relying Party library, these checks will be automatically performed by the library, though you must pass the nonce to the library for it to perform the nonce check.

In order to ensure that the ID token is valid, you must perform the following checks:

  1. Verify that the iss claim matches the issuer identifier of our authorization server, which you can obtain from the issuer field in the OpenID configuration of our authorization server.

  2. Verify that the aud claim matches your client ID.

  3. Ensure that the current time is before the timestamp in the exp claim.

  4. Ensure that the nonce claim is the same as the nonce that you had sent in the authorization request.

If you are integrating with Singpass Login, then the flow ends here. If you are integrating with Myinfo (v5), then the next and final step would be to retrieve the user's information using the /userinfo endpoint.

Last updated

Was this helpful?