fix(tls): containers get combined public+local trust, never a stripped bundle#56
Conversation
…d bundle The internal compose override pointed replace-semantics CA vars (SSL_CERT_FILE, CURL_CA_BUNDLE, REQUESTS_CA_BUNDLE, GIT_SSL_CAINFO) at the bare Caddy local CA and overrode SSL_CERT_DIR, stripping public roots from every OpenSSL-based tool in the container (.NET/NuGet, git, python-requests failed with UntrustedRoot on public hosts; Node survived only because NODE_EXTRA_CA_CERTS appends). Containers now mount the combined public+local trust bundle generated by hack global trust and point replace-semantics vars at it; without the bundle only append-semantics trust is set, so public TLS is never broken as a side effect. SSL_CERT_DIR is never overridden. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 651f234529
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const bundlePath = await findHackHostTrustBundlePath(); | ||
| if (!bundlePath) { | ||
| logger.warn({ | ||
| message: | ||
| "Combined trust bundle not found; containers get Node-only trust for *.hack hosts (OpenSSL-based tools keep public roots but won't trust internal TLS). Run `hack global trust` to generate it.", |
There was a problem hiding this comment.
Generate the trust bundle outside macOS
When running hack on Linux/CI/agent sandboxes, this branch is the steady state: hack global trust exits early on non-macOS in globalTrust, so findHackHostTrustBundlePath() remains null even after hack global ca exports the Caddy CA. The override then only sets NODE_EXTRA_CA_CERTS, leaving curl/git/requests/.NET containers unable to trust https://*.hack; the suggested recovery command cannot produce the bundle in that environment. Please either generate caddy-host-trust-bundle.pem cross-platform or use a fallback that preserves internal TLS there.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 2190dd8 (rebased): hack global trust now has a Linux path — concatenates the distro's canonical system bundle (/etc/ssl/certs/ca-certificates.crt, ca-bundle.crt, etc.) with the local CA to produce the same combined bundle contract as the macOS keychain export, and writes the host trust env script. System trust-store installation stays a documented manual step. Covered by tests/linux-trust-bundle.test.ts (first-available-candidate selection, append-only fallback when no system bundle, unreadable-CA guard).
hack global trust exited early on non-macOS, so Linux/CI/agent sandboxes could never produce the combined bundle and containers were stuck with Node-only internal trust. Linux now concatenates the distro's canonical CA bundle (ca-certificates.crt et al) with the local CA and writes the host trust env script; system trust-store installation stays a documented manual step. From PR review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A real polyglot repo (Vite/Astro/Bun/.NET/Temporal) onboarded by an agent surfaced three repeatable gaps in the prompt: framework dev-server host checks need .hack allowed through (dev-server config only), app-level is-this-local URL guards should treat *.hack as local while keeping the public OAuth alias out of the allowlist, and agents must hand humans the sudo-requiring hack global steps instead of stalling on them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2190dd8451
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return 1; | ||
| } | ||
|
|
||
| if (isLinux()) { |
There was a problem hiding this comment.
Keep macOS trust tests out of the Linux path
When the macOS test suite runs on a Linux CI runner, it mocks isMac() to true but does not override the newly imported isLinux(), so this branch is also true and hack global trust takes the Linux bundle path before the macOS keychain logic. I ran bun test tests/global-command.test.ts tests/global-command.macos.test.ts and the three macOS trust tests fail because the bundle contains the real Linux CA store instead of the mocked SYSTEM certificate; either mock isLinux false in those tests or make this branch mutually exclusive with the macOS path.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## 3.2.0 (2026-07-08) * Merge branch 'main' into fix/container-trust-bundle ([8338b58](8338b58)) * Merge pull request #56 from hack-dance/fix/container-trust-bundle ([9cb82c1](9cb82c1)), closes [#56](#56) * Merge pull request #57 from hack-dance/fix/global-trust-platform-order ([e3c6da0](e3c6da0)), closes [#57](#57) * fix(tls): check isMac before isLinux in globalTrust; pin platform in mac suite ([4d35428](4d35428)) * fix(tls): containers get combined public+local trust, never a stripped bundle ([651f234](651f234)) * fix(tls): generate the combined trust bundle on Linux hosts ([e339920](e339920)) * test(tls): neutral fixture paths for the privacy check ([c4be004](c4be004)) * feat(agents): onboarding lessons from first field hack init --with run ([2190dd8](2190dd8))
Reported from the field: a .NET backend in a hack-managed project hit UntrustedRoot on api.nuget.org because the generated .hack/.internal/compose.override.yml pointed SSL_CERT_FILE/CURL_CA_BUNDLE/REQUESTS_CA_BUNDLE/GIT_SSL_CAINFO at the bare Caddy local CA and overrode SSL_CERT_DIR — replacing the container's public roots with a single internal CA. Node services masked the bug (NODE_EXTRA_CA_CERTS appends).
Fix:
Tests cover both bundle states and the never-set invariants; docs + instruction surfaces updated per the docs-currency rule. Full suite 790/0, e2e 8/8.
🤖 Generated with Claude Code