Keys & their lifetimes
A cluster has few long-lived secrets, and most of its keys die with the process that made them. This page lists them all, shortest-lived first.
| Key | Made by | Lives | Replaced |
|---|---|---|---|
| Sealed-session keys | Noise NK handshake (a node to a peer: IK), both sides’ ephemeral keys | 1 hour at most; 10 minutes idle | The client opens a new session |
| Transport key (X25519) | Each node, in memory, at start | Until the process stops | On restart; clients get stale_transport_key and attest again |
| Receipt key (Ed25519) | Each node, on its first start; kept in its data directory wrapped under K_r; signs receipts and the sessions the node issues | As long as the node’s data directory | When a node is replaced (a new data directory): verify_app_cluster returns the new key, and the node’s sessions refresh |
| Session token | The node that signs someone in, with its receipt key | 15 minutes | Exchanged with a refresh token |
Refresh token (rt_…) |
The same node; only its hash is stored | 30 days | The first refresh once it is an hour old returns a new one; younger, it is kept and nothing is logged |
| Operator key (Ed25519) | The operator (mdma); only the public half is in the system state | The cluster’s lifetime | Not rotated yet |
API key (cal_…) |
Generated for an account; only its hash is stored | Up to 1 year (ttlSecs) |
Revoked by the account, or expires |
| Passkey | The person’s authenticator | Until removed from the account | Added and removed by the account (at least one stays) |
| Storage key K_r | HKDF of the KMS key and the cluster name | One mero-tee release (each has its own mero-kms) | Replaced with the release; it only wraps K_c |
| Cluster key K_c | The founding node’s K_r; handed to new nodes by attestation | The cluster’s lifetime | Not rotated |
Sessions are signed by the node that issued them
Section titled “Sessions are signed by the node that issued them”Each node signs the sessions it issues with its own receipt key (Sessions); no session-signing key is shared or replicated. Every node attests each peer’s receipt key at its registered address ahead of time and verifies tokens from that, so a node’s sessions survive its restart (same key) and outlive it while it is down or frozen. They stop verifying when the node is removed, or replaced on a new data directory (a new key): clients refresh (Failover).
Revocation
Section titled “Revocation”Revocations are system commands, so they hold on every node once applied, and because a credential is judged on fresh system state, they hold before the next request anywhere.
| Event | What ends |
|---|---|
POST /auth/logout |
This session: its refresh tokens go, its tokens stop verifying |
POST /auth/logout-all |
Every session of the account |
| Removing a passkey | Every session opened with that passkey; tokens of a session whose passkey is gone are also refused directly |
| A refresh token presented again after it was exchanged | Its session (RefreshReused): someone else holds a copy |
| Revoking an API key | That key, at once |
A revoked session id is remembered for an hour (REVOKED_SESSION_KEEP_SECS),
past the life of any token it could have minted, and then forgotten; exchanged
refresh tokens are forgotten once they would have expired.
Signature counters
Section titled “Signature counters”A passkey assertion reports a signature counter. SetSignCount accepts only a
counter that moves forward, whatever order sign-ins committed in, so a cloned
authenticator replaying an old counter is refused; an authenticator that
reports zero every time records nothing. It carries the assertion that
reached the counter and is checked at apply, so no node can set a counter
the authenticator never reached.
What does not rotate yet
Section titled “What does not rotate yet”- K_c is fixed for the cluster. K_r changes with every release, but it only wraps K_c (The cluster key). Rotating K_c would mean re-sealing every value and snapshot; nothing does that today. Keys per app are not done.
- A rollback counter — something that would let a node notice it was restarted on an older copy of its disk — is not done.