A JWT Is Signed, Not Encrypted
Contents
A JSON Web Token looks encrypted. It is a long run of characters with no readable words in it, it appears in an Authorization header, and it is handled like a secret. What it actually is: two JSON objects in base64, plus a signature – and base64 is an encoding, not a lock.
The consequence is short. Everything in the payload is readable by anyone who has the token: the browser it was sent to, the proxy it passed through, the log file that recorded the URL, and the support ticket someone pasted it into. That is not a defect; it is how the format works. It only becomes a problem when the payload is written as though nobody were reading.

The Three Parts and What Each Does
A token is three sections separated by dots. The first names the algorithm and, often, the key that was used. The second carries the claims – who the token is about, what it may do, how long it is valid. The third is the signature over the first two.
Only the third part does any protecting, and it protects exactly one property: that the first two have not been changed since they were signed. It does not hide them, and it does not need to be understood in order for them to be read. A token pasted into any decoder gives up its contents immediately.
What Has No Business in the Payload
Every field in the payload is a field handed to whoever holds the token. An email address, a full name, a date of birth – these turn a credential into a data disclosure, and they end up in places that credentials reach and personal data should not: proxy logs, browser storage, error reports.
The second category is internal structure. A list of roles like billing_admin or a tenant id says what exists behind the API and how it is organised, which is exactly what an attacker enumerates first. A short subject and a scope are usually enough; the rest belongs in the lookup the server does anyway.
The third is anything that was only ever meant for the issuer. Tokens are copied into support tickets, and a payload that carries an internal customer number leaves with them.
exp Is the Only Thing That Ends a Token
A token is valid because it says it is. There is no server-side state that ends it: once issued, it works until the exp claim has passed, and a token without exp works forever.
That is why logging out does not invalidate anything. The client discards the token, the token remains valid, and anyone who kept a copy keeps the access. Ending a token before its time takes a deny list that every service checks – which reintroduces exactly the shared state the format was meant to avoid.
The workable arrangement is a short-lived access token and a refresh token that can be revoked centrally. Minutes for the first, and a lifetime for the second that someone actually monitors: a refresh token with a year’s validity is a password with extra steps.
Where Decoding Gets Confused With Verifying
Reading a token and trusting it are different operations, and the difference is a library call. A decoder shows the claims of any token, including one that was written by hand three seconds ago. Verification checks the signature against a key, and only that answers whether the claims were issued by anyone entitled to issue them.
Two failure modes follow from confusing them. The first is alg: none – a token that declares it has no signature. A verifier that reads the algorithm out of the token and obliges will accept anything; the algorithm has to be fixed by the application, not by the token. The second is the same mistake with a key: a service expecting RS256 that is handed an HS256 token can be talked into verifying it with the public key as the shared secret – and the public key is public.
What Belongs in Every Token
Three claims are worth insisting on. exp, because without it nothing ends. iss, so a service can tell which issuer a token came from rather than accepting anything that verifies. And aud, which is the one that stops a token minted for the reporting API from being accepted by the billing API – a check that is easy to skip and hard to notice missing.
None of this needs tooling to review. Splitting a token at its dots and decoding the middle part takes seconds, and it answers the questions that otherwise get answered by assumption: how long this is valid, what it permits, and what it tells anyone who reads it.