Search

↑↓ to move↵ to openesc to closetop 6 documentation results

Book a demoTry TokenTriage

In development · Explore the product preview. Join the launch list or book a walkthrough.

Browse docs

Rotate a runtime key

Replace the secret a running service sends, keeping its identity, with an overlap window so the rollout finishes before the old key stops.

How-to guideLast updated

On this page

A runtime key sits in the environment of a service that is serving traffic. Something has happened to it, or a quarter has passed, and it has to be replaced without a window where half your pods hold a credential that has stopped working.

Rotation gives you that: new secret bytes for the same service identity, with both the old and the new key accepted for a window you choose. Nothing downstream is re-pointed, because the identity a deployment is bound to does not change. Rotation preserves the original expiry; it does not restart the lifetime. To renew an expiring credential, mint a new key for the same service identity and retire the old one after your rollout.

What you need before you start:

You need Where it comes from
keys.manage in the organization the workspace_admin or credential_manager role, or an owner grant (who can do what)
the credential id (vk_…) the document the mint printed, or the credentials list for its service identity. The key’s own value is not usable here and no flag accepts one
a management key on TOKENTRIAGE_MANAGEMENT_KEY cloud key in the same organization
the deployment’s origin --base-url has no default, so a management CLI cannot address the wrong estate by guessing

You do not need the current key’s value, a maintenance window, or a new service identity.

1. Mint the successor

One command replaces the secret. --wait then polls until the new credential’s data-path grant has been acknowledged, and reports that on stderr, so the JSON document on stdout stays a document.

$ tokentriage cloud credential rotate \
    --base-url https://app.example.com --org org_ACME \
    --credential-id vk_ABCDEFGHJKLM --wait

The answer is written to stdout as JSON before anything else is attempted, and it is the only place the new secret ever appears: credential carries the metadata (kid, service_id, environment_id, gateways, readiness, operation_id), and secret carries the value once. The server keeps a digest of it. If you lose it, nothing can show it again, and the recovery is to rotate again.

2. Roll the new secret out inside the window

Both credentials work until the overlap closes. The default window is 15 minutes; the flag accepts 0 to 1440 minutes, and the lane’s own ceiling is 24 hours.

What you pass What happens to the predecessor
nothing accepted for 15 more minutes, then it lapses
--overlap-minutes N accepted for N more minutes
--overlap-minutes 0 closed as the rotation completes
--revoke-previous-now its grant is withdrawn during this call

--overlap-minutes and --revoke-previous-now are mutually exclusive, because “immediately” and “for N minutes” cannot both be the answer.

Use the window to deploy the new value the way you deploy any secret, and let the replicas turn over. Both keys resolve to the same service identity, the same environment and the same gateway allowlist, so a request is metered once whichever one it presented. A request that presents the successor while the predecessor is still accepted is disclosed on its decision row as rotation_grace, which is how you can tell a fleet has finished turning over.

Keep the overlap if you might roll back. A rollback does not resurrect a revoked predecessor. Rolling a deployment back to an image holding the old value works only while that value is still accepted.

3. Close the window when the rollout is done

Waiting for the window to lapse is a valid ending. To close it earlier, revoke the predecessor by id:

$ tokentriage cloud credential revoke \
    --base-url https://app.example.com --org org_ACME \
    --credential-id vk_ABCDEFGHJKLM

The answer is a typed acknowledgement reporting two separate facts: grant_withdrawn, whether the data-path grant was taken away, and revoked_at, when the credential was marked. They are separate because the first is the one that stops traffic.

New dispatch stops within a published bound of 30 seconds, which is push invalidation plus a bounded authority lease and its refresh, with clock skew counted in. It is not zero. Requests already sent to a provider finish and may cost money; revocation closes the door and does not reach through it. A second revocation of the same credential answers 409 rather than a quiet success.

What “ready” means, and what it doesn’t

A minted credential and a working credential are two states, and the word that separates them is published rather than guessed at.

Readiness Accepts requests? How you enter it How you leave it
pending no a mint or rotation is recorded, and the data-path grant is not acknowledged yet the grant is acknowledged, or the operation fails
ready yes the grant was acknowledged revocation, or expiry

There is no third word: “probably ready” is not an operational answer. --wait polls for up to 30 seconds by default, with a ceiling of 5 minutes, and cloud credential status --operation <ID> reads the same fact later. A wait that times out has not failed the rotation; it has stopped watching.

Revocation is terminal. This lane publishes no reversible disabled state between accepted and revoked, so a credential you revoke is replaced rather than re-enabled.

What a rotation cannot widen

The successor’s environment, its gateway allowlist and its actions are read from the predecessor’s own record rather than re-supplied on the rotate call. So a rotation cannot quietly add a gateway, and a credential that was admitted at one gateway in Development stays that after any number of rotations. Widening is a new mint, which names --env and --gateway and is a decision somebody made.

Two more checks run before a successor is minted: the application must still be active, and the environment must still be enabled. A rotation into a retired environment would carry a live credential past the decision to retire it, so it is turned away and revoke is the honest verb there.

What can go wrong

A 401 after the rotation, on some replicas only. Those replicas still hold the predecessor and the window has closed. Rotate again and give the rollout a longer --overlap-minutes.

A 403 naming a gateway or an environment. That is scope, not the key: a runtime credential is admitted at the gateways and the one environment its record names, and the rotation changed neither. Read connect your app for which selector headers a request carries.

Readiness stuck on pending. The mint is durable and the grant has not been acknowledged. Re-read it with cloud credential status; a request with the new key may still be turned away until the word is ready.

What this page doesn’t cover

Availability. These operations are part of this private test release. The 30-second bound is the published design bound; its end-to-end measurement across workers and restarts is part of the release’s own acceptance run.