Follow-up to #764 / PR #766 (round-3 review).
Context
PR #766 derives the combined CA bundle (system roots + MITM CA) from the machine distro trust store, deliberately not from the invoking process's SSL_CERT_FILE/SSL_CERT_DIR. This was chosen to eliminate a class of lifecycle hazards: a single shared ca-bundle.crt derived from per-process env let one shell/cron/sudo context atomically replace another's trust set, and required a fragile env-var provenance marker to recover the operator's original source after we overwrote SSL_CERT_FILE.
clawpatrol run also now force-sets the replace-style CA vars to the bundle, because they are replace-style (they name the one file a client trusts) — otherwise an operator's SSL_CERT_FILE would leave the wrapped agent trusting only that file and not the MITM CA.
Gap
A corporate/internal root supplied only via SSL_CERT_FILE (i.e. not installed in the system trust store via update-ca-certificates) is no longer folded into the bundle. Because we force-set SSL_CERT_FILE to our bundle, the wrapped agent loses that corporate root, so passthrough TLS to hosts chaining to it fails (fail-closed — visible TLS error, not a silent MITM).
Note this was already broken pre-#766 (the old code set SSL_CERT_FILE=ca.crt, MITM-only), so #766 is not a regression here; it just doesn't newly fix this case. The normal path — a corporate root installed in the system store — is covered, since the machine reader includes it.
Proposed work
To support SSL_CERT_FILE-only corporate roots without reintroducing the shared-mutable-path hazard, fold the operator's original trust source into the bundle but write to a content-addressed / per-input path (e.g. ~/.clawpatrol/bundles/<sha256-of-content>.crt), so different trust environments never collide on one pathname. Handle nesting by treating a bundle path already under bundles/ as provisioned, and GC stale bundles.
Alternatively, document CLAWPATROL_NO_ENV=1 (or a targeted opt-out) plus "install your corporate root system-wide" as the supported workaround.
Current behavior
Until then: install corporate roots in the system trust store (standard practice) so they are included, or use CLAWPATROL_NO_ENV=1 to keep the operator's own SSL_CERT_FILE. The SSL_CERT_FILE-only case fails closed.
Follow-up to #764 / PR #766 (round-3 review).
Context
PR #766 derives the combined CA bundle (system roots + MITM CA) from the machine distro trust store, deliberately not from the invoking process's
SSL_CERT_FILE/SSL_CERT_DIR. This was chosen to eliminate a class of lifecycle hazards: a single sharedca-bundle.crtderived from per-process env let one shell/cron/sudo context atomically replace another's trust set, and required a fragile env-var provenance marker to recover the operator's original source after we overwroteSSL_CERT_FILE.clawpatrol runalso now force-sets the replace-style CA vars to the bundle, because they are replace-style (they name the one file a client trusts) — otherwise an operator'sSSL_CERT_FILEwould leave the wrapped agent trusting only that file and not the MITM CA.Gap
A corporate/internal root supplied only via
SSL_CERT_FILE(i.e. not installed in the system trust store viaupdate-ca-certificates) is no longer folded into the bundle. Because we force-setSSL_CERT_FILEto our bundle, the wrapped agent loses that corporate root, so passthrough TLS to hosts chaining to it fails (fail-closed — visible TLS error, not a silent MITM).Note this was already broken pre-#766 (the old code set
SSL_CERT_FILE=ca.crt, MITM-only), so #766 is not a regression here; it just doesn't newly fix this case. The normal path — a corporate root installed in the system store — is covered, since the machine reader includes it.Proposed work
To support
SSL_CERT_FILE-only corporate roots without reintroducing the shared-mutable-path hazard, fold the operator's original trust source into the bundle but write to a content-addressed / per-input path (e.g.~/.clawpatrol/bundles/<sha256-of-content>.crt), so different trust environments never collide on one pathname. Handle nesting by treating a bundle path already underbundles/as provisioned, and GC stale bundles.Alternatively, document
CLAWPATROL_NO_ENV=1(or a targeted opt-out) plus "install your corporate root system-wide" as the supported workaround.Current behavior
Until then: install corporate roots in the system trust store (standard practice) so they are included, or use
CLAWPATROL_NO_ENV=1to keep the operator's ownSSL_CERT_FILE. TheSSL_CERT_FILE-only case fails closed.