Skip to content

fix(proxy): add lowercase proxy vars and NODE_EXTRA_CA_CERTS#1234

Merged
Mossaka merged 3 commits intomainfrom
fix/024-yarn-ssl-squid-proxy
Mar 12, 2026
Merged

fix(proxy): add lowercase proxy vars and NODE_EXTRA_CA_CERTS#1234
Mossaka merged 3 commits intomainfrom
fix/024-yarn-ssl-squid-proxy

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Mar 11, 2026

Summary

Fix Yarn 4 and Corepack EPROTO SSL errors when connecting through the Squid proxy.

  • Add lowercase proxy env vars (http_proxy, https_proxy) alongside uppercase variants. Yarn 4 (undici), Corepack, and some Node.js HTTP clients only check lowercase proxy environment variables. Without these, their HTTPS connections bypass the proxy and get DNAT'd to Squid's forward proxy port, which expects HTTP protocol — causing EPROTO errors.
  • Set NODE_EXTRA_CA_CERTS when SSL Bump is enabled so Node.js tools trust the AWF session CA certificate. Node.js uses its own CA bundle, not the system CA store updated by update-ca-certificates.
  • Add 3 new unit tests covering lowercase proxy vars and NODE_EXTRA_CA_CERTS behavior.

Fixes #949

Test plan

  • Verify npm run build && npm test passes (842 tests)
  • Verify lowercase proxy env vars appear in agent container environment
  • Verify NODE_EXTRA_CA_CERTS is set when SSL Bump is enabled
  • Verify NODE_EXTRA_CA_CERTS is NOT set when SSL Bump is disabled

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 11, 2026 17:41
@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.56% 82.94% 📈 +0.38%
Statements 82.57% 82.93% 📈 +0.36%
Functions 83.01% 83.01% ➡️ +0.00%
Branches 75.12% 75.37% 📈 +0.25%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 84.1% → 85.5% (+1.46%) 83.4% → 84.8% (+1.41%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the container environment setup to improve Node/Yarn/Corepack behavior when running behind the Squid proxy, addressing SSL/proxy handling issues that can surface as EPROTO errors.

Changes:

  • Add lowercase http_proxy / https_proxy alongside uppercase proxy env vars.
  • Set NODE_EXTRA_CA_CERTS when SSL Bump is enabled so Node-based tooling trusts the session CA.
  • Add unit tests covering lowercase proxy vars and NODE_EXTRA_CA_CERTS behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/docker-manager.ts Adds lowercase proxy vars and sets NODE_EXTRA_CA_CERTS under SSL Bump; also propagates lowercase proxy vars to the api-proxy sidecar.
src/docker-manager.test.ts Adds unit tests validating lowercase proxy vars and NODE_EXTRA_CA_CERTS behavior.
containers/agent/entrypoint.sh Exports NODE_EXTRA_CA_CERTS during SSL Bump startup after updating CA certificates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
http_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

The api-proxy sidecar healthcheck uses curl http://localhost:..., but adding lowercase http_proxy/https_proxy here will cause curl to proxy localhost unless NO_PROXY/no_proxy is set (or the healthcheck explicitly disables proxying). This can make the api-proxy container permanently unhealthy and block agent startup via depends_on: service_healthy. Consider adding NO_PROXY=no_proxy=localhost,127.0.0.1,::1 to the api-proxy environment (or change the healthcheck to curl --noproxy '*' ...).

Suggested change
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
// Ensure localhost traffic (e.g., healthcheck) bypasses the proxy
NO_PROXY: 'localhost,127.0.0.1,::1',
no_proxy: 'localhost,127.0.0.1,::1',

Copilot uses AI. Check for mistakes.
Comment on lines 1020 to +1024
// Route through Squid to respect domain whitelisting
HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
http_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

When SSL Bump is enabled, Squid presents certificates signed by the session CA for all clients using the proxy port. The api-proxy sidecar routes upstream requests through Squid (HttpsProxyAgent(HTTPS_PROXY)), but the compose spec does not mount the CA cert into the api-proxy container or set NODE_EXTRA_CA_CERTS there, so upstream TLS requests are likely to fail in --ssl-bump --enable-api-proxy mode. Consider mounting the CA cert into the api-proxy container and setting NODE_EXTRA_CA_CERTS (or otherwise exempting api-proxy traffic from SSL bump).

Suggested change
// Route through Squid to respect domain whitelisting
HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
http_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
// Route through Squid to respect domain whitelisting when SSL bump is disabled.
// When SSL bump is enabled, avoid proxying api-proxy HTTPS traffic through Squid
// to prevent TLS failures due to untrusted session CA certificates.
...(!config.enableSslBump && {
HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
http_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
}),

Copilot uses AI. Check for mistakes.
Comment on lines 344 to +348
HTTP_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
HTTPS_PROXY: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
// Lowercase variants for tools that only check lowercase (e.g., Yarn 4/undici, Corepack)
http_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
https_proxy: `http://${networkConfig.squidIp}:${SQUID_PORT}`,
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

Now that both uppercase and lowercase proxy variables are set, --env / additionalEnv overrides can easily desync them (e.g., overriding only HTTP_PROXY leaves http_proxy pointing at the default). Similar to the existing NO_PROXY/no_proxy normalization below, consider normalizing HTTP_PROXYhttp_proxy and HTTPS_PROXYhttps_proxy after applying additionalEnv so a single override behaves consistently across clients.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

feat(cli): add short flags for frequently used options
docs: clarify --image-tag behavior with agent-image presets
Tests: MCP ✅ | GH CLI ✅ | Playwright ✅ | Tavily ❌ | File ✅ | Bash ✅ | Discussion ✅ | Build ✅
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex for issue #1234

@github-actions
Copy link
Contributor

Smoke Test Results

GitHub MCP: #1229 feat(cli): add short flags for frequently used options, #1228 docs: clarify --image-tag behavior with agent-image presets
Playwright: GitHub page title contains "GitHub"
File Write: /tmp/gh-aw/agent/smoke-test-claude-22966761040.txt created
Bash: File verified via cat

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1234

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

Smoke test results for @Mossaka:

✅ GitHub MCP — Last 2 merged PRs: #1229 feat(cli): add short flags for frequently used options, #1228 docs: clarify --image-tag behavior with agent-image presets
✅ Playwright — github.com title contains "GitHub"
✅ File write — /tmp/gh-aw/agent/smoke-test-copilot-22966761046.txt created and verified
✅ Bash — cat confirmed file contents

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1234

@github-actions
Copy link
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.12 Python 3.12.3
Node.js v24.14.0 v20.20.0
Go go1.22.12 go1.22.12

Result: ❌ Not all versions match. Go matches, but Python and Node.js differ between host and chroot environments.

Tested by Smoke Chroot for issue #1234

@github-actions
Copy link
Contributor

🤖 Smoke test results for PR #1234 by @Mossaka:

✅ GitHub MCP — Last 2 merged PRs: test(docker): verify capsh execution chain after PR #715 (#1240), fix(cli): clear LD_PRELOAD after one-shot-token library loads (#1232)
✅ Playwright — github.com title contains "GitHub"
✅ File Write — /tmp/gh-aw/agent/smoke-test-copilot-22969603660.txt created
✅ Bash — File verified via cat

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1234

@github-actions
Copy link
Contributor

test: expand credential hiding tests to all 14 protected paths | test(docker): verify capsh execution chain after PR #715
GitHub MCP merged PR review: ✅
safeinputs-gh PR list: ✅
Playwright title check: ✅
Tavily search: ❌ (tool unavailable)
File write: ✅
Bash cat verify: ✅
Discussion comment: ✅
Build (npm ci && npm run build): ✅
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex for issue #1234

@github-actions
Copy link
Contributor

Smoke Test Results

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1234

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.12 Python 3.12.3 ❌ NO
Node.js v24.14.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot for issue #1234

Mossaka and others added 3 commits March 12, 2026 18:52
Yarn 4 (undici), Corepack, and some Node.js HTTP clients only check
lowercase http_proxy/https_proxy environment variables. This caused
EPROTO SSL errors when these tools tried to make HTTPS connections
through the Squid proxy.

- Add lowercase http_proxy/https_proxy alongside uppercase variants
- Set NODE_EXTRA_CA_CERTS when SSL Bump is enabled so Node.js trusts
  the AWF session CA certificate
- Export NODE_EXTRA_CA_CERTS in entrypoint.sh for container context
- Add tests for lowercase proxy vars and NODE_EXTRA_CA_CERTS

Fixes #949

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The api-proxy container's curl health check was routing through Squid
because of the newly-added lowercase http_proxy/https_proxy env vars.
curl respects lowercase proxy vars, causing localhost health checks to
fail. Add NO_PROXY/no_proxy with localhost entries to prevent this.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Some curl builds (Ubuntu 22.04) ignore uppercase HTTP_PROXY for HTTP
URLs as an httpoxy mitigation. This means HTTP traffic correctly falls
through to iptables DNAT interception where Squid blocks at the
connection level. Setting lowercase http_proxy causes curl to use the
forward proxy, where Squid's 403 error page returns exit code 0 —
breaking security expectations.

Only https_proxy (lowercase) is needed for Yarn 4/undici/Corepack
compatibility since these tools connect to registries via HTTPS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Mossaka Mossaka force-pushed the fix/024-yarn-ssl-squid-proxy branch from 82f999a to 10c59d3 Compare March 12, 2026 18:53
@github-actions
Copy link
Contributor

Smoke Test Results

  • ✅ GitHub MCP: #1218: chore(deps): aggregated dependency updates, #1230: docs: document flag validation constraints
  • ✅ Playwright: GitHub page title verified
  • ✅ File write: /tmp/gh-aw/agent/smoke-test-claude-23018665746.txt created
  • ✅ Bash: File contents verified

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1234

@github-actions
Copy link
Contributor

GitHub MCP merged PRs: chore(deps): aggregated dependency updates; docs: document flag validation constraints ✅
safeinputs-gh pr list ✅
Playwright title contains GitHub ✅
Tavily search ❌ (tool unavailable)
File write ✅
Bash cat ✅
Discussion query + oracle comment ✅
Build npm ci && npm run build ✅
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex for issue #1234

@github-actions
Copy link
Contributor

🔥 Smoke Test Results

GitHub MCP — Last 2 merged PRs:

Playwright — github.com title contains "GitHub"
File Write/tmp/gh-aw/agent/smoke-test-copilot-23018665691.txt created
Bash — File verified via cat

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1234

@github-actions
Copy link
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.12 Python 3.12.3 ❌ NO
Node.js v24.14.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Result: ❌ Not all versions match — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot for issue #1234

@github-actions
Copy link
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color passed ✅ PASS
Go env passed ✅ PASS
Go uuid passed ✅ PASS
Java gson N/A ❌ FAIL
Java caffeine N/A ❌ FAIL
Node.js clsx passed ✅ PASS
Node.js execa passed ✅ PASS
Node.js p-limit passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 7/8 ecosystems passed — ❌ FAIL


❌ Java Failure Details

Both gson and caffeine failed during mvn compile because Maven could not download dependencies from Maven Central (https://repo.maven.apache.org/maven2). The network is unreachable from this environment for that host.

Error:

Plugin org.apache.maven.plugins:maven-resources-plugin:3.3.1 or one of its dependencies could not be resolved:
Could not transfer artifact ... from/to central (https://repo.maven.apache.org/maven2): Network is unreachable

This is a network restriction in the current execution environment — Maven Central is not reachable.

Generated by Build Test Suite for issue #1234 ·

@Mossaka Mossaka merged commit ffc1746 into main Mar 12, 2026
60 checks passed
@Mossaka Mossaka deleted the fix/024-yarn-ssl-squid-proxy branch March 12, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Yarn SSL/network errors through Squid proxy block Inquirer.js and prettier

2 participants