--- checkId: check.attestation.clock.skew plugin: stellaops.doctor.attestor severity: fail tags: [attestation, time, ntp, quick, setup] --- # Clock Skew ## What It Checks Verifies that the system clock is synchronized accurately enough for attestation validity by comparing local time against the Rekor transparency log server's `Date` response header. Additionally collects NTP daemon status and virtual machine detection as discriminating evidence for root-cause analysis. **Threshold:** maximum allowed skew is **5 seconds** (`MaxSkewSeconds`). The check performs these steps: 1. Collects NTP status: daemon type (chronyd, ntpd, systemd-timesyncd, w32time), running state, configured servers, last sync time, and sync age. 2. Detects virtual machine environment: VMware, Hyper-V, KVM, Xen, or container. Checks whether VM clock synchronization is enabled. 3. Sends HTTP GET to `{rekorUrl}/api/v1/log` (configured via `Attestor:Rekor:Url` or `Transparency:Rekor:Url`, defaults to `https://rekor.sigstore.dev`) with 5-second timeout. 4. Extracts server time from the HTTP `Date` header. 5. Computes skew as `localTime - serverTime`. Results: - **Skew <= 5s**: **Pass** with exact skew value. - **Skew > 5s**: **Fail** with skew, NTP status, and VM detection evidence. Remediation steps are platform-specific (Linux: chronyd/ntpd/timesyncd; Windows: w32time; VM: clock sync integration). - **Server unreachable or non-2xx**: **Warn** (cannot verify, includes NTP evidence). - **No Date header**: **Skip**. - **HTTP exception**: **Warn** with classified error type (ssl_error, dns_failure, refused, timeout, connection_failed). - **Timeout**: **Warn** with 5-second timeout note. Evidence collected: `local_time_utc`, `server_time_utc`, `skew_seconds`, `max_allowed_skew`, `ntp_daemon_running`, `ntp_daemon_type`, `ntp_servers_configured`, `last_sync_time_utc`, `sync_age_seconds`, `is_virtual_machine`, `vm_type`, `vm_clock_sync_enabled`, `connection_error_type`. ## Why It Matters Attestation timestamps must be accurate for signature validity. Rekor transparency log entries include timestamps that are verified against the signing time. If the system clock is skewed beyond the tolerance, attestations may be rejected as invalid, signatures may fail verification, and OIDC tokens used in keyless signing will be rejected for having future or expired timestamps. Even a few seconds of skew can cause intermittent failures that are difficult to diagnose. ## Common Causes - NTP service not running (stopped, disabled, or not installed) - NTP server unreachable (firewall, DNS, or network issue) - System clock manually set incorrectly - Virtual machine clock drift (common when VM clock sync is disabled) - Container relying on host clock which is itself drifted - Hibernation/resume causing sudden clock jump ## How to Fix ### Docker Compose Docker containers inherit the host clock. Fix the host time: ```bash # Check host time date -u # Linux host: ensure NTP is running sudo timedatectl set-ntp true sudo systemctl start systemd-timesyncd # Windows host: resync time w32tm /resync /nowait ``` ### Bare Metal / systemd **Linux with chronyd:** ```bash # Start NTP service sudo systemctl start chronyd # Enable NTP synchronization sudo timedatectl set-ntp true # Force immediate sync sudo chronyc -a makestep # Check status timedatectl status chronyc tracking ``` **Linux with ntpd:** ```bash # Start NTP service sudo systemctl start ntpd # Enable NTP synchronization sudo timedatectl set-ntp true # Force immediate sync sudo ntpdate -u pool.ntp.org ``` **Linux with systemd-timesyncd:** ```bash # Start and enable sudo systemctl start systemd-timesyncd sudo timedatectl set-ntp true ``` **Windows:** ```bash # Start Windows Time service net start w32time # Force time resync w32tm /resync /nowait # Check status w32tm /query /status ``` **Virtual machine with clock sync disabled:** ``` Enable time synchronization in Hyper-V Integration Services or VMware Tools settings. ``` ### Kubernetes / Helm Kubernetes pods inherit node clock. Fix the node: ```bash # Check node time kubectl debug node/ -it --image=busybox -- date -u # Ensure NTP is configured on all nodes (varies by OS) # For systemd-based nodes: ssh 'sudo timedatectl set-ntp true' ``` ## Verification ``` stella doctor run --check check.attestation.clock.skew ``` ## Related Checks - `check.attestation.rekor.connectivity` -- clock skew check requires Rekor connectivity - `check.attestation.rekor.verification.job` -- verification job can fail due to clock skew - `check.attestation.transparency.consistency` -- timestamp accuracy affects consistency proofs