Operator token lifecycle
The operator token is the trust domain’s self-signed policy statement: its
epoch, its validity window, its extensions, signed by the pinned operator key
over its own public key. A verifier configured with it (WithOperatorToken, or
a keyring entry) enforces that policy on every request. One field on it deserves
its own runbook, because getting it wrong takes the whole domain down at once:
its exp.
The exp bounds the whole domain
Warning
When operator policy is enforced, the operator token’s exp gates every
request in the domain. Once it lapses (two minutes past exp, the skew
grace), every account and user on every verifier fails with “the trust domain
is closed.” This is the one expiry whose lapse is a full outage, not a partial
denial.
When the operator token expires, nothing beneath it verifies. The verifier
checks the operator token’s window before it checks anything else, and a lapsed
one is rejected with operator token expired: the trust domain is closed. That
rejection is not per tenant or per server. It is simultaneous and total: every
account, every user, on every verifier that pins this domain, the moment the
token ages past its exp. The only slack is the skew window (DefaultSkew, two
minutes), the same grace applied to every expiry check. Two minutes after exp,
the domain is dark.
This is deliberate. Bounding the domain on the operator token’s exp forces a
periodic renewal rather than letting a domain drift indefinitely on one key
state. The cost of that property is that the exp is a domain-wide deadline you
must never miss.
Sizing the TTL against on-call reality
The exp is a deadline, so size it against how fast you can actually meet a
deadline, not against a calendar. Before exp you must issue a fresh operator
token, distribute it to every verifier, and confirm adoption. The TTL has to be
comfortably longer than that whole cycle, including the human parts: paging the
on-call, the on-call responding, and retrieving the operator seed if it is not
already to hand (see The seed dependency).
- Too short and you are running renewal ceremonies under time pressure, and a single missed page closes the domain.
- Too long and you weaken the periodic-renewal property that is the reason the deadline exists.
Pick a TTL where renewal duration plus worst-case on-call response plus seed retrieval fits inside it several times over. That headroom is what the alert (below) spends.
Renewing before expiry
Renewal is issuing a fresh operator token at the same epoch with a new exp.
Same epoch is what makes it a renewal and not a rotation: it does not touch
account or user credentials, only the domain’s clock. (Advancing the epoch is
the rotation ceremony; do not conflate
them.)
- Re-issue the operator token.
IssueOperator(operator, WithName(domain), WithEpoch(current), WithExpiry(next))with the same epoch and a freshexp. - Distribute it to the verifiers. On a single-anchor verifier, rebuild it
with
WithOperatorToken(newToken). On a keyring verifier, rebuild the keyring with the renewed token in place of the old one: the keyring keys entries by(operator key, epoch), so the renewed token occupies the same slot as the one it replaces, andNewKeyringrejects registering a different token at an already-occupied(key, epoch)pair. Renewal is a rebuild and swap of the keyring, not an overlay. - Verify adoption. Confirm the
operator token expiredsignal stays at zero and the expiry horizon (below) resets to the newexpacross the fleet. Renewal is complete when every verifier reports the fresh window, not when the token was handed out.
The alert
Alert on the operator token’s expiry horizon: how much time remains before
exp. The lead time must be at least the renewal duration plus your response
time, so that when it fires you still have room to issue, distribute, and
confirm before the domain closes. Because renewal needs the operator seed, fold
seed retrieval into that lead time when the seed is not immediately available.
Wire this to the domain’s exp and to the operator token expired rejection
count; see Monitoring for both signals.
When it has already lapsed
If the alert was missed and the token expired, the domain is already down: every
request is failing operator token expired: the trust domain is closed, and it
has been since two minutes past exp. Recovery is renewal under fire.
- Re-issue from the operator seed.
IssueOperatorat the same epoch with a freshexp. This requires the operator seed; if it is in cold storage, retrieving it is the long pole and the domain stays down until it is in hand. - Push to every verifier, single-anchor or keyring, as in the renewal procedure above.
- Watch the recovery signature. As verifiers adopt the fresh token, the
authentication error rate collapses back to baseline: the
operator token expiredrejections stop and normal traffic resumes. A fleet that recovers unevenly tells you which verifiers have not yet taken the new token.
Because the only grace is the two-minute skew, there is no gentle warning at
runtime: the alert firing ahead of exp is the warning, and it is the one you
must not miss.
The seed dependency
Every path above (renewal and emergency recovery alike) requires the operator
seed, because IssueOperator signs with the operator key pair. The seed is the
ultimate secret in the system and belongs in custody, not on a server (see the
Security model and Custody). The
operational consequence is direct: if the seed lives in cold storage, the alert
lead time must include the time to retrieve it. An alert horizon that assumes
the seed is at your fingertips is too short by exactly the retrieval time, and
that gap is discovered at the worst possible moment.
What is manual today
Issuing an operator token is programmatic only. The minter example issues
account and user credentials; it does not produce operator tokens. Renewal and
emergency recovery are hand-written IssueOperator calls against the library,
with hand-maintained keyring rebuilds and distribution. The planned valiss CLI,
holding the operator identity in its per-operator store, is what will own
operator-token issuance and renewal as first-class verbs; until it ships, the
procedures here are manual.