You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
codex itself supports workspace-write sandboxing with network access enabled — sandbox_mode = "workspace-write" plus [sandbox_workspace_write] network_access = true. None of codex-acp's three agent modes exposes that combination, and no configuration path can reach it.
The result is that a host application driving codex-acp has only two usable options:
mode
sandbox
network
read-only
readOnly
✗
agent(default)
workspaceWrite
✗
agent-full-access
dangerFullAccess, approval never
✓
So 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 fetch against the forge, then posting the review back. Under the default agent mode every one of those fails, and the run ends with nothing to do. The only mode that lets it work is agent-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 codex CLI directly works exactly as wanted:
--strict-config accepts the key, so it is a recognised setting — it just cannot be reached through ACP.
Cause
Two things combine.
1. The modes are hardcoded.AgentMode defines exactly three statics, and Agent — which is DEFAULT_AGENT_MODE — fixes networkAccess: false:
staticAgent=new_AgentMode("agent","Agent","Read and edit files, and run commands.","on-request",{type: "workspaceWrite",writableRoots: [],networkAccess: false,excludeTmpdirEnvVar: false,excludeSlashTmp: false},"workspace-write");
Nothing constructs an AgentMode anywhere else, and AgentMode.find() resolves only against those three — including for INITIAL_AGENT_MODE, where an unrecognised value falls back to agent silently.
2. Config cannot widen it, because the policy is re-asserted every turn.CODEX_CONFIGdoes reach the session — CodexAcpClient keeps it as this.config, createSessionConfig() merges it, and it is sent as the config field of thread/start. But sendPrompt then passes the mode's policy into every turn/start:
There is no conditional, and addAdditionalDirectoriesToSandboxPolicy only appends writable roots — it never touches networkAccess. So a sandbox_workspace_write.network_access = true supplied via config.toml or CODEX_CONFIG is 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: runReview and runGoalSet do not send a sandboxPolicy, 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 Agent static still carries networkAccess: false, and sendPrompt still passes sandboxPolicy: addAdditionalDirectoriesToSandboxPolicy(agentMode.sandboxPolicy, …) into runTurn. So upgrading does not address it.
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 as agent has 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:
Let CODEX_CONFIG / config.toml widen 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.
Add a fourth mode, e.g. agent-network: workspaceWrite + networkAccess: true, approval still on-request. Cheap and explicit, but adds a preset rather than removing the coupling.
Happy to test a patch against our setup if that would help; we drive codex-acp over ACP stdio from a host application and can report what a real run records.
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.