Learnitweb

JWT Claims

JWT Claims are the core data that a JWT token carries. These claims convey specific statements about a subject (e.g., a user), and are encoded in the Payload section of a JWT.

4.1. JWT Claims Set

The JWT Claims Set is a JSON object containing a collection of name/value pairs called claims. These claims assert specific facts about a subject, like:

  • Who issued the token
  • When it expires
  • Who it’s intended for
  • Any additional metadata (like user role, email, etc.)

Key Characteristics

  • Unique Claim Names: Each claim name within a JWT Claims Set must be unique. If duplicate names are present, the JWT parser must reject the token, or it must use a JSON parser that keeps only the last occurrence of a name.
  • Context-Dependent Validity: Which claims are required in a JWT depends entirely on the application or context. There is no universal set of required claims.
  • Unknown Claims Must Be Ignored: If a JWT contains claims not understood by the system processing it, those claims must be ignored, unless the context dictates otherwise.

Claim Name Types

There are three categories of claim names in JWT:

  1. Registered Claim Names
    Predefined, commonly used claims that improve interoperability.
  2. Public Claim Names
    Custom claims with globally unique names to avoid conflicts.
  3. Private Claim Names
    Custom claims agreed upon between systems, which may collide unless carefully managed.

4.1 Registered Claim Names

These are standardized claim names defined in the IANA “JSON Web Token Claims” registry. They are not mandatory but are recommended for interoperability between different systems.

4.1.1 "iss" (Issuer)

  • Identifies who issued the JWT.
  • Typically a StringOrURI (e.g., "https://auth.mycompany.com").
  • This is application-specific and optional.

4.1.2 "sub" (Subject)

  • Identifies the subject of the JWT, i.e., who or what the token is about.
  • Can be a username, user ID, email, etc.
  • Must be unique within the context of the issuer.
  • Also a StringOrURI.
  • Optional, but widely used in identity systems.

4.1.3 "aud" (Audience)

  • Identifies the intended recipients of the JWT.
  • Each recipient must verify that it is included in the "aud" value.
  • The value can be:
    • A single string (for one audience).
    • An array of strings (for multiple audiences).
  • Optional but must be validated if present.

4.1.4 "exp" (Expiration Time)

  • Indicates the time after which the token is no longer valid.
  • Must be a NumericDate (i.e., Unix timestamp in seconds).
  • Systems must reject tokens where current time > exp.
  • Implementations may allow clock skew (typically 1–5 minutes).
  • Optional, but strongly recommended for security.

4.1.5 "nbf" (Not Before)

  • Specifies the time before which the JWT must not be accepted.
  • Also a NumericDate.
  • Used to prevent tokens from being used prematurely.
  • Allows limited future-valid tokens (e.g., scheduled access).
  • Optional and may be used with "exp" to define a valid time window.

4.1.6 "iat" (Issued At)

  • Indicates when the JWT was issued.
  • Helps calculate the token age.
  • Also a NumericDate.
  • Useful for detecting replay attacks or validating token freshness.
  • Optional.

4.1.7 "jti" (JWT ID)

  • Provides a unique identifier for the token.
  • Used to detect and prevent replay attacks.
  • Should be a globally unique string (e.g., UUID).
  • Must be generated in such a way that collision is practically impossible, even across different issuers.
  • Optional, but important in stateless authentication to enable blacklisting.

4.2 Public Claim Names

Developers or vendors may define their own custom claim names beyond the registered ones. To avoid name collisions, such custom claims should use a collision-resistant naming scheme. Examples include:

  • Fully qualified domain names (e.g., "https://example.com/user_level")
  • UUID-based namespaces
  • OIDs (Object Identifiers)

Such claims are called Public Claim Names, and it’s recommended that they be registered with IANA if they are going to be reused across systems.


4.3 Private Claim Names

Private Claim Names are used internally between two parties. These names are:

  • Not registered in IANA
  • Not globally unique
  • Agreed upon by sender and receiver

For example:

{
  "user_id": "789",
  "internal_code": "ABC123"
}

While flexible and convenient, private claims may conflict with other claim names if used across systems. Therefore, they should be used only in isolated or trusted systems.


Summary of Claim Name Categories

TypePurposeNaming ConventionRisk of Collision
Registered ClaimsStandard, well-known claimsShort, predefined namesLow
Public ClaimsCustom claims with global uniquenessNamespaced (e.g., domain URI)Low
Private ClaimsInternal, custom claims shared by trusted partiesFreely chosenHigh

Example JWT Payload with Claims

{
  "iss": "https://auth.example.com",
  "sub": "1234567890",
  "aud": ["my-api", "my-service"],
  "exp": 1718038200,
  "nbf": 1718034600,
  "iat": 1718034600,
  "jti": "f1f8d9a8-80b8-4f68-b191-73d6f3f8d2e4",
  "role": "admin",
  "https://example.com/is_premium_user": true
}
  • The first 7 claims are registered.
  • "role" is a private claim.
  • "https://example.com/is_premium_user" is a public claim using a namespaced URI.