Vercel KMS Key Rotation
Rotation replaces an issuer's active signing key without changing the issuer ID or issuer URL, so relying parties keep using the same JWKS endpoint. KMS stages rotation so the JWKS CDN cache has time to invalidate and serve the new public key before that key starts signing, and it sets a kid header on every signature so verifiers that refresh the JWKS select the correct key automatically.
Rotating an issuer's key moves through three stages:
- Stage a pending key: KMS creates a new signing key and immediately adds its public key to the issuer's published JWKS. The pending key does not sign anything yet, which gives the CDN that serves the JWKS time to invalidate its cache so relying parties fetch the new public key before it is used.
- Activate: the pending key becomes the active signer and KMS starts signing new tokens with it. Activation is
automaticby default and happens once the JWKS CDN cache has had time to invalidate, or you can set it tomanualand activate the key yourself when you are ready. - Retire the previous key: when the new key activates, the previously-active key stops signing but stays in the JWKS for a grace period so already-issued tokens keep verifying. After the grace period elapses, KMS removes the key from the JWKS and prunes it.
An issuer can have at most one pending key at a time.
You control when the pending key becomes the active signer:
- Automatic activation (default): KMS activates the pending key once the JWKS CDN cache has had time to invalidate, so relying parties have already fetched the new public key.
- Manual activation: KMS leaves the key pending until you activate it, which lets you coordinate the switch with your own release.
You control the grace period with revokePreviousAfterHours, the number of hours after activation that the previous key keeps verifying. It defaults to 1 hour, and you should set it to at least the longest lifetime of the tokens you have signed. Set it to 0 to retire the previous key immediately at activation.
For an external issuer, rotate by staging a new PEM-encoded private key, for example when the upstream provider regenerates the key pair.
Rotation is a management operation, so unlike signing it is authorized with a Vercel access token rather than a deployment OIDC token. See Authentication for the difference. Stage a pending key by sending a POST to the issuer's keys endpoint:
curl -X POST \
"https://api.vercel.com/v1/kms/issuers/f47ac10b-58cc-4372-a567-0e02b2c3d479/keys" \
-H "authorization: Bearer $VERCEL_TOKEN" \
-H "content-type: application/json" \
-d '{ "activation": "automatic", "revokePreviousAfterHours": 24 }'The response includes the new key's keyId and a status of pending. When you use manual activation, activate the key once its public key has propagated:
curl -X POST \
"https://api.vercel.com/v1/kms/issuers/f47ac10b-58cc-4372-a567-0e02b2c3d479/keys/<keyId>/activate" \
-H "authorization: Bearer $VERCEL_TOKEN" \
-H "content-type: application/json" \
-d '{ "revokePreviousAfterHours": 24 }'To rotate an external issuer, include the new key material as an importKey (a PEM-encoded private key) when you stage the key.
Was this helpful?