Safeguard
Security Guides•

How do you rotate JWT signing keys without breaking clients?

Publish the new key in your JWKS first, sign with it later, and keep the old public key until old tokens expire. Steps, timing and the kid header.

Safeguard Security Team
4 min read

Publish the new public key in your JWK Set first, start signing with it after clients have had time to fetch it, and keep the old public key published until every token it signed has expired. The kid header tells each verifier which key to use, so both keys can live side by side.

The moving parts

A JWT signing setup has three pieces:

  • A private key that the issuer uses to sign tokens.
  • A JWK Set (JWKS), a JSON document at a jwks_uri that lists the matching public keys.
  • A kid (key ID) in each token header that names which public key to use.

The OpenID Connect Core spec describes rotation using exactly these pieces. The signer publishes its keys in a JWK Set at its jwks_uri and includes the kid of the signing key in the header of each message. Keys are rolled over by periodically adding new keys to the set. The signer starts using a new key at its discretion and signals the change through the kid.

The verifier side

The verifier goes back to the jwks_uri to re-fetch keys when it sees an unfamiliar kid. That is the signal that a rotation happened. The spec also says the JWK Set should retain recently decommissioned signing keys for a reasonable period to ease the transition.

A safe rotation sequence

  1. Generate a new key pair and give it a new kid. Do not reuse an old identifier.
  2. Publish the new public key in the JWKS next to the old one. Do not sign with it yet.
  3. Wait longer than your longest cache lifetime for the JWKS, so verifiers have a chance to see it. Check your own cache headers and library settings.
  4. Switch signing to the new key. New tokens carry the new kid.
  5. Keep the old public key in the JWKS until the longest lived token it signed has expired, plus any clock skew leeway.
  6. Remove the old public key, then securely destroy the old private key.

Step three is where most outages start. If you sign with a key that verifiers cannot see yet, valid tokens fail.

Verifier checklist

  • Look the key up by kid, never by trusting a key URL placed inside the token. RFC 8725 warns that blindly following a jku header can enable server side request forgery, and advises matching such URLs against an allow list.
  • Cache the JWKS, but refetch on an unknown kid.
  • Limit refetches so an attacker sending random kid values cannot make you hammer the issuer.
  • Fail closed: if no key matches, reject the token.
  • Pin the algorithm per key instead of reading it from the token alone.

Emergency rotation

If a private key leaks, the calm sequence does not apply. Remove the compromised public key from the JWKS right away and accept that tokens signed with it will fail. Shorter token lifetimes make this less painful, because fewer valid tokens are in flight.

Quick check

How often should I rotate signing keys?

The sources here do not set a number. Pick a schedule you can run without incidents, and practise it, so an emergency rotation is a routine one.

Can two keys be valid at the same time?

Yes. A JWK Set can list several keys, and the kid in each token header says which to use. That is how rotation avoids downtime.

Try it yourself

Click through it at your own pace, or open it full screen. Look for the JWT and JWKS libraries in the inventory, since their versions decide how key caching and refetching behave.

Safeguard's SBOM and dependency scanning gives you that inventory for your own repositories, and a free scan is a quick way to see it.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.