Skip to content

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
Last updated · 854 distilled / 2,448 read