JWT Decoder Results Explained: What alg, kid, iss, aud, exp, nbf, and scope Actually Tell You

Decode JWT fields without confusing readability with trust. Learn what common headers and claims mean, and which checks still require cryptographic verification.

Back to Blog

JWT Decoder Results Explained: What alg, kid, iss, aud, exp, nbf, and scope Actually Tell You

Paste a JWT into a decoder and you immediately get readable JSON. That convenience creates a dangerous misunderstanding: readable claims are not proof that the token is genuine. A decoder can tell you what the token says. Verification is what tells the receiving application whether it should trust those statements.

Vulnify's JWT / Token Decoder decodes JWT headers and payloads locally in the browser, highlights unsafe algorithm choices, and includes Base64 utilities. It is useful for inspection and troubleshooting. It is not a replacement for signature verification, issuer validation, audience checks, expiration enforcement, or authorization in the application.

A signed JWT usually has three compact parts

A typical signed JWT is represented as three Base64URL-encoded sections separated by periods:

eyJhbGciOiJSUzI1NiIsImtpZCI6ImtleS0yMDI2In0
.
eyJpc3MiOiJodHRwczovL2lkLmV4YW1wbGUuY29tLyIsImF1ZCI6ImFwaSIsImV4cCI6MTc5MTk3NjAwMH0
.
SIGNATURE

The first part is the JOSE header, the second contains claims, and the third is the signature for a JWS-form token. Decoding the first two parts requires no secret. Anyone who possesses the token can read them. That is normal and should influence what you put inside a token: do not assume Base64URL encoding provides confidentiality.

alg: which algorithm does the token claim to use?

The alg header names the algorithm the token says protects it. Common examples include RS256, ES256, and HS256. A decoder can show that value, but a verifier must not blindly accept whatever algorithm the token requests.

The application should be configured with the algorithms it expects for that issuer and token type. Security failures have historically occurred when libraries or applications accepted unexpected algorithms, confused symmetric and asymmetric keys, or treated an unsecured algorithm as valid.

So a decoded header like this:

{
  "alg": "RS256",
  "kid": "prod-key-2026-10",
  "typ": "JWT"
}

means "the token claims to use RS256 and identifies a key as prod-key-2026-10." It does not mean the RS256 signature has been checked.

kid: a key selector, not proof of trust

kid commonly tells the verifier which verification key to use. Identity providers rotate keys, so several public keys can be valid during a transition. The key ID lets the receiver select the intended one from a trusted key set.

Treat kid as untrusted input until it has been safely resolved against a trusted configuration. Do not use it as a raw file path, SQL value, URL, or arbitrary lookup instruction. The application should fetch keys only from configured issuer metadata or another trusted source and should handle key rotation without accepting keys from attacker-controlled locations.

iss: who says they issued the token?

RFC 7519 defines iss as the issuer claim. In an identity deployment it often looks like a URL:

"iss": "https://identity.example.com/"

Verification means comparing that value with the issuer the application is configured to trust. A token that says it came from your identity provider is not trustworthy merely because the string matches a familiar domain. The signature must verify with keys that belong to that configured issuer, and the issuer value must match the expected value exactly according to the protocol and library in use.

This matters in applications that support more than one identity provider. OAuth security guidance also calls out issuer checking as a defense against mix-up attacks.

aud: who is the token intended for?

The aud claim identifies the intended recipient or recipients. RFC 7519 states that a principal processing a token must reject it if the token contains an audience claim and that principal does not identify itself as an intended audience.

A token issued for api://billing should not automatically be accepted by api://admin because both services trust the same identity provider.

{
  "iss": "https://identity.example.com/",
  "aud": "api://billing"
}

This is one reason "signature valid" is not the end of token validation. A genuine token can still be inappropriate for the service receiving it.

exp: the point after which the token must not be accepted

exp is a NumericDate expiration time. RFC 7519 says the token must not be accepted on or after that time. Implementations may allow a small amount of clock skew, but expiration is not a hint for the user interface. It is an acceptance rule for the verifier.

A decoder can convert the timestamp into a readable time and help you diagnose "token expired" errors. That is especially useful when browser, API gateway, and identity-provider clocks disagree. The fix, however, is not to extend acceptance indefinitely. Synchronize clocks, issue appropriate token lifetimes, and use the refresh mechanism intended by the identity system.

nbf: not valid yet

nbf, or not before, defines a time before which the token must not be accepted. A token with a future nbf may be perfectly well signed and still unusable for the next few minutes.

When a token works on one server but not another, inspect system time and configured clock-skew tolerance before changing claims. Large tolerances weaken the meaning of time-based controls.

iat: when the token says it was issued

iat records the issuance time. It can help applications reason about token age, key rotation, session events, or security policy. It should not be treated as trustworthy until the token itself has passed cryptographic and semantic validation.

scope, roles, and permissions are application claims

OAuth access tokens often contain a scope claim or an equivalent representation. Applications may also include roles, groups, tenant IDs, or custom permissions. These claims matter only in the context of the authorization model implemented by the receiving service.

For example:

{
  "sub": "user-4831",
  "scope": "orders:read orders:write",
  "tenant_id": "tenant-a"
}

A decoder can show those strings. It cannot prove that the user is currently entitled to them, that the token was issued by a trusted authority, or that the API correctly enforces tenant ownership for each object. The API still has to authorize every operation.

Decoding vs verification

This distinction should be explicit in every troubleshooting workflow.

  • Decoding parses Base64URL content so you can read the header and claims.
  • Signature verification checks cryptographic integrity and authenticity using an appropriate trusted key.
  • Claim validation checks issuer, audience, time restrictions, nonce or other protocol-specific values.
  • Authorization decides whether the authenticated identity can perform the requested operation on the requested resource.

A token can pass one layer and fail the next. A valid signature with the wrong audience should be rejected. A valid token for the correct audience does not automatically authorize an administrator-only action.

A practical 401 debugging sequence

When an API returns 401, inspect in a predictable order:

  • Is the value actually a JWT, with the expected compact structure?
  • What alg does the header claim?
  • Does the kid correspond to a current key from the configured issuer?
  • Does the signature verify with that trusted key?
  • Does iss equal the configured issuer?
  • Does aud include this API?
  • Has exp passed?
  • Is nbf still in the future?
  • Is the token type appropriate for this endpoint?
  • If validation succeeds, is the failure actually authorization and therefore a 403 case?

Do not paste production bearer tokens into random online services. A bearer token may grant access to real data. Vulnify's JWT decoder runs the decoding operation locally in the browser, but you should still use test tokens or sanitized data whenever possible and follow your organization's handling policy.

Key rotation and JWKS troubleshooting

During signing-key rotation, an identity provider may publish multiple keys. An API that caches the JSON Web Key Set too aggressively can reject a newly issued token because its kid is not in the stale cache. At the other extreme, fetching keys from arbitrary locations supplied by a token is unsafe.

The correct design is to trust a configured issuer, obtain keys from its trusted metadata or configured JWKS endpoint, cache them sensibly, and refresh when an unknown key ID appears according to your library's supported behavior.

Use the JWT decoder for inspection, not trust

Use the JWT / Token Decoder when you need to inspect a token's structure and claims during authorized troubleshooting. Use the Open Redirect Checker and broader website tools for related public-surface checks around redirect handling and deployment configuration.

Do not interpret a clean decode as a security verdict. Vulnify does not possess the application's private verification context merely because it can display the token. Cryptographic verification and authorization belong in the system that consumes the JWT.

Treat bearer tokens as secrets even though the payload is readable

A JWT may expose readable claims while still functioning as a bearer credential. Anyone who obtains a valid access token may be able to use it until it expires or is revoked by another control. Do not paste real production tokens into tickets, screenshots, chat systems, analytics events, or public debugging sites.

When sharing a token for troubleshooting, use a synthetic or expired test token where possible. If the exact claim set matters, redact the signature and sensitive identifiers only when doing so will not mislead the investigation. Remember that browser developer tools, reverse-proxy logs, and error-reporting platforms can all become accidental token stores.

Also identify the token type before interpreting claims. An ID token, access token, refresh token, and application-specific session token are not interchangeable simply because one or more of them uses JWT syntax.

The simplest rule

Read a decoded JWT as a statement of claims, not a certificate of truth. alg tells you what protection is claimed. kid points toward a key. iss names an issuer. aud names intended recipients. exp and nbf define time boundaries. scope and custom claims describe intended permissions.

Only after signature verification, issuer and audience checks, time validation, and application authorization should those claims influence a security decision.