2026-08-26 · 8 min read
- jwt
- oauth
- authorization
JWT claims answer different identity questions. The issuer says who minted the token, the subject identifies the principal, the audience identifies intended recipients, and client-related claims identify the application involved. Treating those values as interchangeable creates authorization gaps and confusing 401 or 403 responses.
Claim names also vary by provider and token type. An access token, ID token, and client-credentials token may describe the same OAuth application differently, so policy must follow the issuer's documented profile.
Map the actors before writing policy
Draw the token flow with the user or workload, OAuth client, authorization server, and resource API. Then assign each verified claim to one actor instead of guessing from a familiar-looking identifier.
- iss — the trusted authorization server that issued the token
- sub — the principal represented by the token
- aud — the resource server or recipients intended to accept it
- azp — the authorized party, commonly relevant when audiences are multiple
- client_id — a provider-defined client identifier often present in access tokens
Authenticate before authorizing
First verify the signature with an allowed algorithm and trusted key. Then validate issuer, audience, expiry, not-before, and token type. Only after those checks should roles, scopes, client identity, or tenant claims drive authorization.
Decoding is useful for diagnosis but proves nothing about authenticity. Never paste a decoded value into an allowlist before confirming which verified claim the provider guarantees.
Diagnose 401 and 403 separately
Use 401-oriented evidence for invalid or missing authentication: signature, issuer, audience, or lifetime. Use 403-oriented evidence when a valid principal lacks permission. Logs should name the failed check without recording the full token.
- Compare sanitized accepted and rejected claim sets.
- Verify the gateway and application interpret client claims consistently.
- Check whether token exchange changed the actor or authorized party.
- Test an unrelated client to prove the allowlist remains restrictive.
Use local tools without confusing privacy and trust
Flashman's JWT decoder helps inspect claims, the JSON formatter makes provider metadata readable, the timestamp converter translates lifetime claims, and the diff tool compares safe fixtures. Client-side processing reduces upload risk, but real bearer tokens still grant access and should be replaced with synthetic or redacted examples.
Document the accepted issuer, audience, token type, client claim, and authorization rule together. That runbook makes identity-provider migrations much safer than scattered claim checks.