Service tokens

A service token is the credential a machine authenticates with. You mint one from Service tokens in the app, or from Integrations → Kubernetes, which also fills in the install commands around it.

Every token is scoped to one environment at Read or Write access, and carries an expiry. A second environment means a second token.

Read and write

Read lets the holder read the keys in its environment. Write includes read. There is nothing finer, because a machine credential describes what a pipeline does rather than a person’s standing in an organisation.

Every token expires

An expiry is required. The longest lifetime is set by whoever runs your kyvlt.sh — a year by default, and never more than that.

Ask for longer than the maximum and the mint is refused. It is not quietly shortened, so the expiry you were given is the one you asked for.

Renewal

A token can exchange itself for a successor, by presenting itself, before it expires. The successor is a new credential with a new expiry; the one that asked is revoked in the same act, so there is never a moment with two live tokens for one consumer.

The Kubernetes connector does this for you. It renews and writes the new value into the same Secret it reads from — no restart, nothing to do. A cluster projecting an environment today is still projecting it next year.

It starts trying at twice expiryWarningDays, which is fourteen days before expiry by default. Three stages, one setting:

WhenWhat
14 days leftrenewal beginsEvery sync retries until it works. At five minutes apart that is thousands of attempts.
7 days leftTokenExpiringThe warning means renewal has been failing for a week. Something is wrong that the cluster cannot fix.
0expiredThe projection stops. Mint a replacement and update the Secret.

Nothing about the successor can be wider: same environment, same access level, same name. There is no field to ask for more, so the worst a stolen token achieves is the access it already had, for longer.

Every renewal is its own audit record, naming the token it replaced. A chain renewing quietly for two years is what healthy looks like; one renewing from somewhere you do not recognise is what you are looking for.

Why expiry still matters when something renews

It does not stop an attacker holding a live token: they can renew it too. What it kills is the copy nobody is renewing — the one in an old backup, a log, a laptop that left with somebody. Those stop working on their date without anyone doing anything, and they are a large share of how credentials actually leak.

Against an attacker who does renew, the controls are different: every renewal is an audit record naming what it replaced, and a deployment can bound how long a chain runs before a person has to decide again.

With renewal, the number stops being about rotation and starts setting one thing: how old a live credential can get. The runway is fourteen days whatever it is, because the warning sets that and not the window.

So Integrations → Kubernetes does not ask. It mints for thirty days, renews from fourteen days out, and a credential in your cluster is never more than a month old. The choice is on this screen, for a credential nothing renews.

Tokens that outlive the maximum

Not every consumer is a cluster. A job that runs twice a year has nothing to renew it, and an Owner can mint a token deliberately past the deployment's maximum.

It is marked long-lived wherever it is listed, because that is the point: when an expiry is years away it has stopped being a control, and somebody seeing the credential in a list is what replaces it. The same list shows when each token was last used, and says so when nothing has presented one in a month.

There is still no token without an expiry. A date that arrives is a date somebody looks at the credential again; no date is never revisited by anything except an incident.

The value is shown once

The token appears exactly once, when it is minted. kyvlt.sh stores a hash of it and has no route that can produce the value again.

A token starts with kyvlt_, which makes it recognisable to secret scanners and to anybody reading a log who should not be seeing one.

Revoking

Revoke a token in the app. The next request that presents it is refused; nothing is cached, so there is no window to wait out.

A connector holding a revoked token reports Unauthorised and leaves whatever it last wrote in place.