API & BACKEND ARCHITECTURE / SYSTEM CONCEPT BRIEF

JWT

A JSON Web Token (JWT) is a compact, signed token with three base64url parts: header (algorithm), payload (claims such as user ID, expiry, scopes), and signature.

IntermediatePhase 02 / Topic 9 of 20RequirementsTrade-offsFailure modes
01

Overview

A JSON Web Token (JWT) is a compact, signed token with three base64url parts: header (algorithm), payload (claims such as user ID, expiry, scopes), and signature. Any service with the signing key or public key can verify the token and trust its claims without calling a database or the issuer.

That statelessness is the main benefit and the main risk. JWTs scale well across microservices, but once issued they remain valid until they expire, so revocation requires short lifetimes, refresh tokens, or deny lists. JWTs are signed, not encrypted: anyone can read the payload, so never put secrets in it.

A tamper-evident wristband with printed details

The wristband shows your name, access level, and expiry time, and has a hologram seal. Any guard can check the seal without calling the office. But if the office wants to revoke it early, guards will not know unless they check a revocation list.

02

When to use it

  • Access tokens verified by many services without a shared session store.
  • OIDC ID tokens that convey user identity.
  • Short-lived, signed claims between systems (signed URLs, email links).
  • Stateless APIs where database lookups per request are too costly.
03

Where it shows up in interviews

Stateless auth in microservices

Recognize it when: many services must verify identity cheaply.

  • Design auth for a microservice platform
  • Design an API gateway
Token lifecycle

Recognize it when: logout, revocation, and refresh.

  • Design secure mobile app login
  • Design session management at scale
04

Where it is used in real software

OIDC ID tokens

Google, Microsoft, and Okta issue ID tokens as JWTs signed with RS256; apps fetch public keys from a JWKS endpoint.

JWKS key rotation

Issuers publish multiple keys identified by kid, so they can rotate signing keys without breaking verification.

The alg: none vulnerability

Early libraries accepted unsigned tokens when the header said alg: none; modern libraries require an explicit allowed algorithm.

05

Key terms

Header
{ alg: RS256, typ: JWT, kid: key-id }.
Claims
sub (subject), iss (issuer), aud (audience), exp (expiry), iat (issued at), plus custom claims.
HS256 vs RS256
Shared-secret HMAC vs asymmetric RSA (or ES256) signatures.
JWKS
JSON Web Key Set: public keys published by the issuer.
Refresh token
Long-lived credential used to obtain new short-lived access tokens.
06

How it works, step by step

  1. 1
    Issuer creates claims

    sub, iss, aud, exp (for example 15 minutes), scopes.

  2. 2
    Issuer signs

    signature = sign(base64url(header) + '.' + base64url(payload), privateKey).

  3. 3
    Client sends the token

    Authorization: Bearer <jwt>.

  4. 4
    Service verifies

    Check the signature with the public key (by kid), then iss, aud, exp, and the allowed algorithm.

  5. 5
    Refresh

    When the access token expires, exchange the refresh token for a new one; rotate the refresh token.

Anatomy of a JWT
Step 1 / 4
Header
Payload
Signature

STEP 1Header: {"alg":"RS256","kid":"2026-09"} base64url encoded. It tells verifiers which key and algorithm to use.

07

Sessions vs JWT access tokens

Both authenticate requests after login

Step 1 / 5
AspectServer session + cookieJWT access token
StateStored server-side (Redis)Self-contained in the token
Verification costStore lookupSignature check (CPU only)
RevocationDelete session: instantWait for expiry or use a deny list
Cross-serviceNeeds shared storeAny service with the public key
Best forBrowser web appsAPIs, microservices, mobile

NOWAspect: State | Server session + cookie: Stored server-side (Redis) | JWT access token: Self-contained in the token

A common hybrid: browser talks to a backend with a session cookie; the backend exchanges it for short-lived JWTs to call internal services.

08

Implementation

import { SignJWT, jwtVerify, createRemoteJWKSet } from "jose"; // Issuer: sign a short-lived access tokenasync function issueAccessToken(userId: string, privateKey: CryptoKey) {  return new SignJWT({ scope: "orders.read orders.write" })    .setProtectedHeader({ alg: "ES256", kid: "2026-09" })    .setSubject(userId)    .setIssuer("https://auth.example.com")    .setAudience("orders-api")    .setIssuedAt()    .setExpirationTime("15m")    .sign(privateKey);} // Resource server: verify with the issuer's public keys (cached, rotated by kid)const jwks = createRemoteJWKSet(new URL("https://auth.example.com/.well-known/jwks.json")); async function authenticate(authorization?: string) {  const token = authorization?.replace(/^Bearer /, "");  if (!token) throw new HttpError(401, "Missing token");  const { payload } = await jwtVerify(token, jwks, {    issuer: "https://auth.example.com",    audience: "orders-api",    algorithms: ["ES256"], // never accept "none" or unexpected algorithms  });  return { userId: payload.sub!, scopes: String(payload.scope).split(" ") };}
09

Complexity and performance

Verification~0.05-0.5 ms

Signature check, no I/O (JWKS cached).

Token size~0.5-2 KB

Sent on every request; keep claims small.

Access token TTL5-15 min typical

Limits exposure.

10

Trade-offs

Statelessness vs revocation

No lookup per request, but logout and account suspension take effect only at expiry unless you add a deny list (which reintroduces state).

HS256 vs RS256 / ES256

HS256 is simpler but every verifier can also forge tokens; asymmetric signatures let services verify without being able to sign.

11

Variants and related techniques

JWE

Encrypted JWTs when claims must be confidential.

PASETO

An alternative token format designed to avoid JWT's algorithm confusion issues.

Refresh token rotation

Each refresh returns a new refresh token; reuse of an old one signals theft and revokes the chain.

12

Common mistakes

  • Storing JWTs in localStorage.

    Fix: Any XSS can steal them. Prefer HttpOnly Secure cookies for browsers, or keep tokens in memory.

  • Long-lived access tokens.

    Fix: Keep them short and use refresh tokens.

  • Not checking aud and iss.

    Fix: Otherwise a token issued for another service is accepted.

  • Putting sensitive data in claims.

    Fix: Payloads are only base64 encoded; anyone can read them.

13

Interview questions

How do you log out a user with JWTs?

Delete the refresh token server-side so no new access tokens can be issued, keep access tokens short-lived, and for immediate revocation maintain a small deny list of token IDs (jti) until they expire.

Why use asymmetric signing for JWTs in microservices?

Only the auth service holds the private key and can issue tokens. Other services verify with the public key and cannot forge tokens, limiting damage if one service is compromised.

14

Practice problems

ProblemDifficultyWhat it trains
Decode a JWT and explain every claimEasyStructure.
Design access + refresh token rotation for a mobile appMediumLifecycle and theft detection.
Design revocation for 50M active tokensHardDeny lists and TTLs.