Repository navigation
No agent mode exposes workspace-write *with* network access #406
Description
Activity
FWIW, I got mine to work with network access AND manual approvals with
INITIAL_AGENT_MODE = 'agent' CODEX_CONFIG = '{ "approval_policy": "on-request", "approvals_reviewer": "user", "sandbox_mode": "workspace-write"}'Confirming this from a different client/setup, with a measurement that may help land one of the open fixes.
Environment: Zed (macOS, Apple Silicon) driving
codex-acp1.13.1 fromagent_servers, Codex CLI 0.157.1. The session runs in the default mode (agentviaDEFAULT_AGENT_MODE;INITIAL_AGENT_MODEis not set). This is a plain Agent prompt — no explicit mode change.Observed — a network command in the default
agentmode fails at DNS resolution, not at the forge:$ curl -sS -m 8 -o /dev/null -w '%{http_code}\n' https://api.github.com curl: (6) Could not resolve host: api.github.com 000The same command through Codex's own sandbox, with the combination this request asks for, works:
$ codex sandbox -c sandbox_mode=workspace-write -- curl ... https://api.github.com curl: (6) Could not resolve host: api.github.com # 000 $ codex sandbox -c sandbox_mode=workspace-write -c sandbox_workspace_write.network_access=true -- curl ... https://api.github.com 200So the only difference between "blind to the network" and "works" is exactly the
network_accessflag the per-turn policy discards — confirming both halves of the report on 1.13.1.I also traced the code path in 1.13.1:
AgentMode.Agent(theDEFAULT_AGENT_MODE) hardcodesnetworkAccess: false, andsendPromptpassessandboxPolicy: addAdditionalDirectoriesToSandboxPolicy(agentMode.sandboxPolicy, …)into everyturn/start;addAdditionalDirectoriesToSandboxPolicyonly appends writable roots and never touchesnetworkAccess. Asandbox_workspace_write.network_access = truesupplied viaCODEX_CONFIG/config.tomlreachesthread/startand is then overwritten on the first prompt turn — exactly as described.+1 for direction 1 (let
CODEX_CONFIG/config.tomlwiden the selected mode rather than being overwritten): it is the smallest change and would close #310 as well. Both #561 and #368 already implement the network half of it — would love to see one of them merged.Current workaround: selecting
agent-full-accessfor the session, which grants unrestricted filesystem access and turns approvals off — far more privilege than a task that only needsgit ls-remote/git fetch.Reproduced this on upstream v2.2.2 and opened #608 with a configuration-based fix.
For workspace-write turns, it uses an explicit boolean from CODEX_CONFIG first, then Codex's effective config/read result for the working directory, then the existing mode default. This covers config.toml as well as the supplied session configuration, while leaving other sandbox types, writable roots and approvals unchanged.
The new policy tests reproduce the problem before the change and pass afterward. A native Codex config/read probe also confirmed that the file-backed flag reaches the outgoing workspace-write policy; it made no model requests. Full local tests pass except for three filesystem-watcher failures that also reproduce on the unmodified upstream SHA in this macOS environment. The PR remains Draft pending the release-matrix/CI checks.
Related to the existing approaches in #561 and #368; this proposal includes the effective file-configuration path rather than changing everyone's default mode.
Summary
codexitself supports workspace-write sandboxing with network access enabled —sandbox_mode = "workspace-write"plus[sandbox_workspace_write] network_access = true. None ofcodex-acp's three agent modes exposes that combination, and no configuration path can reach it.The result is that a host application driving
codex-acphas only two usable options:read-onlyreadOnlyagent(default)workspaceWriteagent-full-accessdangerFullAccess, approvalneverSo enabling network for an agent means giving up the workspace boundary and approvals at the same time. There is no way to say "keep the workspace sandbox, allow network".
Why this matters
Our use case is an automated code-review agent. It runs in a checkout, and its job legitimately ends in network calls —
git ls-remote/git fetchagainst the forge, then posting the review back. Under the defaultagentmode every one of those fails, and the run ends with nothing to do. The only mode that lets it work isagent-full-access, which also removes the workspace boundary and silences approvals — considerably more privilege than the task needs, for an agent whose whole design premise is that its worst case should be a wrong opinion.Running the same prompt through the
codexCLI directly works exactly as wanted:--strict-configaccepts the key, so it is a recognised setting — it just cannot be reached through ACP.Cause
Two things combine.
1. The modes are hardcoded.
AgentModedefines exactly three statics, andAgent— which isDEFAULT_AGENT_MODE— fixesnetworkAccess: false:Nothing constructs an
AgentModeanywhere else, andAgentMode.find()resolves only against those three — including forINITIAL_AGENT_MODE, where an unrecognised value falls back toagentsilently.2. Config cannot widen it, because the policy is re-asserted every turn.
CODEX_CONFIGdoes reach the session —CodexAcpClientkeeps it asthis.config,createSessionConfig()merges it, and it is sent as theconfigfield ofthread/start. ButsendPromptthen passes the mode's policy into everyturn/start:There is no conditional, and
addAdditionalDirectoriesToSandboxPolicyonly appends writable roots — it never touchesnetworkAccess. So asandbox_workspace_write.network_access = truesupplied viaconfig.tomlorCODEX_CONFIGis transmitted at thread start and then overwritten on the first prompt turn.This is observable from the host side: a session run this way records
— an explicit turn-level policy object rather than a config-level mode string.
There is a subtlety worth flagging for anyone debugging this:
runReviewandrunGoalSetdo not send asandboxPolicy, so the thread-level config still governs those. That makes it possible to see config-supplied network settings appear to work on one path while silently having no effect on ordinary prompts.Versions
Observed on 1.1.14. Verified still present in 1.3.0 (latest at time of writing) — the
Agentstatic still carriesnetworkAccess: false, andsendPromptstill passessandboxPolicy: addAdditionalDirectoriesToSandboxPolicy(agentMode.sandboxPolicy, …)intorunTurn. So upgrading does not address it.Relationship to #310
Same chokepoint, different missing capability. #310 asks for granular approval policy from
config.toml, and a commenter there additionally wants sandbox-off-with-approvals-on. This request is the other axis — keep the workspace sandbox and the approval behaviour exactly asagenthas them, and only allow network. Neither is a superset of the other, but a fix that decouples the policy dimensions from the three presets would resolve both.Possible directions
Roughly in increasing order of scope, and entirely your call which fits the project:
CODEX_CONFIG/config.tomlwiden the selected mode rather than being overwritten — i.e. treat the mode as a default and the config as an override at turn construction. This is the smallest change and would close Sandbox and approval policies from config.toml are ignored #310 too.agent-network:workspaceWrite+networkAccess: true, approval stillon-request. Cheap and explicit, but adds a preset rather than removing the coupling.networkAccessselectable independently of the sandbox type — a config knob or an ACP session option — which is the general form of the problem both this and Sandbox and approval policies from config.toml are ignored #310 describe.Happy to test a patch against our setup if that would help; we drive
codex-acpover ACP stdio from a host application and can report what a real run records.