Each server derives the sealing key from a shared master secret and the current day:
key = HKDF-SHA256(master, salt = BE32(day), info = “fbnts-cookie-seal-v1”)
Server-side, the public NTS list today runs to a few dozen entries, mostly national metrology institutes and internet infrastructure operators such as PTB, Netnod, and time.nl.
That indirection is why we use pool rather than server. A single server line gives you one association and one responder, which is a single point of failure – and NTP is a protocol that wants several sources so it can outvote a bad one. pool asks for maxsources independent assoc…
Android’s platform time sync is plain SNTP over UDP/123 – a fixed 48-byte packet with no extension-field handling, alongside NITZ and GNSS – so there is no NTS path in it.
NTS works in phases, and separating them is what makes it deployable.
Phase 1 – Key Establishment (NTS-KE): TLS 1.3 over TCP/4460, negotiated with ALPN ntske/1.
The key that seals them into a cookie is the shared one – the epoch day number from the derivation above, identical on every responder we run, stamped inside each cookie and never visible to the client.
We’ve previously written about building a more accurate time service at Meta scale – migrating from ntpd to chrony, going from 10 milliseconds to 100 microseconds, and opening time.meta.com to everyone.