Skip to content

permissions.<id>.network.unix_sockets config not propagated to macOS Seatbelt policy #25416

@naoto256

Description

@naoto256

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 chore: refactor network permissions to use explicit domain and unix socket rule maps #15120
  • permissions.<id>.network.allow_unix_sockets = ["/path"] — legacy array form
  • permissions.<id>.experimental_network.unix_sockets = {...}
  • permissions.<id>.experimental_network.dangerously_allow_all_unix_sockets = true
  • permissions.<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 :workspace was 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 (without extends) triggers the warning "Permissions profile workspace-write does 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 (Linux sandbox: support safe sandbox-local AF_UNIX sockets (e.g., sccache) #16910); this one is specifically about the macOS Seatbelt path being half-wired.

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingconfigIssues involving config.toml, config keys, config merging, or config updatessandboxIssues related to permissions or sandboxing

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions