sandbox: allowMachLookup is not passed through from settings.json, so the only fix for Go TLS is the blunt one
sandbox: allowMachLookup is not passed through from settings.json, so the only way to fix Go TLS is the blunt one
Summary
@anthropic-ai/sandbox-runtime accepts an allowMachLookup list (with wildcard
support) for granting individual Mach services. Claude Code's settings file does
not pass it through, so the narrowest available fix for the Go/TLS problem is
unreachable and users are pushed to excludedCommands, which removes the sandbox
for that command entirely.
Measured on Claude Code 2.1.220, macOS 26 (Darwin 25.5.0), gh 2.x.
The underlying problem, briefly
Go's crypto/x509 on macOS evaluates chains via SecTrustEvaluateWithError(),
which reaches the trust agent over Mach IPC. With that lookup denied, evaluation
aborts:
$ gh api rate_limit
Get "https://api.github.com/rate_limit": tls: failed to verify certificate: x509: OSStatus -26276
curl to the same host from the same sandbox works, so this is not the domain
allowlist or the proxy. This part is already known — #34876 — and affects gh,terraform, tofu, gcloud and any other Go binary.
Note for anyone landing here from #34876: that issue proposes(allow mach-lookup (global-name "com.apple.trustd")). That name does not fix
it. Isolated with sandbox-exec, one variable per profile over (allow default):
| profile | gh api rate_limit |
|---|---|
| deny com.apple.trustd | works |
| deny com.apple.trustd.agent | OSStatus -26276 |
| deny all mach-lookup, allow com.apple.trustd | OSStatus -26276 |
| deny all mach-lookup, allow com.apple.trustd.agent | works |
com.apple.trustd.agent is the necessary and sufficient service. The library
already uses the correct name.
The actual report
Two settings, same repo, same session:
| ~/.claude/settings.json | gh inside the sandbox |
|---|---|
| sandbox.enableWeakerNetworkIsolation: true | works |
| sandbox.allowMachLookup: ["com.apple.trustd.agent"] | no effect |
So enableWeakerNetworkIsolation is wired (this also means #28954 no longer
reproduces on 2.1.220), but allowMachLookup is not — even thoughmacos-sandbox-utils.ts implements it:
...(allowMachLookup && allowMachLookup.length > 0
? [
'; User-specified XPC/Mach services',
...allowMachLookup.map(name => /* global-name or global-name-prefix */),
]
: []),
Why this matters more than it looks
On macOS, enableWeakerNetworkIsolation has exactly one effect on the generated
profile:
; trustd.agent - needed for Go TLS certificate verification (weaker network isolation)
(allow mach-lookup (global-name "com.apple.trustd.agent"))
It opens no port, no host and no file. The name suggests a network hole, which
leads people to reject it and reach for excludedCommands instead — andexcludedCommands runs the command with no sandbox at all. The current menu is:
| option | grant | scope |
|---|---|---|
| enableWeakerNetworkIsolation | one Mach service | every sandboxed command |
| excludedCommands | no sandbox at all | the named command |
| allowMachLookup | one Mach service | every sandboxed command | (not reachable) |
A user who wants only Go TLS has to take a global flag whose name implies
something much larger, or turn the sandbox off for that tool. PassingallowMachLookup through would at least make the grant explicit and auditable
in the settings file, and would let the same mechanism serve the other Mach
services people hit.
On the safety of the grant
Tested, since "can a sandboxed process install its own root CA through the trust
agent" is the obvious question. Throwaway self-signed cert,security add-trusted-cert -r trustRoot, user domain:
- outside the sandbox: blocks on a SecurityAgent authorization dialog
- inside a profile granting only
com.apple.trustd.agent: fails immediately, no
dialog, nothing written
Nothing landed in the trust store in either case. The write path goes through
interactive authorization, so the grant does not appear to enable a silent
trust-store modification.
Ask
Pass sandbox.allowMachLookup from settings.json through to the sandbox-runtime
config, the way enableWeakerNetworkIsolation already is. Secondarily: the flag
name is misleading on macOS, where it grants one Mach service and touches nothing
about network isolation.
Reproducing
cat > /tmp/deny.sb <<'EOF'
(version 1)
(allow default)
(deny mach-lookup (global-name "com.apple.trustd.agent"))
EOF
sandbox-exec -f /tmp/deny.sb gh api rate_limit # x509: OSStatus -26276
cat > /tmp/allow.sb <<'EOF'
(version 1)
(allow default)
(deny mach-lookup)
(allow mach-lookup (global-name "com.apple.trustd.agent"))
EOF
sandbox-exec -f /tmp/allow.sb gh api rate_limit # works
(sandbox-exec cannot nest inside Claude Code's own sandbox — run these from a
plain terminal.)
---
Full measurements, including the profiles used and the root-CA abuse test:
https://github.com/dT-Tb-labs/babel-orchestration/blob/master/SANDBOX-NOTES.md