JWT Inspector
Paste a token below. The header and payload are base64url-decoded and formatted,
the algorithm is read from the header, and any exp claim is compared against
your device’s clock.
This tool does not verify the signature. It has no key, it never contacts a server, and it therefore cannot tell you whether the token is authentic. A decoded token is a claim about its contents, not proof of them. Treat anything shown below as untrusted input until something holding the right key says otherwise.
Nothing is transmitted. The decoding runs in the page, in your browser. There are no network requests, no analytics and no storage — the token is not saved anywhere and disappears when you close the tab. That said, tokens are live credentials for as long as they are valid; if you paste a production token anywhere, treat it as exposed and let it expire.
Paste a token to decode it.
Signature is not checked. This page has no key and makes no requests.
What the three segments are
A JWT is three base64url-encoded segments joined by dots. The first is a JSON header describing how the token was signed. The second is a JSON payload holding the claims. The third is the signature over the first two.
Base64url is ordinary base64 with two substitutions — - for +, _ for / —
and the trailing = padding removed, so the value survives being placed in a URL
or a header without further escaping. Decoding it is a reversible transformation
requiring no secret, which is the single most misunderstood property of the
format.
Encoded is not encrypted
Anyone holding a signed JWT can read every claim in it, on any machine, with no key. The signature protects the token from being modified undetectably; it does nothing to conceal the contents.
That has a direct design consequence: a JWT is not a place to put anything you would not hand to the party carrying it. Internal identifiers, entitlement structure, group names and email addresses all leak to whoever holds the token, including whoever steals it.
Reading the algorithm
The alg value in the header states how the token was signed. Symmetric
algorithms use one shared key for signing and verification, which means every
party able to verify is also able to mint. Asymmetric algorithms separate the
two, so a verifier holds only a public key and cannot issue.
Two header fields matter operationally. kid names which key was used, which is
what makes rotation possible without invalidating everything in flight. And alg
itself must never be the thing that selects the verification method at the
verifier — a verifier should decide what it will accept in advance, from its own
configuration, and reject anything else. A verifier that reads alg from the
token and does as it is told has handed the choice of algorithm to whoever
produced the token, and none is a value.
Expiry is a claim too
exp is a numeric date: seconds since the Unix epoch, in UTC. nbf sets the
earliest moment the token is valid, and iat records when it was issued. This
page compares exp against your device’s clock, which is worth remembering — a
token that appears expired here may be perfectly valid to a verifier whose clock
differs, and the reverse.
Expiry is enforced by the verifier, not by the token. Nothing stops a stolen token being used until the moment the verifier decides it is too old, which is why lifetime is the main lever on how long a compromised token remains useful. Long lifetimes are convenient in exactly the way that makes theft profitable.
What to look at when a token behaves unexpectedly
Three claims explain most rejections. iss identifies the issuer, and a verifier
should accept only issuers it was configured with. aud names the intended
recipient; a token minted for one service and presented to another should be
rejected by that check alone, and often is not. And sub names the principal —
worth reading closely when an authorisation outcome is surprising, because a
token frequently turns out to be for a different principal than the person
debugging it assumes.