You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Decide the MCP URL policy (HTTPS, allowlist, ADR?) #108
The policy half of audit finding #4: what restrictions apply to operator-configured MCP fingerprinting URLs? This constrains what operators may configure, so it is a product/config-surface decision (HITL), not a straight fix. SSRF exposure from configured URLs is the driver.
To settle:
HTTPS-only? With a loopback/localhost exception for local dev (the demo fingerprints local MCP servers)?
Operator allowlist: hard-require, or optional with default-warn?
Does the change warrant a short ADR (it changes the daemon's operator-facing config contract)?
Resolution records: the decided policy, ADR yes/no (and number if yes). The implementation ticket is blocked on this.
Resolution (grilling session with Toni, 2026-07-09)
Decided policy, three parts:
HTTPS required except loopback. Non-loopback http:// MCP URLs are rejected at daemon startup with a typed, loud error; http:// stays permitted for localhost / 127.0.0.0/8 / ::1. No --insecure-allow-http escape hatch in v1.0 — remote-plaintext MCP is not a supported shape even behind friction (the ADR-0012 escape-hatch precedent existed because the demo needed it; the demo doesn't configure MCP at all).
Redirect-following disabled (reqwest::redirect::Policy::none()) on the daemon's HTTP client. This is the half with a genuine remote attacker: a compromised configured server could 30x the fingerprinting POST to internal endpoints (Cloud Run metadata server) and the response would be canonicalised and persisted into the commit tree — SSRF plus exfiltration into the object store, unstoppable by any startup URL check. A redirect response becomes a per-server fingerprint error naming the Location target. The shared DaemonState.http client gets a comment pinning this: future non-MCP uses that want redirects must build their own client.
No separate allowlist — addressed by construction, not skipped.--mcp name=url is already an explicit operator enumeration; with schemes validated and redirects off, the destination set equals the configured list exactly, so a second host list would restate the first with extra ceremony. The reasoning goes in the ADR so the audit finding reads as consciously closed.
ADR: yes — ADR-0016, a one-pager in ADR-0001's format, drafted as part of the implementation ticket. It changes the operator-facing startup contract (previously-valid remote http:// URLs now abort startup) and pins the SSRF posture in one citable place.
Facts surfaced during the session: MCP URLs enter only via the --mcp startup flag (operator-controlled, never socket input); run-demo.sh passes no --mcp at all, so the demo is unaffected; the current client follows up to 10 redirects (reqwest default) — the live vector item 2 closes.
Activity
tonibergholm commentedon Jul 9, 2026
Resolution (grilling session with Toni, 2026-07-09)
Decided policy, three parts:
http://MCP URLs are rejected at daemon startup with a typed, loud error;http://stays permitted forlocalhost/127.0.0.0/8/::1. No--insecure-allow-httpescape hatch in v1.0 — remote-plaintext MCP is not a supported shape even behind friction (the ADR-0012 escape-hatch precedent existed because the demo needed it; the demo doesn't configure MCP at all).reqwest::redirect::Policy::none()) on the daemon's HTTP client. This is the half with a genuine remote attacker: a compromised configured server could 30x the fingerprinting POST to internal endpoints (Cloud Run metadata server) and the response would be canonicalised and persisted into the commit tree — SSRF plus exfiltration into the object store, unstoppable by any startup URL check. A redirect response becomes a per-server fingerprint error naming theLocationtarget. The sharedDaemonState.httpclient gets a comment pinning this: future non-MCP uses that want redirects must build their own client.--mcp name=urlis already an explicit operator enumeration; with schemes validated and redirects off, the destination set equals the configured list exactly, so a second host list would restate the first with extra ceremony. The reasoning goes in the ADR so the audit finding reads as consciously closed.ADR: yes — ADR-0016, a one-pager in ADR-0001's format, drafted as part of the implementation ticket. It changes the operator-facing startup contract (previously-valid remote
http://URLs now abort startup) and pins the SSRF posture in one citable place.Facts surfaced during the session: MCP URLs enter only via the
--mcpstartup flag (operator-controlled, never socket input);run-demo.shpasses no--mcpat all, so the demo is unaffected; the current client follows up to 10 redirects (reqwest default) — the live vector item 2 closes.Enforce the MCP URL policy: HTTPS-except-loopback + no redirects (ADR…