railiance-clock/specs/railiance-clock-v0.1.md
tegwick 7af595b2cc Specify candidate signed time samples and trust lifecycle
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbc-910e-77a0-b336-3130194350b3
2026-09-14 15:13:44 +02:00

11 KiB

Railiance Clock specification — draft v0.1

Status: proposed protocol and consumer contract, 2026-09-14. Normative words MUST/SHOULD describe the proposed acceptance contract; no runtime or cross-owner adoption is implied. RCLK-WP-0002 must resolve the named review gates before implementation is used for security decisions.

1. Time domains

  • Authority UTC: railiance01's externally disciplined estimate with measured health and conservative error bound. A platform-approved leap/UTC convention must match upstreams and consumers; no silent mixture of smeared and unsmeared time.
  • Local wall time: OS-reported timestamp, zone/offset and clock-domain identity; descriptive only until attributed. A timezone conversion does not fix clock skew.
  • Local monotonic time: elapsed-time measurement in one boot/process domain.
  • Receipt time: the receiving service's time interval at ingestion, not occurrence.
  • Causal order: explicit event IDs, sequence numbers and predecessor references; overlapping time intervals are not a total order.

UTC output uses RFC3339 with Z. Wire numerical units, precision and representation must be fixed in the reviewed schema; integers/decimal strings are preferred over unbounded binary float timestamps. Reject NaN, infinity, overflow and unknown units.

2. Authority and deployment boundary

The initial authority is one service on railiance01. It MUST obtain host clock health through a reviewed adapter and expose upstream error/holdover state. It MUST stop advertising usable bounded time if its clock is unsynchronized or its error bound is unsupported. Multiple upstreams SHOULD be independent; a majority of endpoints is not proof of independence or accuracy.

A process restart, detected UTC step or authority continuity break invalidates the previous mapping and changes an authority epoch. Epochs are continuity labels, not a license for rollback. Clients must reacquire live evidence and enforce any persisted rollback floor before using a new epoch. A claimed epoch change alone cannot justify accepting arbitrarily older time. Exact rollback recovery is a review gate; v0.1 must fail closed until reviewed recovery if continuity is unknown.

Host synchronization/NTP configuration remains platform/host-owner work. Service packaging, private exposure and production admission follow Railiance contracts. A dedicated rapp/reef placement declaration is deferred until the runtime exists.

3. Sample exchange proposal

Candidate transport: bounded HTTPS POST /v1/time-samples, no redirects or cache. The final endpoint/schema and signing profile are RCLK-WP-0002 deliverables.

Request binds protocol version, a cryptographically random single-use nonce and requested authority. It carries no bearer secrets or arbitrary caller URLs. Client records monotonic send and receive instants itself; it MUST NOT trust its wall clock to establish sample freshness.

Response binds version, nonce, authority ID, epoch, key ID, server UTC receive and send instants, upstream uncertainty, clock-quality state and maximum sample age. All those fields MUST be authenticated as one statement with unambiguous encoding, domain separation and algorithm/key allowlists. Select an established signing format/profile during review; do not invent custom crypto or reuse a provider key. The client maintains outstanding nonces and discards them after one response, timeout or restart. A replay with a new locally invented receive time is refused.

TLS authenticates transport using the supported trust store. A signature proves who made the statement, not UTC truth; quality/uncertainty checks remain mandatory. Pin authority and key scope through an admitted bootstrap; do not fetch an untrusted key from the same response and thereby trust it.

No-cache headers are defense in depth. Fresh nonces, elapsed-time bounds and strict parsing provide freshness. Limit request/response size and sample rate; serve health metadata without exposing host topology or secret material.

4. Conservative sample interval

Let m0/m1 be client monotonic send/receive values, R = m1 - m0; s2/s3 server receive/send UTC values; and e the accepted server UTC error bound. Reject negative/oversized R, backwards s2/s3, epoch changes during the request, unusable quality and any unbounded error. Account for client timer error and drift over the round trip in R's upper bound Rmax.

At receipt, a deliberately conservative bound is:

lower = s3 - e
upper = s3 + e + Rmax

This assumes true time of server send is within s3 ± e and the response transit cannot exceed the bounded whole exchange. It does NOT assume symmetric routes. Do not subtract server processing time to tighten the bound without validating its own clock/error assumptions. Midpoint estimation may be offered, but its reported uncertainty must enclose the interval above. A delayed authentic response widens the interval or times out; a nonce does not eliminate delay attacks.

For elapsed monotonic d after receipt, propagate both bounds by d and widen by a reviewed oscillator/timer drift bound rho*d plus resolution/scheduling error. No generic drift coefficient is assumed proven on all WSL/VM hosts. Unsupported monotonic behavior yields unusable state. Multiple samples may improve availability; intersection is permitted only if all required continuity/error assumptions hold. Contradictory intervals trigger reacquisition/diagnosis, not averaging away conflict.

5. Client interface and lifecycle

Proposed Clock.read() returns:

  • status: usable, holdover, unavailable or untrusted;
  • lower_utc, upper_utc and optional midpoint;
  • authority ID, epoch, policy version and sample ID;
  • monotonic sample age, uncertainty and clock-domain identifier;
  • reason code and next refresh requirement.

Only usable or explicitly admitted bounded holdover can reach time checks. There is no implicit fallback to OS wall time. Clock.elapsed() is separate from UTC. The client exposes local-to-authority offset as an observation with capture window, not a permanent global correction. Wall-clock steps do not move an established monotonic mapping, but invalidate local-wall event translations across the step.

v0.1 MUST invalidate on process restart, boot-domain change, suspend/resume, monotonic discontinuity, sample expiry, authority revocation or unbounded drift. Suspend detection/appropriate OS clock selection is a platform-specific proof obligation. If undetectable, that platform is unsupported for offline/security use; periodically querying is not evidence that suspension cannot occur. Offline holdover is disabled for the first protected-use pilot unless the owner accepts measured drift and maximum age. Authenticated but unhealthy is not usable.

6. Validity and authorization consumers

The clock supplies evidence, not an allow/deny authorization verdict. A reviewed consumer can conservatively require lower_utc >= not_before and upper_utc < expires_at, subject to its artifact's exact boundary semantics. Unknown/overlapping bounds require refresh, bounded wait or refusal. Never alter signed fields, backdate an observation, enlarge expiry, or resurrect a consumed approval.

Approval Engine's atomic consume and execution-time checks remain authoritative. A correct timestamp does not resolve replay, revocation or check-to-use races. Bind the complete action using existing owner protocols and recheck validity at the protected side effect. Prefer issuer/validator/executor colocated on disciplined infrastructure; the workstation initiates an operation without impersonating the server's time authority or decision identity.

Current secrets-engine explicitly refuses shifted validation clocks. Adoption of this interface requires a reviewed contract change plus native positive/negative proof; this specification cannot be used as a local bypass. Third-party JWT, TLS, browser, SSH and Kerberos validators are unaffected unless explicitly adapted. Small artifact-specific leeway is separate from measurement uncertainty and must not be counted twice or treated as unlimited drift tolerance.

7. Trust bootstrap, offline use and failure

An application clock cannot by itself repair TLS validation when OS time makes certificates appear invalid. v0.1 requires functioning transport trust at bootstrap or a separately admitted authenticated transport with its own validity handling. Do not disable certificate dates/verification or use an HTTP Date header as authority. Trust-key provisioning, expiry, rotation, revocation and freshness under wrong OS time must be designed together. Static public keys without a bounded revocation story do not solve offline trust. On unavailable revocation evidence, security consumers follow their adopted fail-closed policy.

Trusting a live service on one host creates a single failure/compromise domain. A nonce protects against replay, not authority compromise or a dishonest upstream. Compromise requires revocation and an explicit new trust admission; rollback of service code alone is not recovery. A previous signed sample must not become fresh because its verifier restarted.

8. Event attribution

Retain immutable original local timestamp, UTC offset/timezone when known, producer identity, clock domain, event ID and local sequence/causal references. Append a separate mapping record with sample reference, estimated UTC interval, translation method/version and assumptions. Store receiver-assigned UTC interval separately.

Mapping applies only within its evidenced clock domain and time interval. A sample obtained now cannot calibrate an arbitrary event from yesterday. Uncalibrated events remain unknown. Report intervals as overlapping when their order is uncertain. Clock corrections append observations; do not rewrite originals or Git history. Git author/committer dates remain provenance supplied under Git's own semantics.

9. Operations and observability

Metrics: authority quality, upstream dispersion/age, epoch changes, usable client interval width, sample RTT/age, refresh failures and invalidation reasons. Logs contain sample identifiers and sanitized reasons; no tokens, keys or callback URLs. Separate service liveness from time usability and security-consumer admission.

Failure exercises cover source outage, wrong source time, service restart, bad signature/nonce, delayed responses, drift, suspend and authority rollback. Retain measured thresholds and evidence in versioned policies. No production SLO or ppm bound is claimed until RCLK-WP-0004 measurements justify it.

10. Open decisions before implementation admission

RCLK-WP-0002 owns transport/signature schema, trust bootstrap/revocation, leap convention, authority health/error model, per-platform monotonic semantics, consumer policy interface and exact NetKingdom role/PEP classification. RCLK-WP-0003 implements the adopted contract in isolation; RCLK-WP-0004 owns production placement, thresholds and native consumer migration. These are explicit dependencies, not placeholders to bypass while shipping.

References

Detailed wire/trust review candidate: sample profile. This supplies proposed field/encoding choices; owner admission remains RCLK-WP-0002.