How JWTs work
A JWT is three Base64URL-encoded parts joined by dots: header.payload.signature. The header names the signing algorithm, such as RS256. The payload holds claims: registered ones like iss (issuer), sub (subject), aud (audience), exp (expiry), and iat (issued at), plus custom claims such as email, roles, or tenant. The signature covers the first two parts, so any tampering invalidates the token.
Signing comes in two families. HMAC (HS256) uses one shared secret for both signing and verification, which suits a single application. Asymmetric algorithms such as RSA (RS256/384/512) or ECDSA sign with a private key while anyone holding the public key can verify, which is why identity providers publish their keys in a JWKS endpoint and every microservice can validate tokens independently. Crucially, a standard JWT is signed but not encrypted: anyone who obtains it can read the payload, so secrets never belong in claims.
Why JWTs matter
JWTs are the workhorse token format of modern identity. OpenID Connect ID tokens are JWTs by specification, OAuth 2.0 access tokens frequently are, and APIs across the industry accept them as bearer credentials. Their appeal is statelessness: a service validates the signature, checks expiry and audience, and trusts the claims without a session store or a network call, which fits microservices and horizontal scaling naturally.
Statelessness is also the trade-off to manage. A signed token remains valid until it expires, so revoking access mid-lifetime requires extra machinery. The practical pattern is short-lived access tokens, minutes rather than hours, refreshed from the identity provider, which re-evaluates the user's status at each refresh. Anything requiring instant revocation on its own is better served by server-side sessions or token introspection.
JWTs in practice
Validation discipline is everything. Verify the signature against the issuer's published keys, pin the expected algorithm rather than trusting the token's header (the alg=none and algorithm-confusion attacks exploit exactly this), and check iss, aud, and exp on every request. Keep tokens out of browser local storage where scripts can read them; httpOnly cookies or in-memory storage are safer homes.
Keep payloads lean, since the token travels with every request, and rotate signing keys on a schedule that clients can follow via JWKS. Monosign issues JWTs signed with RSA-SHA256, SHA384, or SHA512 for its OIDC and API integrations, with published keys that services validate independently.