permissions.<id>.network.unix_sockets config not propagated to macOS Seatbelt policy
Summary
The canonical permissions schema accepts permissions.<id>.network.unix_sockets (per #15120) and codex doctor reports the config as loaded with no warnings, but the allowlist is never injected into the generated Seatbelt SBPL. Connecting to a listed AF_UNIX socket from a sandboxed child still produces a network-outbound denial.
The equivalent CLI flag --allow-unix-socket (from #17654) works correctly, which confirms the Seatbelt-side machinery is fine — only the config → SBPL wiring is missing.
Version
codex-cli 0.135.0-alpha.1
Codex.app on macOS 26.5 (aarch64)
Repro
~/.codex/config.toml:
default_permissions = "uds-test"
[permissions.uds-test]
extends = ":workspace"
[permissions.uds-test.network.unix_sockets]
"/tmp/.X11-unix" = "allow"
$ codex doctor | grep config
✓ config loaded # no warnings, profile recognized
$ codex sandbox --permissions-profile uds-test --log-denials -- \
python3 -c 'import socket; s=socket.socket(socket.AF_UNIX); s.connect("/tmp/.X11-unix/X0")'
ERR PermissionError [Errno 1] Operation not permitted
=== Sandbox denials ===
(Python) network-outbound /tmp/.X11-unix/X0
The same socket via the CLI flag works:
$ codex sandbox --permissions-profile uds-test \
--allow-unix-socket /tmp/.X11-unix -- \
python3 -c 'import socket; s=socket.socket(socket.AF_UNIX); s.connect("/tmp/.X11-unix/X0")'
# OK
Other schema variants I tried (none work)
All accepted by the config loader, none reach Seatbelt:
permissions.<id>.network.unix_sockets = { "/path" = "allow" }— canonical per #15120permissions.<id>.network.allow_unix_sockets = ["/path"]— legacy array formpermissions.<id>.experimental_network.unix_sockets = {...}permissions.<id>.experimental_network.dangerously_allow_all_unix_sockets = truepermissions.<id>.network.network_access = true(also not wired)- Top-level
experimental_network.unix_sockets - Top-level
experimental_network.allow_unix_sockets
The only working config-side switch I found is the legacy, pre-profile path:
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true
…but that opens the entire network namespace, which is exactly the over-reach #15120's unix_sockets map was meant to avoid.
Expected
A permissions.<id>.network.unix_sockets entry on the active profile should produce the same SBPL allow rules as --allow-unix-socket:
(allow network-bind (local unix-socket (subpath "...")))
(allow network-outbound (remote unix-socket (subpath "...")))
Notes
- On my install, only
:workspacewas a recognized built-in;extends = ":workspace-write"failed with "cannot extend unsupported built-in profile". Documenting which built-ins ship per build flavor would help. - Defining
[permissions.workspace-write]directly (withoutextends) triggers the warning "Permissions profileworkspace-writedoes not define any recognized filesystem entries" and silently strips the built-in filesystem defaults — that footgun is a separate UX concern. - Linux side has its own open issue (#16910); this one is specifically about the macOS Seatbelt path being half-wired.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗