Architecture Decision Record

0033. Clock and time-source trust

Context

Verification trusts "a clock" (ADR-0010): token exp/nbf/iat, TOTP windows (ADR-0015), and status-list freshness (ADR-0032) all depend on accurate time. If an edge node's clock can be skewed, an attacker extends expired tokens or defeats TOTP. The constitution leans on a clock as a trusted input, but its integrity has been an unstated assumption. This ADR makes it explicit and bounded.

Decision

  1. Bounded skew tolerance. Verification accepts a small, configured clock-skew window for exp / nbf / iat (and a tight window for TOTP); beyond the window it fails closed. The window is a stated budget, kept small because every second of slack is attacker slack.

  2. A trusted time source. Edge and core nodes synchronize via authenticated time (NTS — Network Time Security — or the platform's trusted time source), not unauthenticated NTP that a network attacker can spoof.

  3. Implausible-clock detection. A node whose clock is grossly off (failed sync, large drift) fails closed / is drained rather than issuing or verifying against a bad clock — a corrupt clock is a correctness fault, treated like one.

  4. This refines the Vör contract (ADR-0010: "a clock" is now "a trusted clock within a skew budget") and the deployment view (ADR-0024: time-source hardening is an operational requirement, not optional).

Consequences

  • Clock skew can no longer silently extend expired tokens or break TOTP; the trusted-clock assumption is explicit, bounded, and enforced.
  • The skew budget is shared by token expiry, TOTP, and status-list freshness (ADR-0032), so it is set once and small.
  • Time-source integrity becomes a deployment requirement (ADR-0024), and a node with a bad clock removes itself — consistent with the fail-closed posture throughout (ADR-0010).
  • Refines ADR-0010 and ADR-0024.