Why Workspace-write Still Blocks Network Access
It looks inconsistent at first glance — a sandbox mode permissive enough to edit and run commands freely inside your project, but still blocking outbound network calls by default. It isn't inconsistent once you separate what the two kinds of access actually risk.
Two different categories of risk, not one sliding scale
Editing and running commands inside a workspace is bounded by the workspace itself — even a mistaken or overly broad edit affects files you already control, inside a directory you already chose to work in. A network call reaches outside that boundary entirely: it can send data somewhere, fetch and potentially execute something you didn't examine first, or interact with a service in ways that aren't reversible the way a bad file edit usually is. Treating "can it touch files in my project" and "can it reach the internet" as the same permission would collapse two genuinely different risk profiles into one setting, which is exactly what this split avoids.
Why the split matters most for agentic sessions specifically
An agentic session iterating on its own, potentially across many turns without you reading every single action closely, is precisely the context where an unexpected network call is easiest to miss — a package install that pulls in something unintended, a request to an endpoint that wasn't part of the task. Requiring network access to be turned on deliberately, rather than defaulting to available, means that class of surprise needs an explicit decision behind it rather than happening as a side effect of an otherwise-reasonable-looking task.
What this means in practice, concretely
A task that needs to install a dependency, call an internal API, or fetch something from the web will fail under the workspace-write default until network access is explicitly enabled — and that failure can look like a tooling problem rather than a deliberate restriction if you don't already know the default exists. Recognizing a connection-refused or unreachable-host style failure as possibly this default, rather than immediately assuming something's broken, saves real debugging time the first several times you hit it.
Enabling it deliberately, per task or per project
Turning network access on is a configuration change, not a sandbox-mode change — you're still in workspace-write, just with that one additional capability explicitly granted. Doing this per task, when a specific task actually needs it, rather than as a standing global setting you forget is even on, keeps the deliberate-decision property intact rather than quietly reverting to "network always available" through a setting nobody remembers configuring.
A useful mental test before enabling it
Before turning network access on for a given task, it's worth asking plainly what the task would actually do with it — install one specific known dependency, call one specific known endpoint — versus a vaguer sense that "it might need internet access for something." A task with a specific, nameable network need is a reasonable candidate to enable it for; a task where the need is vague is worth scoping more precisely first, since a vague justification for network access is exactly the kind of thing this default exists to make you stop and articulate.
This default doesn't apply the same way under every sandbox mode
read-only doesn't need a separate network conversation — its restriction is broader and network access isn't part of what it permits regardless. danger-full-access removes the workspace boundary and, consistent with its name, doesn't apply this same off-by-default network restriction either. The network-off-by-default behavior is specifically a workspace-write characteristic, worth understanding as belonging to that one mode rather than as a general rule about Codex's sandboxing across every mode uniformly.
Why this is worth understanding rather than just working around
It would be easy to treat this default purely as friction — a thing to switch on reflexively at the start of every session so you never hit the restriction again. That defeats the actual purpose: the default exists so that a task with a genuine, specific network need gets a deliberate decision, and a task without one simply doesn't carry that risk at all. Understanding why the split exists is what makes it worth respecting rather than routing around out of habit.
Checking whether it's actually enabled for a running session
If you're unsure whether a session currently has network access enabled, checking the CLI's current documentation for how that state is reported — rather than assuming from whether a prior task happened to need it — is worth doing before running anything that depends on reaching an external service, since an incorrect assumption here fails in the least convenient way: partway through a task that was otherwise going fine.
The failure signature worth recognizing quickly
A command that hangs, times out, or reports a connection refused where you'd normally expect a fast response — a package manager unable to reach its registry, a script unable to resolve a hostname it should easily reach — is the specific shape of failure this default produces, and it's worth having as a pattern-matched first guess before spending time on other explanations. Compare that against a genuinely broken command (a typo, a missing dependency already on disk, a real bug in the script) which usually fails immediately and specifically rather than hanging or timing out the way a blocked network call typically does.
Why this default doesn't get relaxed globally by most teams
It would be simpler, in one sense, for a team to just enable network access globally once and stop thinking about it per task — and some teams do exactly that for a specific, trusted, long-running project where the tradeoff has been deliberately considered. Most teams don't, because the value of the default isn't really about any single task's risk, it's about keeping the decision visible and current — a global always-on setting is exactly the kind of configuration that gets set once, forgotten, and never revisited even as the tasks running under it change over time.
This default is one of several defense layers, not the only one
Network-off-by-default sits alongside the workspace boundary itself, the protected-paths list, and the destructive-tool-call approval override as one layer among several — none of them is meant to be the single thing standing between a session and a genuinely bad outcome. Understanding it as one deliberate layer in a broader, defense-in-depth design is a more accurate mental model than treating it as an isolated inconvenience to route around as quickly as possible.
Verified 2026-08-09 against CodexHow facts module (src/data/facts/) — see /about/#accuracy.