Skip to content

fix(tls): containers get combined public+local trust, never a stripped bundle#56

Merged
roodboi merged 5 commits into
mainfrom
fix/container-trust-bundle
Jul 8, 2026
Merged

fix(tls): containers get combined public+local trust, never a stripped bundle#56
roodboi merged 5 commits into
mainfrom
fix/container-trust-bundle

Conversation

@roodboi

@roodboi roodboi commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

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:

  • Containers now also mount the combined public+local trust bundle (caddy-host-trust-bundle.pem, generated by hack global trust) and replace-semantics vars point at it
  • Without the bundle: only append-semantics vars (NODE_EXTRA_CA_CERTS, HACK_LOCAL_CA_CERT) are set, with a warning suggesting hack global trust — public TLS is never sacrificed for internal trust
  • SSL_CERT_DIR is never overridden (it discarded the image's default hashed cert dir)

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

…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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/commands/project.ts
Comment on lines +2511 to +2515
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.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

roodboi and others added 3 commits July 7, 2026 20:36
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>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/commands/global.ts
return 1;
}

if (isLinux()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in PR #59 (or as noted): Fixed in PR #57 (merged, commit 4d35428): globalTrust checks isMac() before isLinux() so the mocked mac path wins on Linux runners, and the macOS suite pins isLinux()=false.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@roodboi
roodboi merged commit 9cb82c1 into main Jul 8, 2026
4 checks passed
@roodboi
roodboi deleted the fix/container-trust-bundle branch July 8, 2026 00:48
roodboi pushed a commit that referenced this pull request Jul 8, 2026
## 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))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant