Documentation menu

Key rotation

Rotation is a sequence of status changes in Vault. Every verifier learns the new public key before any data plane signs with it.

Steps

StepActionEffect
StageWrite k2 with status: staged.k2 appears in the public JWKS only.
WaitAt least the longest JWKS cache TTL (backends, proxy-cache, jwks_max_age) plus refresh_interval.Every verifier knows k2.
PromoteSet k2 active, k1 retired./keyset returns [k2, k1].
PropagateEach data plane reloads on its access_token_keyset_rotate_period timer.Data planes switch to k2 one by one; tokens from both keys verify.
WaitAt least the rotate period plus the longest token lifetime plus clock skew.No live token carries k1.
RemoveDelete k1.k1 leaves both documents.

Helper script

examples/vault/rotate.sh runs each step with the Vault CLI and jq:

export KEYSET_PATH=secret/jwks-bridge/default
./rotate.sh stage RS256      # prints the new kid
./rotate.sh promote <kid>
./rotate.sh show
./rotate.sh remove <old kid>

Staging guard

The bridge refuses to serve a key first until min_stage_duration (default 10 min) has passed since its staged_at. Until then it keeps the most recently promoted retired key of the same algorithm first and logs a warning. This protects against a promotion written too early. Keep min_stage_duration well above refresh_interval, so that bridge replicas that disagree for one refresh never matter.

Emergency revoke

Remove the compromised key from Vault. The public JWKS drops it after the next refresh and cache expiry; data planes drop it after their next reload. Verifiers that still cache it accept its tokens until their cache expires, so keep backend JWKS TTLs short.

Tested end to end

The end-to-end test runs this rotation with two hybrid data planes under continuous traffic and fails on any verification error.