Module 04 · API fundamentals · Lesson 13 of 15
JWT
A JSON Web Token is a signed set of claims any holder of the key can verify. Its three parts, the claims that matter, symmetric versus asymmetric signing, key rotation with JWKS, and the validation mistakes that have produced real breaches.
Why it matters
JWTs are the lingua franca of modern authentication: OAuth providers issue them, API gateways verify them, and services pass them downstream. They are also widely misused, because a token that "just works" when decoded hides the fact that verification is the whole point. Knowing what a JWT does and does not promise is what lets you use it in a design without creating the vulnerabilities that make the news.
The idea
A JSON Web Token is three base64url-encoded parts joined by dots: a header (algorithm and key id), a payload of claims (JSON facts about the subject), and a signature over the first two. Anyone can decode and read it; only a holder of the key can create a valid signature; anyone with the verification key can check it. It is signed, not encrypted: never put secrets in the payload.
Claims that matter
| Claim | Meaning | Verify |
|---|---|---|
| iss | Issuer: who signed it | Must equal the issuer you trust |
| sub | Subject: the user or service id | Use as the principal |
| aud | Audience: which API this token is for | Must include this service, or a token for one API works on another |
| exp | Expiry (Unix time) | Reject if past; keep lifetimes short |
| iat / nbf | Issued at / not before | Reject tokens from the future or before validity |
| jti | Unique token id | Needed if you ever want to deny-list a token |
| scope / roles / tenant | Application claims | Authorize on them; keep them small |
Symmetric versus asymmetric signing
HS256 uses one shared secret to sign and verify. Simple, fast, and every verifier can also forge tokens, so it suits a single service, not a fleet. RS256 or ES256 use a private key to sign and a public key to verify. The issuer keeps the private key; every service verifies with the public key and cannot mint tokens. This is the right choice as soon as more than one party verifies.
Key rotation with JWKS
The issuer publishes its public keys at a well-known URL as a JWKS (JSON Web Key Set), each with a key id. Tokens name their key in the header's kid. Verifiers cache the key set and refresh it when they see an unknown kid. Rotation is then routine: publish a new key, start signing with it, keep the old one listed until all tokens signed with it have expired, then remove it.
Validation mistakes that became breaches
- 1
Trusting the header's algorithm
A token claimingalg: noneor switching RS256 to HS256 (so the public key is used as an HMAC secret) has fooled libraries. Pin the expected algorithm in the verifier; never let the token choose. - 2
Decoding without verifying
Many libraries offer a decode function that does not check the signature. Using it for authentication accepts any token anyone types. - 3
Ignoring aud and iss
A valid token from your login provider intended for a different app is still a valid signature. Check that it was issued by the right party for this audience. - 4
Long lifetimes with no revocation
A 30-day stateless token is a 30-day window for a stolen one. Keep access tokens to minutes and pair with refresh tokens (previous lesson). - 5
Secrets in claims
The payload is readable by anyone. Put identifiers and permissions in it, never passwords, personal data or internal hostnames.
Size and where it travels
A JWT with a few claims is a few hundred bytes and rides in every request's Authorization: Bearer header. Stuffing it with roles, preferences and profile data makes every request heavier and the data stale the moment it changes. Keep the token to identity and coarse permissions; fetch the rest.
Trade-offs
JWTs let any service verify identity without a round trip and carry claims across service boundaries, which is exactly what a distributed system wants. They cost delayed revocation, a readable payload, header overhead on every request, and a verification routine that must be done correctly in every service. Asymmetric keys with JWKS add a small amount of infrastructure and remove the shared-secret risk.
In an interview
Be specific about verification, because that is where designs go wrong: "The identity provider issues RS256 JWTs with a fifteen-minute expiry. Services fetch the JWKS, verify the signature with the pinned algorithm, and check iss, aud and exp before trusting sub and scope. Refresh tokens are server-side so we can revoke." Said in one breath, it covers every item on the checklist.
Check yourself
A service verifies JWTs by reading the alg field from the token header and using that algorithm with its RS256 public key. An attacker sends a token with alg set to HS256, signed using the public key as the HMAC secret. What happens?