Skip to content

fix(agent): pass proxy, TLS trust and CLAUDE_ settings to the agent CLI - #820

Merged
coo1white merged 1 commit into
mainfrom
claude/trusting-wozniak-d0z17o-agent-proxy-env
Oct 17, 2026
Merged

coo1white merged 1 commit into
mainfrom
claude/trusting-wozniak-d0z17o-agent-proxy-env

Conversation

@coo1white

Copy link
Copy Markdown
Owner

Capability

A user who reaches the model API through a proxy can now run cw -q … -claude. Found in the operator's 0.3.3 acceptance run: claude -p "say hi" worked in their shell, but every CW worker failed with Failed to authenticate. API Error: 403 Request not allowed, because CW stripped HTTPS_PROXY and friends from the agent child env and the CLI connected directly.

Implementation

buildAgentChildEnv in src/shell/execution-backend/agent.ts (the one env builder for both the serial and the batch agent spawn) now also forwards, when set:

  • proxy: HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY and their lowercase forms (clients read one case or the other);
  • TLS trust: NODE_EXTRA_CA_CERTS, SSL_CERT_FILE, SSL_CERT_DIR (a TLS-intercepting proxy needs its CA trusted);
  • the CLAUDE_ prefix (CLAUDE_CONFIG_DIR, CLAUDE_CODE_*), like ANTHROPIC_ already is.

A policy deny still wins by exact name; CW_NEVER_FORWARD_ENV names are never forwarded; the forwarded list (and so the worker.agent-env audit event) stays names only, never values. buildChildEnv (non-agent backends) is unchanged. A proxy URL can carry a password, but the agent must reach its API anyway and these go only to the agent CLI the operator configured.

Docs: docs/sandbox-profiles.7.md (new in 0.3.3), docs/security-trust-hardening.7.md (audit names list), and a row in the 0.3.3 table of project/docs/intent/2026-10-16-release-gate-ci.md (default bytes change only in that audit event's names list, only when such vars are set).

Tests

New test/shell/execution-backend/agent-child-env-proxy.test.mjs: all 11 proxy/CA names and CLAUDE_CONFIG_DIR forwarded with values and named in forwarded; no value text in forwarded; SECRET_THING not forwarded; CW_RELEASE_VERDICT_PRIVKEY / CW_WORKBENCH_TOKEN never forwarded; deny: ["HTTPS_PROXY","CLAUDE_CONFIG_DIR"] strips both. Fails before (HTTPS_PROXY forwarded with its value), passes after.

build, check, test:unit 144/144, test:gate 277/277, citation, growth, index, purity, lang, onramp check, release:check: pass. Conformance 86/88 (only the known sandbox-only report-doctor / report-fix).

Risk

Low. Only the agent backend's child env gains these names, only when set in the parent.


Generated by Claude Code

Live report: `claude -p "say hi"` worked in the operator's shell, but
every `cw -q ... -claude --fast` worker failed with "Failed to
authenticate. API Error: 403 Request not allowed". The shell reaches the
API through a proxy (HTTPS_PROXY and friends). buildAgentChildEnv built
the agent child env from buildChildEnv (PATH + HOME + expose under the
default/readonly profiles) plus provider-key prefixes and USER, so the
proxy vars were dropped and the vendor CLI went direct and was refused.

buildAgentChildEnv (the one place both the serial and batch agent spawns
use) now also forwards, when set, not denied by the policy, and not in
CW_NEVER_FORWARD_ENV:
- HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY and their lowercase forms
  (curl/Node/undici/Rust clients read either case);
- NODE_EXTRA_CA_CERTS (claude, gemini are Node CLIs), SSL_CERT_FILE and
  SSL_CERT_DIR (OpenSSL / rustls-native-certs, e.g. codex). A TLS-
  intercepting proxy needs its CA trusted. REQUESTS_CA_BUNDLE left out:
  no shipped wrapper's vendor is a Python requests client;
- the CLAUDE_ prefix (CLAUDE_CONFIG_DIR, CLAUDE_CODE_*), which the claude
  CLI reads for its login/config, like ANTHROPIC_ already was. codex
  (CODEX_), gemini (GEMINI_/GOOGLE_), opencode/deepseek (DEEPSEEK_ etc.)
  already had their prefixes; no other prefix added.

Credentials: a proxy URL can hold a user:password. The agent child must
reach its API anyway, and these vars go only to the delegated agent CLI
the operator configured. Values are never recorded: the `forwarded` list
feeding the worker.agent-env trust-audit event stays names only. An
explicit policy deny still wins (exact name).

buildChildEnv is unchanged: non-agent backends (node/bun/shell/container)
keep their stricter env; they do not call a remote model API.

Default bytes change only in the worker.agent-env audit event's names
list, and only when such vars are set. Shipped as a fix under the
operator's fix-everything request for 0.3.3 (row added to the intent
table); docs/sandbox-profiles.7.md and docs/security-trust-hardening.7.md
updated.

Test: test/shell/execution-backend/agent-child-env-proxy.test.mjs fails
on the old dist ("HTTPS_PROXY forwarded with its value") and passes now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NpzNqRDJFpBt4cSyYjhbV3
@coo1white
coo1white marked this pull request as ready for review October 17, 2026 20:11
@coo1white
coo1white enabled auto-merge October 17, 2026 20:11
@coo1white
coo1white merged commit b69b15f into main Oct 17, 2026
9 checks passed
@coo1white
coo1white deleted the claude/trusting-wozniak-d0z17o-agent-proxy-env branch October 17, 2026 20:16
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.

2 participants