JSON Web Key Set (JWKS)
A published set of public keys (as JSON) that lets anyone verify JWT signatures and lets services rotate signing keys without breaking every client.
What is a JWKS?
A JSON Web Key Set (JWKS) is a JSON document that publishes an identity provider’s public keys — the keys clients use to verify the signatures on JWTs it issues. When an OIDC provider signs an ID token or access token with its private key, any Service Provider that receives that token needs the matching public key to confirm the signature is genuine. The JWKS is how that public key is distributed: the provider hosts it at a well-known URL (typically /.well-known/jwks.json), and clients fetch it to validate tokens. It’s small, unglamorous plumbing that quietly makes the whole token-validation ecosystem work.
The problem it solves: key rotation without downtime
The reason JWKS exists as a set rather than a single key is key rotation. Security best practice says signing keys should be rotated periodically (and immediately if compromised) — but if a service hardcoded one public key, rotating the signing key would instantly invalidate every token and break every client until they all updated. The JWKS solves this elegantly. Each key carries a key ID (kid), and each JWT’s header names the kid that signed it. The set can hold multiple keys at once, so during a rotation the provider publishes both the old and new public keys; tokens signed by either verify correctly. Clients look at the token’s kid, find the matching key in the JWKS, and validate — no coordinated flag-day update required. This is what lets providers rotate keys continuously and transparently.
How clients should use it — and the pitfalls
The correct client pattern: on receiving a JWT, read its kid, fetch (and cache) the provider’s JWKS, select the key with the matching kid, and verify the signature — then check issuer, audience, and expiry. The pitfalls are specific and common. Not caching the JWKS means fetching it on every token validation, hammering the provider’s endpoint and adding latency — but caching too aggressively (or forever) means missing a key rotation and rejecting valid new tokens, so caches need sensible TTLs and a refresh-on-unknown-kid fallback. And the cardinal sin: fetching the JWKS over an untrusted channel or not pinning the issuer — if an attacker can substitute their own JWKS, they can forge tokens that validate, so the endpoint’s TLS and the token’s issuer claim are load-bearing security controls.
What people get wrong
- No caching or infinite caching — fetching per-request overloads the endpoint; never refreshing breaks validation the moment keys rotate.
- Ignoring the
kid: picking the wrong key (or assuming a single key) fails validation during rotations when multiple keys coexist. - Trusting an unverified JWKS source — if an attacker can swap the key set, they can forge valid-looking tokens; secure the fetch and pin the issuer.
Primary source: RFC 7517: JSON Web Key (JWK)
Historical figures and technical concepts for informational purposes only. Not technical, professional, legal, or financial advice. Sources: Official Documentation.