Skip to content
Credential renewal

Credential renewal

The security model recommends short validity windows for user credentials, and for good reason: the allowlist keys accounts, not users, so there is no per-user revocation short of removing a whole account. A user credential’s own exp is often the only lever that cuts off that one user, which argues for a short one. But a short TTL is a standing obligation. A credential that expires quickly has to be re-issued and redelivered quickly, over and over, for as long as the user exists. valiss ships no renewal pipeline. That loop is yours to build, and this page is what it has to do.

Who re-issues

Renewal is re-issuance, and re-issuance is a signing operation with the seed one level up. A user token is signed by the account seed (IssueUser); an account token is signed by the operator seed (IssueAccount). So the process that renews user credentials holds the account seed, and the process that renews account credentials holds the operator seed.

That places renewal firmly on the issuer side, off the serving hosts. The operator seed in particular never belongs on a production box (Seed custody), so account-token renewal runs in the issuer’s controlled environment, not on the fleet it feeds. Today the renewing process is your own code against the issuing API, or examples/minter driven from your automation: it re-issues deterministically from a manifest, and because its validity boundaries are absolute timestamps, re-issuing against an unchanged manifest reproduces the same window, so advancing the window is an explicit manifest edit. The valiss CLI (early development) is the issuer-side tool being built to own this ceremony; until it lands, library code or examples/minter is the path.

Renewal cadence

A token is honored until its exp plus the verifier’s skew slack (DefaultSkew, two minutes): the effective expiry is exp + skew, not exp. That slack is clock tolerance, though, not a renewal buffer, and you must not schedule renewal to land inside it. Treat exp as the hard deadline and renew well before it, leaving a lead time that covers the whole loop: signing the new credential, writing it to wherever the service reads it, and the service picking it up. Renew at exp minus that lead, and size the lead from your real redistribution latency plus margin, never from the two-minute skew.

Redistributing renewed credentials

Re-issuing is half the job. A fresh credential that never reaches the service is no better than an expired one, so the new credentials file has to arrive before the old one lapses. That is the same delivery problem as allowlist distribution, turned around to the client side: update the secret in your secrets manager and refresh the mount, or push the new file and hot-reload it, whatever your services read. The deadline is not “eventually”; it is exp minus your lead, per credential.

Staggering to avoid expiry herds

Tip

Jitter the exp across a batch issued together so lapses, and the renewals they trigger, spread over a window instead of a synchronized wave of expired rejections and a re-issue stampede.

Credentials issued together with the same TTL expire together. Issue a batch of users in one run with a fixed lifetime and they all lapse in the same minute, which produces two coincident problems: a synchronized wave of expired rejections (the transports map these to 401) as every affected client fails at once, and a renewal stampede as your pipeline tries to re-issue and redeliver the whole batch simultaneously.

Spread the expiries. Jitter the exp across a batch so lapses, and therefore renewals, distribute over a window instead of piling onto one instant. The same applies to account tokens under an operator: staggering their windows keeps a single re-issue run from having to touch every tenant at the same moment.

Watching the expiry horizon

Renewal is driven from the horizon, not from failures. By the time expired rejections appear, the outage for that holder has already started. Track the minimum time-to-expiry across the credentials you issue and alert while more than a lead time is still left, so renewal fires ahead of the lapse. The expiry-horizon signal is covered in Monitoring; renewal is the ceremony that signal should trigger.

Bearer tokens: TTL is the only revocation

Bearer user tokens sharpen every point above. A bearer token is accepted with no per-request signature, so proof of possession cannot help contain it, and the allowlist keys accounts, so it cannot cut off one bearer user either. That leaves exactly one lever that retires a leaked bearer token short of removing its whole account: its own expiry. For a bearer token the TTL is not merely an availability knob, it is the sole revocation mechanism and the length of your exposure window if the token is captured. Size it as tight as the client can tolerate re-issuing, and treat the renewal frequency it forces as a security parameter you chose on purpose.