Sandbox blocks inbound SSO/OAuth loopback callback from Bash-tool CLI commands (Linux/WSL2)
What's Wrong?
Commands run via the Bash tool's sandbox that perform browser-basedexternalbrowser-style SSO/OAuth (e.g. Snowflake CLI's snow sql, or any tool using a local loopback OAuth
--authenticator externalbrowser
callback) hang until their own internal timeout, then fail. The same exact
command succeeds instantly when run with dangerouslyDisableSandbox: true,
via ! in the prompt box, or in a plain terminal.
Root-caused two independent, compounding issues on Linux/WSL2:
1. WSL interop socket failure (blocks browser launch entirely)
Inside the sandbox, wslview/xdg-open (used by CLIs to open the SSO URL in
the Windows-side browser) fail with:
grep: /proc/sys/fs/binfmt_misc/WSLInterop: No such file or directory
<3>WSL (89) ERROR: UtilConnectUnix:505: socket failed 1
No browser opens at all — the SSO flow just sits waiting. Workaround
found: setting sandbox.network.allowAllUnixSockets: true in~/.claude/settings.json fixes this half; the browser then opens correctly.
2. Inbound loopback callback unreachable (blocks the OAuth/SAML redirect)
Once the browser opens and the user authenticates, Okta/the IdP redirects tohttp://localhost:<ephemeral-port>/.... That port is bound by the sandboxed
process, but the sandbox runs commands in an isolated network namespace
(confirmed via differing /proc/self/ns/net inode between the sandboxed
process and the host). The browser (running on the real host) gets
"connection refused" hitting that port — verified directly by starting a
throwaway listener inside the sandbox and confirming it was unreachable from
a real browser on the host.
The sandbox's process tree shows only an egress proxy (socat) for reaching
TCP-LISTEN:3128/1080 ... UNIX-CONNECT:/tmp/claude-http-*.sockallowedDomains — there is no equivalent ingress path to forward a
host-originated connection into the sandbox's network namespace. No
documented sandbox.network.* setting (tried allowAllUnixSockets,allowLocalBinding) fixes this half.
What Should Happen?
Either:
- Provide a sandbox setting to forward specific inbound loopback ports from
the host into the sandboxed process's network namespace (e.g. for known
OAuth/SAML callback ports), or
- Document that inbound loopback callbacks are unsupported in the sandbox and
that sandbox.excludedCommands (with a glob pattern, e.g. "snow *" — a
bare prefix like "snow" does NOT match) is the intended, supported
workaround for commands that need browser-based SSO.
Environment
- OS: Linux (WSL2, Windows host)
- Claude Code version: tested across 2.1.221–2.1.228 (root cause is
architectural, not version-specific — reproduced identically on all tested
versions)
- Failing commands: Snowflake CLI (`snow sql ... --authenticator
externalbrowser`), Cortex Code CLI (Snowflake connector, same auth path)
Steps to Reproduce
- On Linux/WSL2, configure a
connections.toml/CLI with
authenticator = "externalbrowser" and no cached credential.
- Run the command through Claude Code's Bash tool (sandboxed, default
settings).
- Observe: no browser opens (WSL interop socket error in tool output), OR
with sandbox.network.allowAllUnixSockets: true set, the browser opens
but the post-login redirect to localhost:<port> fails with "connection
refused" in the browser.
- Compare: the identical command run via
!(prompt-box passthrough) or a
plain terminal completes successfully in seconds.
Workaround Found
Add the command to sandbox.excludedCommands as a glob pattern (not a
bare prefix):
"sandbox": {
"excludedCommands": ["snow *"]
}
This runs matching commands fully unsandboxed automatically, avoiding the
issue entirely. Confirmed working end-to-end.
Related Issues
- #28018 — same architectural root cause (isolated network namespace, no
loopback bridging), opposite direction (outbound sandboxed→localhost)
- #62801 — same defect class in Cowork's own MCP OAuth (closed stale, not
fixed)
- #67715 — Claude Code's own OAuth login failing to bind a loopback port on
macOS (closed not-planned, different platform/flow)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗