Sandbox proxy variables are set for excludedCommands (docs say no proxy); breaks gh TLS on macOS
Summary
The sandbox layer sets HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY and related variables for Bash commands, including commands that match sandbox.excludedCommands. The sandboxing docs say excluded commands run "outside the sandbox, which means no filesystem restrictions and no network proxy." Go-based CLIs (gh) fail TLS verification on macOS when these variables are set, and work when they are removed.
Related: #26466 (same symptom, proposed cause is a MITM certificate), #88180 (trustd Mach port, inside the sandbox).
Environment
- macOS (Darwin 27), Claude Code desktop app, Code tab
gh2.102.0 (Homebrew), Go-built
Steps to reproduce
- In
settings.json, set"sandbox": { "excludedCommands": ["gh *"] }. - Run
gh api userfrom Claude Code's Bash tool, with the sandbox enabled. - Observe
tls: failed to verify certificate: x509: OSStatus -26276. - Run the same
ghcommand with the proxy variables unset (env -u HTTPS_PROXY -u HTTP_PROXY -u ALL_PROXY ...), outside the sandbox. It returns the user's login.
Evidence
- A harmless script named
ghprints the proxy variable names. It receives them whether invoked through thegh *exclusion or by full path, so the variables are added per command. - The variables are absent from the
claudeparent process and from a plain shell outside the sandbox. They are therefore not inherited from the app. - A plain Go TLS client (Go 1.27.2, darwin/arm64) fails the same way through the proxy, for
api.github.com,google.com,github.comandproxy.golang.org. The same client, with the proxy variables removed, gets200 OKand a verified chain. - The chain the proxy presents for
api.github.comis a normal Sectigo chain (*.github.com→ Sectigo DV E36 → Root E46 → USERTrust ECC). This does not look like a MITM certificate, which differs from #26466's explanation.
Expected
Either excluded commands get no proxy variables, as documented, or the docs should say they do. Go CLIs should work through the proxy the way curl does.
Workaround
Unset the proxy variables inside a wrapper named gh, placed before /opt/homebrew/bin on PATH. The wrapper calls the Homebrew binary by its full path. It works outside the sandbox only, because inside the sandbox the excluded path has no route to GitHub once the proxy is removed.