Implement remediation-aware health checks across all Doctor plugin modules (Agent, Attestor, Auth, BinaryAnalysis, Compliance, Crypto, Environment, EvidenceLocker, Notify, Observability, Operations, Policy, Postgres, Release, Scanner, Storage, Vex) and their backing library counterparts (AI, Attestation, Authority, Core, Cryptography, Database, Docker, Integration, Notify, Observability, Security, ServiceGraph, Sources, Verification). Each check now emits structured remediation metadata (severity, category, runbook links, and fix suggestions) consumed by the Doctor dashboard remediation panel. Also adds: - docs/doctor/articles/ knowledge base for check explanations - Advisory AI search seed and allowlist updates for doctor content - Sprint plan for doctor checks documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4.6 KiB
checkId, plugin, severity, tags
| checkId | plugin | severity | tags | |||||
|---|---|---|---|---|---|---|---|---|
| check.attestation.clock.skew | stellaops.doctor.attestor | fail |
|
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:
- Collects NTP status: daemon type (chronyd, ntpd, systemd-timesyncd, w32time), running state, configured servers, last sync time, and sync age.
- Detects virtual machine environment: VMware, Hyper-V, KVM, Xen, or container. Checks whether VM clock synchronization is enabled.
- Sends HTTP GET to
{rekorUrl}/api/v1/log(configured viaAttestor:Rekor:UrlorTransparency:Rekor:Url, defaults tohttps://rekor.sigstore.dev) with 5-second timeout. - Extracts server time from the HTTP
Dateheader. - 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:
# 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:
# 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:
# 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:
# Start and enable
sudo systemctl start systemd-timesyncd
sudo timedatectl set-ntp true
Windows:
# 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:
# Check node time
kubectl debug node/<node-name> -it --image=busybox -- date -u
# Ensure NTP is configured on all nodes (varies by OS)
# For systemd-based nodes:
ssh <node> '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 connectivitycheck.attestation.rekor.verification.job-- verification job can fail due to clock skewcheck.attestation.transparency.consistency-- timestamp accuracy affects consistency proofs