toolhq.io

All posts
5 min readby Jameel Haider

JWT claims explained

A JSON Web Token is often described as a bag of data, which is true but unhelpful when something goes wrong. The useful structure is the set of standard fields called registered claims. They have fixed short names, a defined meaning, and a few of them are the difference between a token you can trust and one you cannot.

What a claim is

The middle section of a JWT is the payload, a JSON object whose keys are claims. The specification reserves a handful of three letter names so that different systems agree on their meaning. Everything else is a custom claim you define yourself. A decoded payload looks like this:

{
  "iss": "https://auth.example.com",
  "sub": "user_1042",
  "aud": "api.example.com",
  "iat": 1760000000,
  "nbf": 1760000000,
  "exp": 1760003600,
  "jti": "a3f9c1e2"
}

The seven registered claims

  • iss (issuer): who created and signed the token. Your service should accept tokens only from issuers it recognizes.
  • sub (subject): who the token is about, usually a stable user or account identifier. Prefer an opaque ID over an email that can change.
  • aud (audience): who the token is for. A token minted for one API should not be accepted by another.
  • exp (expiration): the Unix time after which the token must be rejected. This bounds how long a leaked token stays useful.
  • nbf (not before): the Unix time before which the token is not yet valid. Useful for tokens issued ahead of time.
  • iat (issued at): when the token was created. Handy for measuring age and for detecting tokens that are implausibly old.
  • jti (JWT ID): a unique identifier for the token, which lets you build a denylist to revoke a specific token.

The three time claims are seconds since the Unix epoch, not milliseconds, which is a common integration bug.

Why aud, exp, and iss validation matters

Decoding a token is not the same as trusting it. A JWT is readable by anyone, so the security comes entirely from verifying the signature and then checking these claims.

  • Skipping exp means a token works forever, so a single leak is permanent.
  • Skipping aud means a token issued for one service can be replayed against another, a classic confused deputy problem.
  • Skipping iss means you might honor a token signed by an issuer you never intended to trust.

A correct validator verifies the signature first, then confirms iss is expected, aud contains your service, and the current time falls between nbf and exp. Only then should the custom claims be used for authorization.

You can inspect any token's claims in the JWT Decoder. It decodes only, it never verifies against a secret, and it runs entirely in your browser so the token is never transmitted, which matters because a JWT often carries live credentials. For the signing side, see JWT HS256 vs RS256, and for a subtle trap, the JWT alg none attack.

The practical takeaway: claims are the structure that makes a JWT trustworthy. Read them to understand a token, but always validate iss, aud, and the time window on the server before you act on anything inside.