Registered, public, and private JWT claims

RFC 7519 §4 splits every claim that can appear in a JWT payload into three categories: registered, public, and private. The category doesn't change how a claim is encoded — they're all just JSON members — it defines who governs the name and how likely two systems are to disagree about what it means.

CategoryDefined byExamplesCollision risk
RegisteredRFC 7519 itselfiss, sub, aud, exp, nbf, iat, jtiNone — reserved
PublicIANA "JSON Web Token Claims" registryemail, name, auth_time, nonce, scopeNone if you use registered names as specified
PrivateAgreement between issuer and consumertenant_id, https://example.com/rolesHigh unless namespaced

Registered claims

Seven claim names are reserved by the RFC. All are optional, but verifiers should treat the ones they rely on as mandatory:

Public claims

A public claim is any claim intended for use across systems. To avoid two products inventing the same name with different meanings, public claim names are supposed to be registered with IANA or use a collision-resistant name (a URI). In practice most public claims you'll meet come from OpenID Connect: email, name, preferred_username, auth_time, nonce, plus the RFC 9068 access-token profile (scope, client_id).

Private claims

Private claims are whatever an issuer and its consumers agree on — tenant_id, plan, roles. Two rules keep them safe:

  • Namespace them. Auth0 requires URI-style names like https://example.com/roles; Microsoft Entra prefixes extension claims with xms_. A bare name like role risks silently colliding with a future spec or another vendor.
  • Never put secrets in them. A signed JWT (JWS) is readable by anyone who holds it — the payload is only base64url-encoded. If a claim value must stay confidential, use JWE encryption instead.

Which claims should you use?

Prefer registered claims for everything they cover, use OIDC names for identity data instead of inventing your own, and keep private claims few and namespaced — every extra claim grows the token that's sent on every request. To see how a real token is categorized, decode it in the TokenPrism debugger: every known claim is annotated from the same reference that powers the complete claims list.