Lion Cipher Lab
Rotate JWT signing keys with a JWKS endpoint
- Identity & Access Management
- Intermediate
- ~45 min
- Free · no account required
Why it matters
Every modern login hands your app a JWT, and every JWT is trusted only because its signature checks out against a key your app fetched from the identity provider's JWKS endpoint. That one cryptographic key is a single point of failure: if it leaks, an attacker can mint tokens that impersonate anyone until the key is retired. So keys must rotate — on a schedule for hygiene, and immediately on compromise. But you cannot just swap the key, because tokens already signed with the old key are still valid until they expire; yank the key and you log out the entire internet at once. The professional…
What you'll learn
- understanding JWT structure (header.payload.signature) and claims
- asymmetric (RS256) signing: private key signs, public key verifies
- generating an RSA key pair and assigning it a key id (kid)
- publishing public keys as a JWKS (JSON Web Key Set)
- verifying a token by selecting the key by its kid
- zero-downtime signing-key rotation with an overlap window
- algorithm pinning and defeating the alg:none and RS256->HS256 attacks
- enforcing exp/nbf/iss/aud with clock-skew leeway
Steps in this lab
- The words first: JWT, claims, RS256, kid, JWK, JWKS
- Why signing keys must rotate — and why you cannot just swap them
- Install the tools and confirm the versions
- Open one Python session and set up the helpers
- Generate the first key, mint a token, and publish a JWKS file
- Verify a token CORRECTLY: select the key by kid, pin the algorithm
- Rotate with an overlap window: add kid2, prove BOTH keys work
- Retire kid1: prove old tokens now fail and new ones still work
- Footgun A: alg:none and the RS256->HS256 confusion attack
- Footgun B: expiry must be enforced (and the leeway subtlety)
- Optional: serve the JWKS over HTTP like a real IdP
- Judgment: when to rotate, how long to overlap, and how a pro consumes a JWKS