macOS: network_access = true in config.toml silently ignored by seatbelt sandbox — workaround included
Problem
On macOS, setting network_access = true under [sandbox_workspace_write] in ~/.codex/config.toml has no effect. The seatbelt sandbox unconditionally sets CODEX_SANDBOX_NETWORK_DISABLED=1, causing all outbound network calls (OCI CLI, curl, API clients, etc.) to fail with connection timeouts.
This affects any workflow that requires network access from within a Codex session — cloud CLI tools (OCI, AWS, GCP), package registries, API calls, etc.
Environment:
- macOS (Darwin 25.2.0)
- Codex CLI installed via Homebrew (
/opt/homebrew/bin/codex) config.tomlwithnetwork_access = trueunder[sandbox_workspace_write]
Reproduction:
- Set
network_access = truein~/.codex/config.toml:
``toml``
[sandbox_workspace_write]
network_access = true
- Launch
codexand run any network command (e.g.curl https://example.comor an OCI/AWS CLI call) - Command fails with connection timeout / "not reachable"
Root cause: The macOS seatbelt sandbox profile (codex-rs/core/src/seatbelt_network_policy.sbpl) enforces network blocking at the OS level regardless of config.toml.
Confirmed Workaround
The only reliable fix is bypassing the seatbelt sandbox via CLI flag:
codex --sandbox danger-full-access "your prompt"
Or as a persistent shell alias:
alias codex='CODEX_SANDBOX_NETWORK_DISABLED=0 codex --sandbox danger-full-access'
Setting sandbox_mode = "danger-full-access" in config.toml alone is not sufficient — the CLI flag is required.
Proposed Fix
The seatbelt profile should respect the network_access = true configuration from config.toml the same way the Linux Landlock sandbox does. When a user explicitly opts in to network access via config, the seatbelt policy should conditionally allow outbound connections instead of unconditionally blocking them.
A potential implementation path:
- In
codex-rs/core, readnetwork_accessfrom the resolved config before generating the seatbelt profile - Conditionally include/exclude the network deny rule in
seatbelt_network_policy.sbpl - This would make macOS behavior consistent with the documented
config.tomlsettings
Happy to submit a PR if the team agrees with this approach.
Related Issues
- #8714 (per-project config ignored,
CODEX_SANDBOX_NETWORK_DISABLED=1forced) - #5041 (VS Code extension blocks network with
danger-full-access) - #3454 (network_access permission not working)
- #5090 (sandbox/network enforcement regression)
13 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Not a duplicate — those issues were closed without a workaround or root cause analysis.
This issue provides both:
--sandbox danger-full-access+CODEX_SANDBOX_NETWORK_DISABLED=0)network_access: truein the seatbelt path (unit + integration tests proving the OS-level sandbox behavior), plus tracing inderive_sandbox_policy()so users can debug why network is blockedThe integration tests in #10392 confirm the seatbelt code on
maindoes correctly handlenetwork_access: true— the policy includes network rules and socket creation succeeds undersandbox-exec. This means the bug users are hitting is likely a version mismatch between their installed binary and currentmain, or the config resolution path silently falling back to defaults (which the new tracing would surface).The pre-existing seatbelt tests (
create_seatbelt_args_with_read_only_git_and_codex_subpaths,create_seatbelt_args_with_read_only_git_pointer_file) also have a macOS/var/foldersvs/private/var/folderspath mismatch bug — unrelated to this issue but worth noting.Closing this as a duplicate of issues that were themselves closed without resolution doesn't help the users still hitting this. Happy to iterate on the PRs if the team has feedback.
Can confirm the issue on Codex MacOS app as well.
The app also does not respect the setting
Feel free to try this solving your problem. It works for me ; curious to know
Quick follow-up after re-checking current
main: the macOS seatbelt path now has substantial sandbox/network changes (including dynamic network policy and proxy-aware routing in recent sandbox PRs), which looks like it may have addressed the originalnetwork_accessbehavior reported here. @etraut-openai could you confirm whether this issue is now considered fixed on latest releases, or if there is still a reproducible gap for macOS users? If fixed, I can help validate and close with tested version details.I encountered the same issue. Using MCP is an interesting option, but in my workflow I need to invoke Bazel directly. Bazel itself provides many tools such as
bazel query, so agents still need to invokebazeldirectly to work and to diagnose problems.I added this to my Codex settings:
Even with that, the project still fails like this:
I am not an expert on Seatbelt, but it seems like Codex could potentially support an option to allow binding to a local port. That would not weaken security very much, but it would make Bazel work in this setup. I am not sure whether this is feasible, but it would be great if Codex could support it. Thanks.
It seems pretty non-intuitive to configure
workspace-writemode but, on the Mac, silently ignore that setting and change toseatbeltmode. Ifseatbeltmode is desirable, it seems like I should be able to disable it without resorting todanger-full-accessmode.@etraut-openai following up on this issue after the latest report on March 17, 2026: has this been addressed in current releases, or is there still an open macOS behavior gap here?
The latest feedback suggests the remaining problem may now be less about raw network egress and more about the UX/config model on macOS: users configure
workspace-write, but Codex appears to silently enforceseatbeltsemantics unless they jump all the way todanger-full-access.If this is fixed, could you share which release/version contains the fix and what the expected behavior is on macOS for:
workspace-writenetwork_access = trueseatbeltwithout usingdanger-full-accessThat would help clarify whether this issue should be closed or reframed.
Adding data from a Tuist + SPM iOS project:
The silent network block causes
tuist generateto hang indefinitely when a project is connected to Tuist Cloud (fullHandleset inTuist.swift). Tuist attempts auth againsttuist.devduring workspace generation — with network silently blocked, the call never completes and never errors. No timeout, no log output, just a permanent stall.Workaround: Setting
optionalAuthentication: truein Tuist'sgenerationOptionsmakes it skip server interactions gracefully when auth is unavailable. Generate goes from hanging indefinitely to completing in ~3 seconds with a warning.Additional seatbelt findings from the same project:
swift package resolvefails withsandbox_apply: Operation not permitted(nested sandbox-exec). Fix:--disable-sandboxflag.xcodebuild -listfails with exit 66 and misleading"not a workspace file"error — actually caused by missing CoreSimulator XPC/mach-lookup services in the seatbelt allowlist, not a bad workspace.network_access = trueand broadwritable_rootsin.codex/config.tomlhad no observable effect on any of these behaviors.The core issue remains:
workspace-writewithnetwork_access = truesilently enforces seatbelt with no network. Every tool that phones home (Tuist Cloud, CocoaPods trunk, SwiftPM registry auth, Fastlane) will hang or fail without tool-specific opt-outs.When Codex on a Mac cannot even run a Maven build because it blocks both the ability to download dependencies and write into $HOME/.m2/repository, might as well call the mode
worthless. Dangerous mode is the only mode that lets developers use Codex to do their day-to-day work…Root Cause Analysis & Fix
After tracing the full code path from config parsing through sandbox enforcement, I've identified the root cause and submitted a fix with full test coverage.
Root Cause
The issue is in
dynamic_network_policy_for_network()(codex-rs/sandboxing/src/seatbelt.rs). It combines three unrelated conditions into a single guard:When
enforce_managed_networkistrueor a proxy config is present but no usable proxy ports exist, the function enters the restricted path, builds an empty network policy (no ports to allow through), and returns it — silently blocking all network regardless of the user'snetwork_access = true.Two additional findings that make this worse than it appears:
enforce_managed_networkis not an admin policy flag. It's set inexec.rs:241asparams.network.is_some()— a proxy-presence indicator, not a security enforcement mechanism. There is no admin-level override in the current architecture.core/src/seatbelt.rshardcodesenforce_managed_networktofalseinspawn_command_under_seatbelt(). The flag only takes effect through theSandboxManagertransform path.The Fix
Separated the proxy-routing logic from the no-proxy fallback:
| Scenario | Before (broken) | After (fixed) |
|----------|-----------------|---------------|
| Usable proxy exists | Route through proxy | Route through proxy (unchanged) |
| No proxy +
network_access=true| Silent empty policy → blocked | Full network +tracing::warn!|| No proxy +
network_access=false| Blocked (fail-closed) | Blocked (unchanged) |Explicit user config is honored when there is no proxy to route through. Fail-closed behavior is preserved when the user did not request network access. All overrides are logged via
tracing::warn!so the behavior is never silent.Additionally,
derive_sandbox_policy()inconfig/mod.rsnow logs the resolved sandbox mode, its source (cli-flag/config-profile/config-toml/default), and thenetwork_accessvalue — making the entire config resolution chain visible withRUST_LOG=info.Test Coverage
network_access×enforce_managed_network× proxy configsandbox-execon macOS (localhost bind, CI-safe)mainare unrelated (/var/folderspath mismatch)PR
https://github.com/fede-kamel/codex/pull/1 — ready for review, rebased on current
main. Supersedes #10392.Unable to open directly against this repo due to contribution policy restrictions. Happy to resubmit upstream if the team opens it up.
---
cc @etraut-openai @bolinfest @pakrym-oai @rreichel3-oai — you've been the most active on the sandbox/seatbelt code recently. Would appreciate your review.
cc @robertpatrick @BigCactusLabs @bc-lee @jawwadfirdousi — this should resolve the Maven, Tuist, and general
network_access = trueissues you've reported.End-to-End Verification on macOS
Built codex from the fix branch (
744f337c3) and tested under real seatbelt enforcement. All tests run on macOS Darwin 25.2.0 (aarch64).Test Results
| Test | Mode |
network_access| Result ||------|------|-------------------|--------|
|
curl https://example.com| seatbelt (workspace-write) |true| HTTP 200 ||
curl https://example.com| seatbelt (workspace-write) |false| HTTP 000 (blocked) || TCP socket bind
127.0.0.1:0| seatbelt (workspace-write) |true| SUCCESS: bound to 127.0.0.1:52930 || TCP socket bind
127.0.0.1:0| seatbelt (workspace-write) |false| Operation not permitted ||
cargo test -p codex-sandboxing seatbelt| unit + integration | — | 24/24 pass ||
cargo check -p codex-core| compile | — | clean |Reproduction
@robertpatrick @BigCactusLabs — if you want to validate this against your Maven / Tuist workflows before the team merges, the steps above should get you going.
@etraut-openai ^