ID Token and Standard Claims

Learn more about ID Token and how you can customise the ID Token using the Standard Claims format.

The ID Token is a security token containing the user’s claim about their identity provided by Affinidi Login from the VP Token issued by the user’s Vault. ID Token is represented in a JSON Web Token (JWT) format, a key/value pair where the key is the field name in string format, and the value could be any value shared by the user from their Vault.

The OpenID Connect provides standard claims that developers can define when customising the ID Token that will be generated and consumed by their application. Below is the example of the ID Token claim provided by Affinidi Login:

{
    "acr": "0",
    "at_hash": "R8YwamO1HFMT3Nf-hBMg-w",
    "aud": [
        "e7e54cff-1640-4f9b-878u-d8b294a2267c"
    ],
    "auth_time": 1698815469,
    "custom": [
        {
          "type": [
            "VerifiableCredential",
            "Email"
          ]
        },
        {
          "email": "email@email.com"
        },
        {
          "did": "did:key..."
        }
    ],
    "exp": 1698816371,
    "iat": 1698815471,
    "iss": "https://<PROJECT_ID>.apse1.login.affinidi.io",
    "jti": "c77b819d-f4cf-4771-8977-c4c482287569",
    "rat": 1698815462,
    "sid": "2e86778d-83af-47d9-jai8-1f928e2743bc",
    "sub": "did:key..."
}

Visit OpenID Connect Standard Claims to learn more.

ID Token Claims Format

Affinidi Login through Login Configurations enables developers to define and customise the ID Token consumed by the application. Using the Presentation Definition as the source of ID Token values, developers can customise the ID Token mapping and add claims using Standard Claims provided by the OpenID Connect defined in JWT Specifications .

JWT Reserved Claims

JWT Specifications defines seven reserved claims. These claims are not mandatory to be implemented, but it is recommended to enable interoperability of claims with third-party applications.

  • iss (issuer): a case-sensitive string that identifies the token issuer.

  • sub (subject): a case-sensitive string that identifies the subject of the claim (Affinidi Vault user).

  • aud (audience): a case-sensitive array of strings that identifies where the claim is intended for.

  • exp (expiration time): the time that sets the expiration after which the claim must not be accepted.

  • nbf (not before time): the time before which the claim must not be accepted.

  • iat (issued at time): the time at which the claim was issued.

  • jti (JWT ID): a unique identifier of the claim. It can be used to prevent the token from being replayed.

OIDC Standard Claims

OpenID Connect (OIDC) provides sets of standard claims that developers can use when customising their ID Token to consume in their application.

  • name (string): End-User’s full name that may include title and suffixes.

  • given_name (string): given name(s) or first name(s) of the End-User.

  • family_name (string): surname(s) or last name(s) of the End-User.

  • middle_name (string): middle name(s) of the End-User. Note that in some cultures, middle names are not used.

  • nickname (string): casual name of the End-User that may or may not be the same as the given_name.

  • preferred_username (string): shorthand name by which the End-User wishes to be referred to. This value may be any valid JSON string including special characters such as @, /, or whitespace.

  • profile (string): URL of the End-User’s profile page.

  • picture (string): URL of the End-User’s profile picture. This URL MUST refer to an image file, rather than to a Web page containing an image.

  • website (string): URL of the End-User’s Web page or blog.

  • email (string): End-User’s preferred e-mail address.

  • email_verified (boolean): true if the End-User’s e-mail address has been verified; otherwise, false. In the context of Affinidi Vault, using the EmailVC as the source identified the email address supplied by the user as a verified email.

  • gender (string): End-User’s gender.

  • birthdate (string): End-User’s birthday, represented as an ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format.

  • zoneinfo (string): string from IANA Time Zone Database [IANA.time‑zones] representing the End-User’s time zone. For example, Europe/Paris or America/Los_Angeles.

  • locale (string): End-User’s locale, represented as a BCP47 [RFC5646] language tag. For example, en-US or fr-CA. As a compatibility note, some implementations have used an underscore as the separator rather than a dash, for example, en_US;

  • phone_number (string): End-User’s preferred telephone number.

  • phone_number_verified (boolean): true if the End-User’s phone number has been verified; otherwise, false.

  • address (JSON object): End-User’s preferred postal address. The value of the address member is a JSON [RFC8259] structure containing some or all of the address information.

  • updated_at (number): time the End-User’s information was last updated. Its value is a JSON number representing the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time.

Registered and Private Claims

Registered or public claims are fields registered in the IANA JSON Web Token Claims Registry including the OIDC Standard Claims and the JWT Reserved Claims.

Private claims are fields specific to the application, such as ID Number, Order ID, etc. It is important to make sure that the naming of these fields is collision-resistant. If you need to define private or non-standard claims for your application, you must use $.custom[x] claim in the ID Token Mapping (e.g. $.custom[0].id_numbder).

Define Custom ID Token Claim

Using the ID Token Mapping of the Login Configuration, you can define a custom ID Token format based on standard or registered claims specific to your application.

Default ID Token Mapping

By default, Login Configuration has a default ID Token mapping that defines the claims in the custom field.

[
  {
    "sourceField": "$.type",
    "idTokenClaim": "$.custom[0].type",
    "inputDescriptorId": "email_vc"
  },
  {
    "sourceField": "$.credentialSubject.email",
    "idTokenClaim": "$.custom[1].email",
    "inputDescriptorId": "email_vc"
  }
]

Using the $.custom[x], we define the ID Token format that contains claims within the custom field. The resulting ID Token will look like this:


{
  "acr": "0",
  "at_hash": "Oc2PFY2SJUxL0HB6Hoza8Q",
  "aud": [
    "ee2811b9-10b8-4ce1-94ac-750e325fcc98"
  ],
  "auth_time": 1696314694,
  "custom": [
    {
      "type": [
        "VerifiableCredential",
        "Email"
      ]
    },
    {
      "email": "myemail@email.com"
    },
    {
      "did": "did:key......"
    }
  ],
  "exp": 1696315595,
  "iat": 1696314695,
  "iss": "https://<PROJECT_ID>.apse1.login.affinidi.io",
  "jti": "51af00fb-6aa6-4d95-b51a-05dba94361b2",
  "rat": 1696314688,
  "sid": "c3bcb434-28ea-4a59-83f4-f587e2a17055",
  "sub": "did:key......"
}

Defining Top-level Claims

The following examples defines the top-level claim using standard claims provided by OpenID Connect (OIDC).

Using the $.email in the ID Token Mapping, we are defining a top-level claim that adheres to the standard claim of OIDC.

[
  {
    "sourceField": "$.type",
    "idTokenClaim": "$.custom[0].type",
    "inputDescriptorId": "email_vc"
  },
  {
    "sourceField": "$.credentialSubject.email",
    "idTokenClaim": "$.email",
    "inputDescriptorId": "email_vc"
  }
]

The resulting ID Token from the example above will be:


{
  "acr": "0",
  "at_hash": "Oc2PFY2SJUxL0HB6Hoza8Q",
  "aud": [
    "ee2811b9-10b8-4ce1-94ac-750e325fcc98"
  ],
  "auth_time": 1696314694,
  "custom": [
    {
      "type": [
        "VerifiableCredential",
        "Email"
      ]
    },
    {
      "did": "did:key......"
    }
  ],
  "email": "myemail@email.com",
  "exp": 1696315595,
  "iat": 1696314695,
  "iss": "https://<PROJECT_ID>.apse1.login.affinidi.io",
  "jti": "51af00fb-6aa6-4d95-b51a-05dba94361b2",
  "rat": 1696314688,
  "sid": "c3bcb434-28ea-4a59-83f4-f587e2a17055",
  "sub": "did:key......"
}

Another example is using the OIDC standard address claim to include address information like country of the user in the ID Token. Using the $.address.country in the ID Token Mapping, we are defining a top-level claim that adheres to the standard claim of OIDC for address information.

[
  {
    "sourceField": "$.type",
    "idTokenClaim": "$.custom[0].type",
    "inputDescriptorId": "email_vc"
  },
  {
    "sourceField": "$.credentialSubject.country",
    "idTokenClaim": "$.address.country",
    "inputDescriptorId": "email_vc"
  }
]

The resulting ID Token from the example above will be:


{
  "acr": "0",
  "at_hash": "Oc2PFY2SJUxL0HB6Hoza8Q",
  "aud": [
    "ee2811b9-10b8-4ce1-94ac-750e325fcc98"
  ],
  "auth_time": 1696314694,
  "custom": [
    {
      "type": [
        "VerifiableCredential",
        "HITCountry"
      ]
    },
    {
      "did": "did:key......"
    }
  ],
  "address": {
    "country": "Singapore"
  },
  "exp": 1696315595,
  "iat": 1696314695,
  "iss": "https://<PROJECT_ID>.apse1.login.affinidi.io",
  "jti": "51af00fb-6aa6-4d95-b51a-05dba94361b2",
  "rat": 1696314688,
  "sid": "c3bcb434-28ea-4a59-83f4-f587e2a17055",
  "sub": "did:key......"
}

ID Token Mapping Validation

  • JWT reserved claims are restricted from being defined in the ID Token Mapping as top-level claims.
  • Only the standard and registered claims can be defined at the top-level claims.
  • Non-standard or private claims can only be defined inside the $.custom[x] claim.

ID Token Mapping is a powerful tool that enables developers to customise their ID Token specific to their application, and just like the Presentation Definition, ID Token Mapping leverages JSONPath Expression ($.<field_name>) to define the ID Token claim format consumed by the application after successful authentication of the user through Affinidi Login.

To customise the ID Token with additional data from the Affinidi Vault using Presentation Definition, visit this guide to learn more.