CodexHowSupport Us

Sandboxing Codex for a CI Pipeline, No Surprises

A Codex-calling CI step that works perfectly in every manual test and then behaves differently — or fails outright — the first time it runs unattended in the actual pipeline is a specific, recurring category of surprise, and it almost always traces back to a sandbox or approval assumption that held during interactive testing and quietly stopped holding once nobody was there to answer a prompt.

Why interactive testing hides the exact problem CI exposes

When you're testing a Codex-calling step by hand, you're present — an approval prompt you didn't expect gets answered by you, in the moment, and the step completes. That same step, wired into an unattended pipeline with an approval mode that still expects prompting, doesn't get answered by anyone. It hangs, or times out, or fails in a way that looks nothing like the smooth manual test run that preceded it. The gap between "worked when I tested it" and "works in CI" is, more often than not, exactly this gap between attended and unattended approval expectations.

Getting the approval mode right for a genuinely unattended context

--ask-for-approval never is the mode built for this — no prompting, because there's nobody there to answer one. The detail worth internalizing precisely: this doesn't remove every possible pause. A destructive-annotated MCP tool call still requires approval regardless of approval mode, which means a genuinely unattended pipeline needs to be designed around that possibility explicitly, not assume never guarantees an uninterrupted run from start to finish.

Sandbox mode, chosen for what the step actually does

A read-only review or analysis step belongs in read-only, paired with never-prompt — the combination this site's own read-only CI profile guidance covers directly, and one where the destructive-tool-call caveat above is largely moot, since a read-only session has nothing destructive to attempt in the first place. A step that genuinely needs to write — auto-formatting, generating a file — needs workspace-write, scoped as tightly as the task allows rather than granted broadly out of convenience.

The network default that catches people specifically in CI

workspace-write turns off network access by default, and this bites CI pipelines more than interactive use precisely because a CI step is less likely to have a human present who'd notice a network-dependent command silently failing and investigate immediately — it might sit failing, unnoticed, for a while, especially if the pipeline's overall status reporting doesn't surface the specific step's specific error clearly. Any CI step that needs to reach the network — installing a dependency, hitting an internal service — needs that access enabled explicitly, and it's worth confirming this deliberately during setup rather than discovering it during the pipeline's first real failure.

The deprecated flag that survives longest in exactly this context

CI configuration is where an old --full-auto invocation tends to live the longest, set up once and rarely revisited, running quietly until the eventual removal of the flag breaks a pipeline nobody's looked at in months. Auditing CI-specific configuration for this flag, specifically, as its own pass — not just something caught incidentally during other work — closes off a failure mode that's entirely avoidable with a few minutes of proactive searching.

Trust posture and a freshly checked-out CI workspace

CI environments frequently check out a fresh copy of a repository for every run, and it's worth confirming that fresh checkout is recognized as version-controlled (which it will be, since it's a git checkout) rather than assuming some CI-specific quirk in how the checkout happens might cause it to start in the more restrictive non-version-controlled default posture. This is usually a non-issue in practice, but it's exactly the kind of assumption worth confirming once rather than carrying forward untested.

Testing the unattended path, not just the interactive one

The single most effective way to avoid CI-specific sandbox surprises is testing the actual unattended invocation — the real flags, the real approval mode, run without a human standing by to intervene — before it goes live in a pipeline gating real work. A manual test where you're present to catch and correct anything unexpected isn't a substitute for this, because it's precisely the unattended behavior that differs, and that difference is the whole point of this page.

Building a checklist rather than relying on memory

Given how many small decisions this involves — sandbox mode, approval mode, network access, the deprecated-flag check, trust posture — writing them down as a short checklist for any new Codex-calling CI integration is worth more than trying to remember the full list from experience each time. A checklist converts "surprises found the hard way, one pipeline at a time" into "known considerations, checked deliberately, every time" — which is, in miniature, the entire value proposition of a checklist over intuition for any repeatable technical task.

Why CI amplifies a mistake that would be minor in an interactive session

A misconfigured sandbox in an interactive session produces one bad experience, once, for the person running it — annoying, but bounded and immediately visible. The same misconfiguration wired into a CI pipeline that runs on every commit produces that bad experience repeatedly, automatically, at whatever rate the pipeline fires, often invisibly if nobody's specifically watching that step's output. A five-minute sandbox misconfiguration caught in interactive testing is a five-minute problem; the same misconfiguration shipped into CI can run wrong hundreds of times before anyone notices the pattern.

Treating the first production run as part of the rollout, not the finish line

Passing every test in a staging environment doesn't guarantee identical behavior against a pipeline's actual production triggers, actual repository sizes, and actual commit patterns — those are a different, messier test than any staging run can fully replicate. Watching the first several real production runs closely, rather than considering the integration finished the moment staging tests pass, is what actually catches the class of surprise this whole page is about before it's had a chance to run unnoticed for a while.

Where this leaves teams building their first Codex-calling pipeline

If this is your first time wiring Codex into an unattended pipeline, the honest expectation to set is that the first version won't be perfectly configured on the first attempt — the goal isn't zero surprises on day one, it's a deliberate process (this checklist, tested against the real unattended path, watched closely on its first real runs) that catches whatever surprises do show up quickly and cheaply, rather than discovering them expensively months later.

Verified 2026-08-09 against CodexHow facts module (src/data/facts/) — see /about/#accuracy.