Appearance
ts signing-key
List the keys that sign Turbo tickets and workload tokens, and rotate to a new one. Rotation is a routine, non-disruptive operation, but it is worth understanding what stays valid afterwards before you run it in production.
Usage
text
ts signing-keys
ts signing-key rotate [--force]Description
Every ticket a user holds and every workload token services present to each other is signed by the server's active signing key. ts signing-keys is the inventory: one row per key, with its id, its state, when it was activated, and — for a key on the way out — the last instant at which it is still accepted.
Exactly one key is Active at a time; that is the key new tickets are signed with. Keys in Overlap no longer sign anything but are still accepted for validation. Retired keys are accepted for nothing and are kept only as a record.
rotate is the only action. There is no command to print or export a key, by design: the listing is metadata only, the server never returns private key material over the API, and nothing you can run here will show you a private key.
What rotation does
Rotation generates a new key, makes it active immediately, and moves the previously active key into overlap with an expiry stamped on it. Tickets already in users' hands keep working — validators accept both the active key and any key still in overlap, and the published key set (JWKS) advertises both — so rotating does not sign anyone out, does not interrupt running sessions, and does not need a restart or a maintenance window.
Every process re-reads the key ring within about fifteen seconds, and re-reads immediately on encountering a key id it does not recognize, so a multi-node deployment converges on the new key on its own.
The overlap window
The overlap is sized to outlive every ticket the old key could have signed: the configured long-lived ticket lifetime (ticket-long-life-timeout, 30 days by default) plus a day of renewal allowance plus five minutes of clock skew. With the default setting that is roughly 31 days. The length is computed at the moment you rotate, from the setting as it stands then — changing the setting afterwards does not resize an overlap already in progress.
An hourly background job moves overlapping keys to Retired once their expiry passes. You do not need to clean anything up, and the retired rows stay in the listing.
If you are rotating because a key may be exposed
Read this part carefully, because rotation on its own is not containment. The old key remains able to validate tickets for the whole overlap window — that is the property that makes routine rotation safe, and the same property makes it insufficient for a compromise. Anything signed by the exposed key stays acceptable for about a month by default.
If you are responding to a suspected exposure, lower ticket-long-life-timeout with ts settings before you rotate, so the overlap the rotation computes is short, and expect existing long-lived tickets to be affected by that change too. Then rotate, and revoke the individual credentials that matter — API keys, and sign-ins you can force out — rather than relying on the key change to do it.
Confirmation and audit
rotate prompts for confirmation, stating that existing tickets remain valid through the overlap. --force (or -f) skips the prompt. When there is no terminal — a script, a scheduled job, a pipeline — --force is required rather than assumed, and the command fails instead of proceeding unasked.
Rotation is recorded in the audit log as SigningKeyRotated, attributed to the account that ran it, with the previous key id, the new key id, and the end of the overlap.
Options
| Flag | Description | Default/Values | Notes |
|---|---|---|---|
--force, -f | Rotate without confirming. | rotate only. Required when there is no terminal. |
Examples
bash
# What keys exist, and is anything still in overlap?
ts signing-keys
# Rotate, with the confirmation prompt
ts signing-key rotate
# Rotate from a scheduled job — --force is mandatory here, not optional
ts signing-key rotate --force
# Record what the rotation produced
ts signing-key rotate --force --format=json > rotation.json
# Check afterwards when the old key stops being accepted
ts signing-keys --csvOutput
text
KEY ID STATE ACTIVATED VALID UNTIL
9f3c1a7e5b2d48c0 Active 2026-08-01T14:22:07.1120000Z -
2b70e4d9c8a14f63 Overlap 2026-05-03T09:10:44.8830000Z 2026-09-01T14:22:07.1120000Z
c41d8fa2e6b7490a Retired 2026-01-12T11:02:19.4470000Z 2026-05-04T09:10:44.8830000ZRotation reports what changed in one line:
text
Rotated signing key 2b70e4d9c8a14f63 -> 9f3c1a7e5b2d48c0 (overlap ends 2026-09-01T14:22:07.1120000Z)Note the end of the overlap — it is the date on which tickets signed by the old key stop being accepted, and the date worth putting in a calendar if you rotated for a security reason.
--format=json returns the same key metadata as the table plus creation and retirement timestamps. It never contains key material.
Exit Codes
0 on success. -2 when rotate is omitted. -1 when a word other than rotate is given, when you answer no at the prompt, and when the command is run without a terminal and without --force. -4 when no account is signed in and -5 when the signed-in account is not a Server Administrator — key rotation is Server Administrator only.
Related Commands
- ts settings —
ticket-long-life-timeout, the setting that sizes the overlap. - ts audit — The
SigningKeyRotatedentries: who rotated, when, and to which key. - ts api-keys — The credentials to review separately when you rotate for a security reason.
