Scout — limitations
An honest, consolidated list of what Scout does not do and the known
residual risks, so the capability descriptions elsewhere in these docs aren't
read as more than they are. Grouped by area.
Functional gaps
| Gap |
Detail |
| At-most-once command delivery |
Commands travel over core NATS with no redelivery: a command published while a Scout is offline is not delivered and is not re-sent. The Hub's commands row for it expires after 1 hour, which now raises a warning naming the Scout and the command (counted toward Pipeline health) — visible, but still not retried automatically. The offline Scout itself is always operator-visible — last_seen and /readyz reflect real NATS reachability, and an always-on, decoupled "scout went dark" alert fires the first time it crosses the dark-alert threshold, independent of whether the separate, opt-in, destructive auto-disable (AGENT_STALENESS_HOURS) is configured. See Commands and When the link drops. |
| No Kubernetes / cert-manager collector |
Nothing in Scout collects K8s cert-manager evidence. |
| Linux x86-64 only |
Scout is built and supported for Linux x86-64: build.sh (run by the Hub's Download Installer button, or by hand) embeds the one prebuilt scout-linux-amd64 binary and installs a systemd service. No other operating system is supported. |
Security residuals
| Residual |
Detail |
| The policy signing key resides with the Hub |
Acceptance-policy verification defends against a compromised Hub control plane (API / DB / NATS) only while the policy signing key is isolated from it. Today the signing key is co-located with the Hub, so a full Hub compromise would also capture it; policy verification therefore does not defend against a full Hub compromise. The issuing CA's intermediate key is co-resident with the Hub as well, so isolating the policy signer alone would not close this gap — a fully compromised Hub could issue itself an accepted identity directly. What the layer does defend, always-on and fail-closed: network MITM, rogue endpoints, and revoked peer certificates. Policy age is deliberately not defended — a stale cache is reported, not refused, because gating the handshake on it locked out any Scout offline for more than an hour with no way to recover. A separate off-box signer with HSM support is planned as a future install-time option. |
| Scout runs as root |
The service runs as root inside a conservative systemd sandbox (PrivateTmp, ProtectKernel*, RestrictRealtime, LockPersonality). It does not run under a dedicated non-root user with scoped capabilities. |
Measurement / evidence caveats
- Scout doesn't score — it derives 10 findings + raw facts; all
weak-cipher/key/signature/self-signed judgments and the score/tier math are
Hub-side.
- TLS 1.3 ciphers aren't fully enumerated — only the one negotiated suite is
recorded (Go stdlib limit).
- OCSP staple is validated (parses, verifies to the issuer, status good,
fresh); an out-of-date or unverifiable staple trips the
-5 stapling-missing
finding, and a staple that reports the served cert revoked raises a fatal
cert_revoked finding that forces the score to 0 (like a name mismatch).
- Trust-store membership collection was removed, not merely limited —
local_trust_store_membership was pruned from the wire vocabulary, no
collector for it exists, and the Hub drops any attestation of that kind at
ingest (see Proof collection). The agent's
--trust-store-path flag still parses for back-compat but no longer feeds
anything (see Install → the flags
table).
- Key-custody metadata never reads keys or validates pairing — it's
filename-convention discovery +
stat().
- Cert discovery captures only DNS SANs (no IP/email/URI) and skips wildcard
SANs for auto-scan (raw certs are de-duped by fingerprint).
- Config discovery is glob-based, not real parsing —
nginx includes and
non-standard layouts are invisible.