PATTERN Cited by 1 source
Stateless token via time-derived key¶
Shape¶
Stateless token via time-derived key is the design where a server hands a client an encrypted/sealed token carrying the server-side session state, and seals it with a key that is deterministically derived from a shared master secret plus a coarse time bucket — rather than stored in a replicated key ring or looked up from a session table. Any server in the fleet re-derives the same key for the same time bucket and can open a token it has never seen, minted by a peer it has never talked to.
seal_key(t) = KDF(master_secret, salt = time_bucket(t), info = "<domain-label>")
token = AEAD_seal(seal_key(now), { session_keys, ... }) # held by client
The token's key ID is the time-bucket integer itself, sent in the clear, so a receiving server knows exactly which derived key to reconstruct. A small acceptance window around the current bucket tolerates clock skew across the fleet at rotation boundaries.
Canonical instance: NTS stateless cookies at Meta¶
Meta's NTS service seals each NTS cookie
(which holds the C2S/S2C session keys) with
key = HKDF-SHA256(master, salt = BE32(day), info = "fbnts-cookie-seal-v1"),
where day is whole 24-hour periods since the Unix epoch — "no
timezone and no DST, and every host computes the same integer for the same
instant." That integer is the cookie's key ID; servers accept two days
back and one forward to cover skew around a rotation boundary. The result:
"no key ring, no replication, no session table, no shared state to fall out
of sync, and nothing for an attacker to exhaust." (Source:
sources/2026-10-06-meta-nts-authenticated-time-at-meta)
Why derive instead of replicate¶
The obvious alternative — a key ring replicated to every server — "turns
[the service] into a distributed state problem": the ring must be
distributed, kept consistent, and recovered after partition. Deriving the
key instead collapses that to a pure function of (master, time_bucket):
- Horizontal scaling is trivial — "adding a server is adding a server"; no new node needs to be seeded with existing key material.
- No cross-tier coordination — in NTS this is what lets the key-exchange tier and the NTP-responder tier be "different machines in different places" that "never exchange anything," because a cookie minted by one is openable by the other without any shared session record.
- Nothing to exhaust — no session table means no memory-exhaustion surface from unbounded client state.
The time bucket is the rotation schedule¶
Because the salt is a coarse time bucket, the seal key rotates automatically every bucket with no explicit rollover event — a key rotation whose cadence is the bucket width. The acceptance window (how many buckets back/forward a server will try) is the single tuning knob that trades key-lifetime against skew-tolerance: too narrow and clock-skewed clients fail at boundaries; too wide and a leaked derived key stays valid longer. Meta's 2-back/1-forward window is the concrete instance.
Design requirements¶
- Coarse, timezone-free bucket. Use an absolute monotone integer (Unix epoch days), not a calendar day, so every host derives the same bucket for the same instant regardless of locale/DST.
- Key ID travels in the clear. The receiver must know which derived key to reconstruct without opening the token first; the bucket integer is that ID.
- Skew-tolerant acceptance window. Accept a few buckets around the current one so clients and servers slightly out of sync still interoperate across a rotation boundary.
- AEAD seal, server-only. The token is sealed (AES-SIV in NTS) so only a server holding the master can open it; the client treats it as opaque.
- Client spends tokens appropriately. With no server session table, any replay/one-time semantics (NTS: spend each cookie once) are the client's responsibility.
Relationship to other patterns¶
- A specialization of concepts/stateless-compute — pushes session state out of the server and onto the client, but makes it cryptographic: the state is sealed so the client can hold it without being able to read or forge it.
- The seal-key derivation is a concepts/key-rotation whose schedule is implicit in the time bucket.
- Composes with patterns/protocol-algorithm-negotiation in NTS (the AEAD used to seal and to authenticate is negotiated at key establishment).
- Family resemblance to encrypted session cookies, Kerberos tickets, and signed/encrypted JWTs with rotating keys — the distinguishing move here is deriving the key from a time bucket so rotation and multi-server openability come for free without a shared key store.
Seen in¶
- sources/2026-10-06-meta-nts-authenticated-time-at-meta — canonical wiki instance: Meta's NTS cookies sealed with an epoch-day-derived AES-SIV key, 2-back/1-forward acceptance window, enabling a fully stateless, independently-scalable key-exchange + NTP-responder fleet.
Related¶
- concepts/stateless-compute — the property this pattern achieves cryptographically.
- concepts/key-rotation — the time bucket is an implicit rotation schedule.
- patterns/protocol-algorithm-negotiation — the AEAD is negotiated in NTS-KE.
- concepts/forward-security — the session keys the token carries are themselves per-session and ephemeral.
- systems/nts-meta-time-service — the canonical deployment.