[FEATURE] Linux (bwrap): Add allowUnixSockets / allowAllUnixSockets equivalent for seccomp BPF
Status Open
Maintainer reply None cached
Activity 6 comments · opened Apr 6, 2026
Problem
On macOS, allowAllUnixSockets: true and allowUnixSockets path arrays exist to selectively permit AF_UNIX socket operations within the sandbox. On Linux (bwrap + seccomp BPF), no equivalent configuration exists. The seccomp filter unconditionally blocks all socket(AF_UNIX, ...) syscalls with EPERM.
This breaks any tool that requires Unix domain sockets for IPC:
- Playwright / Puppeteer — Chromium requires AF_UNIX for Zygote/Mojo IPC →
socket() failed: Operation not permitted (1) - SSH agent —
ssh-addcannot connect to agent socket - GPG agent —
gpg-agentcannot create/connect to sockets - .NET MSBuild — worker nodes use AF_UNIX for IPC (#39257)
Context
- This worked before v2.1.92 because the
apply-seccompbinary was not bundled (#28576). The v2.1.92 changelog explicitly states: "Linux sandbox now ships the apply-seccomp helper in both npm and native builds, restoring unix-socket blocking for sandboxed commands." - macOS has had
allowAllUnixSocketssince sandbox-runtime PR #140 (2026-02-19), and path-scopedallowUnixSocketsis being worked on (#41817). - Linux has no equivalent — the seccomp BPF filter is binary: all AF_UNIX blocked or none blocked.
excludedCommandsonly bypasses filesystem restrictions, not seccomp (#10524).settings.jsonseccomp configuration is silently ignored (#24238).
Environment
- Linux (WSL2), Claude Code v2.1.92+
sandbox.enabled: true
Reproduction
# Inside Claude Code sandbox:
python3 -c "import socket; s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)"
# → OSError: [Errno 1] Operation not permitted
# Chromium launch:
playwright-cli open https://example.com
# → FATAL: socket() failed: Operation not permitted (1)
Proposed Solution
Add Linux equivalents of the macOS socket configuration:
// settings.json
{
"sandbox": {
// Option 1: Allow all AF_UNIX sockets (parity with macOS)
"allowAllUnixSockets": true,
// Option 2: Path-scoped (preferred, more granular)
"allowUnixSockets": [
"/tmp/claude/**"
],
// Option 3: Command-scoped seccomp exceptions
// (extend excludedCommands to also bypass seccomp)
"excludedFromSeccomp": ["playwright-cli", "chromium"]
}
}
Any of these would unblock browser automation, SSH signing, and GPG operations on Linux.
Related Issues
- #11791 — Browser automation incompatible with sandbox
- #41817 — Path-scoped Unix socket bind() support (macOS)
- #39257 — macOS sandbox blocks bind() for child processes
- #41254 — allowAllUnixSockets does not cover network-bind
- #24238 — seccomp config silently ignored
- #28576 — apply-seccomp binary bundling (the fix that caused this regression)
- OpenAI Codex PR #12702 — Fixed equivalent network-bind issue in their sandbox
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
Adding a concrete use case and reproduction as a data point for prioritization.
Use case: signed git commits from a sandboxed session via host-side ssh-agent.
Setup: long-running
ssh-agenton the WSL2 host with a signing key loaded, listening on/tmp/claude/vigil-signing.sock. Settings exportSSH_AUTH_SOCKinto the session and list the socket insandbox.network.allowUnixSockets:Inside the sandbox:
The socket node is visible with correct ownership/mode, but
connect(2)fails with EPERM and no listener exists in the sandbox — consistent with seccomp blocking AF_UNIXconnect()unconditionally before netns or filesystem rules apply.Why the feature matters here: signed commits are a security property that gets weakened if the signing step has to be carved out of the sandbox via
excludedCommandsor if the agent has to be run inside the sandbox (losing key isolation between sessions). A workingallowUnixSocketson Linux would let the sandbox remain strict-by-default while still lettinggit commit -Sreach a host-held key.Docs note: the current sandboxing page documents
allowUnixSocketsand listssocatas a Linux install dependency without a platform-specific caveat. Users on Linux/WSL2 will reasonably expect it to work and won't know to look at this feature request until they hit the silent no-op. A short platform note on the docs page linking here would save downstream users the same debugging path.Environment: WSL2, kernel
6.6.87.2-microsoft-standard-WSL2, Ubuntu 24.04, bubblewrap 0.9.0,socatinstalled, Claude Code 2.1.109.please add this :)
It would be nice to be able to run sandbox and have ssh and gpg signing
Bump! This would be very useful to me also.
I spent a while researching how the Linux sandbox could get the path-selective
allowUnixSocketsbehavior macOS already has, and ended up building two of the options. Sharing the map in case it's
useful — full writeup + runnable code here: https://github.com/jmaccoby/unix-socket-allowlist-sandbox.
Why it's hard on Linux specifically. seccomp filters syscalls by
(domain, type), never by thedestination path (the
connect()sockaddr is behind a pointer the filter can't dereference). So thestatic filter can only choose "all
AF_UNIXor none" — it can't tell the ssh-agent socket fromdocker.sock, since they're the same(AF_UNIX, SOCK_STREAM)class. And because the sandboxbind-mounts the host filesystem read-only, every host socket path is visible inside, so a path-blind
allow would expose everything — which is exactly why the filter blocks
AF_UNIXwholesale. macOS canoffer
allowUnixSocketsbecause Seatbelt rules are path-based; Linux seccomp has no path equivalent.The options I could find:
| Mechanism | Path allowlist? | Privilege | Kernel | In-kernel? | Usable today? |
|---|---|---|---|---|---|
| Mount-masking — tmpfs the socket dirs, rebind the allowed one | ✗ — it's a denylist; can't express "allow only these" without enumerating every socket dir or inverting the fs model | unprivileged | any | ✓ | ✓ (but wrong contract) |
| Landlock (
RESOLVE_UNIX) | ✓ | unprivileged | ABI 9 — merged to mainline, not in a released kernel yet (~7.1) | ✓ | ✗ — not in a released kernel || cgroup-eBPF (
cgroup/connect_unix) | ✓ | privileged (CAP_BPF + CAP_NET_ADMIN + a managed cgroup) | ≥ 6.7 | ✓ | partial — needs BPF + cgroup control || seccomp-notify — a supervisor mediates each
connect()| ✓ | unprivileged | ~5.9+ | ✗ — userspace mediator | ✓ |Bottom line. Landlock's
RESOLVE_UNIXis the clean endgame — unprivileged, in-kernel, by-path —but it's only just merged to mainline and won't reach most users' kernels for years. Until then the two
genuinely-viable options are a privilege tradeoff: cgroup-eBPF (in-kernel, but needs privileged
setup and kernel ≥ 6.7) vs. a seccomp-notify broker (unprivileged and zero-setup, but it moves a small
security-relevant component into userspace). Of the two, seccomp-notify is the one I implemented and
tested end-to-end (against real Claude Code) — it's in the repo with its mechanism writeup and a
red-team record. I also included the mount prototype, mainly to show concretely why masking can't be
a true allowlist.
(I also opened a design issue on the sandbox repo — anthropic-experimental/sandbox-runtime#343)