OpenAI Codex Approval Workflow: Reviewing Before You Merge
Why "just let it run" is the wrong default
The first time you install OpenAI Codex CLI, there's a strong temptation to hand it the keys and walk away. Type a prompt, watch the terminal scroll, come back to a finished feature. For toy projects this feels magical. For anything connected to a real repository, a real CI pipeline, or a real production branch, it's a bad habit waiting to bite you.
Codex is not just a chat window that suggests code. It's an agent that can read your filesystem, write files, run shell commands, and — depending on how you've configured it — push changes without asking twice. That's the entire point of an agentic coding tool: it should be able to do the boring parts (grep through fifty files, run the test suite, fix the failing assertion) without you narrating every step. But "can act autonomously" and "should act autonomously with zero review" are different claims, and conflating them is how a codebase ends up with a committed .env file, a deleted migration, or a dependency bump that silently breaks the build.
The approval workflow is Codex's answer to this tension. It's not a bolt-on safety feature you can ignore — it's the primary interface between your intent and the agent's actions. Understanding how approval modes, sandboxing, and diff review fit together is the difference between using Codex as a force multiplier and using it as a liability generator. This article walks through the mechanics, the failure modes, and the habits that make reviewing Codex output fast instead of tedious.
The three approval modes, and what each one actually trusts
Codex CLI ships with a small number of approval modes that control how much it asks before acting. The names vary slightly across versions, but the underlying spectrum is consistent: at one end, Codex asks before almost everything; at the other, it acts freely and only reports back.
Suggest / read-only mode is the most conservative setting. Codex can read your codebase, reason about it, and propose changes, but it will not write to disk or execute commands without explicit confirmation for each action. This is the mode you want when you're exploring an unfamiliar repository, evaluating whether Codex even understands your codebase's conventions, or working in a repo you don't fully trust yet. It's slow — you're approving nearly every file write — but it's the safest way to build initial confidence.
Auto-edit mode (sometimes surfaced as "auto" with file-write approval) lets Codex modify files in your working directory without asking each time, but it still pauses before running shell commands that could have side effects — installing packages, hitting the network, deleting files, or touching anything outside the project directory. This is the sweet spot for most day-to-day feature work: you trust it to edit code, but you still want a checkpoint before it runs rm -rf or npm install some-random-package.
Full-auto mode removes almost all interactive prompts. Codex edits files and runs commands inside a sandbox without asking, and only stops for things explicitly marked as dangerous or for actions that would escape the sandbox boundary (like network access when it's disabled, or writes outside the approved directory). This mode is fast and genuinely useful for well-scoped, repetitive tasks — bulk renames, mechanical refactors, running an established test suite in a loop until it's green — but it assumes you've already set up guardrails elsewhere (sandboxing, a clean git working tree, CI as a backstop) because you're not going to catch problems in real time.
The mistake teams make is picking a mode once and never revisiting it. The right mode is a function of the task, not a personal preference you set in a config file and forget. A one-line typo fix in a well-tested function is a full-auto task. A change touching authentication, payment webhooks, or database migrations is a suggest-mode task, every time, no exceptions.
Sandboxing: the safety net underneath approval mode
Approval mode controls *when* Codex asks you. Sandboxing controls *what Codex is physically capable of doing* even if something goes wrong — a bad prompt, a hallucinated command, a misinterpreted instruction. These are separate axes and both matter.
Codex CLI's sandbox typically constrains three things:
- Filesystem access — restricting writes to the current project directory (and often a designated scratch or temp path), so a wayward command can't touch your home directory, SSH keys, or unrelated projects.
- Network access — off by default in the strictest sandbox profile, which matters more than people expect. An agent that can shell out to
curlcan also exfiltrate data or pull down unreviewed scripts and execute them. - Process/command execution — some sandbox implementations use OS-level primitives (seatbelt on macOS, containers or namespaces on Linux) to enforce these boundaries at the kernel level rather than trusting the agent to self-police.
Here's the part worth internalizing: sandboxing and approval mode compose. Full-auto mode is only "safe enough for unattended use" *because* it's paired with a sandbox that limits blast radius. If you disable the sandbox to work around a permission error — a common instinct when something fails and you're in a hurry — you've quietly removed the safety net that made full-auto mode acceptable in the first place. If you find yourself disabling sandbox restrictions, that's a signal to drop back to a more conservative approval mode, not to keep full-auto and hope for the best.
A reasonable default policy looks like this:
- Untrusted or unfamiliar repo: suggest mode, sandbox on, network off.
- Familiar repo, exploratory feature work: auto-edit mode, sandbox on, network off unless the task needs package installs.
- Mechanical, well-scoped, well-tested task: full-auto mode, sandbox on, network off, git working tree clean before you start so you can always
git difforgit resetyour way out.
What the diff review step is actually for
Every approval mode eventually produces a diff — a set of file changes Codex wants applied. Reviewing that diff is not a formality. It's the single highest-leverage five minutes in the entire workflow, and it's the step people skip when they're tired or behind schedule.
A useful mental model: treat every Codex diff the way you'd treat a pull request from a junior engineer who is fast, tireless, occasionally overconfident, and has no idea what you actually meant unless you spelled it out. That engineer will produce correct code more often than not. They will also, with some regularity, do things like:
- Solve the stated problem while quietly breaking an unstated invariant elsewhere in the file.
- Add error handling that swallows exceptions instead of surfacing them, because it "made the test pass."
- Introduce a new dependency to solve a problem that three lines of existing utility code already handled.
- Rewrite a function's signature in a way that's locally correct but breaks three call sites it didn't check.
None of this means Codex is unreliable — it means Codex, like any contributor, needs review proportional to the blast radius of the change. Here's a checklist worth running against every diff before you accept it:
- Does the diff match the scope you asked for? If you asked for a bug fix and got a bug fix plus a refactor of an unrelated module, that's a scope-creep flag, not a bonus.
- Are there deleted lines you didn't expect? Deletions hide easily in a wall of additions. Scan the removed lines specifically.
- Did test files change alongside source files? If Codex modified a test to make it pass rather than fixing the code the test was checking, that's a critical catch, and it happens more than people admit.
- Are there new dependencies or imports? A new package pulled in to solve a small problem is a maintenance cost you're accepting on behalf of the whole team.
- Does anything touch secrets, config, or environment files?
.env, credentials, API keys, CI secrets — these deserve manual eyes every single time, no matter how much you trust the run. - Would you be comfortable if this diff had your name on the commit? If the answer is "let me reword the commit message and check one more thing," that's your signal to actually check the one more thing.
Reviewing at the command line
Codex integrates with your existing git workflow rather than replacing it, which means the review tools you already know still apply. A typical review loop looks like this after a Codex session finishes a task:
# See what changed at a glance
git status
# Review the actual diff, not just the file list
git diff
# If the diff is large, review file by file
git diff -- path/to/changed/file.py
# Run the test suite yourself — don't trust a summary that says "tests pass"
pytest -x
# Only stage what you've actually reviewed
git add -pThat last command, git add -p, deserves special mention. It walks you through each hunk of each changed file and lets you stage or skip individually. When Codex has touched six files across a feature, patch-mode staging forces you to look at every hunk instead of blanket-adding everything with git add .. It's slower. It's also the difference between catching a stray debug print statement and shipping it to production.
If you're working inside Codex's own review flow rather than a raw terminal, the same principle holds: don't accept a batch of changes as a single unit if you can review them as discrete, labeled steps. Ask Codex to break a large task into smaller commits or smaller diffs specifically so each one is independently reviewable. A 400-line diff that does five things is much harder to audit than five 80-line diffs that each do one thing.
Writing prompts that reduce review burden later
The approval workflow catches problems after Codex has already done the work. The cheaper fix is upstream: prompts that constrain scope produce diffs that are faster to review. This isn't about being polite to the model — it's about reducing the surface area you have to check.
Compare these two prompts:
Fix the bug where checkout fails for international addresses.In src/checkout/address_validator.py, the validate_postal_code function
assumes a 5-digit US zip format. Fix it to accept international postal
formats without changing the function signature or any other file.
Do not touch the payment processing code in this same directory.
Add a unit test for at least one non-US postal format.The second prompt does three things that matter for review: it names the exact file and function (so you know where to look), it explicitly fences off adjacent code that shouldn't change (so any edit outside that fence is an immediate red flag), and it asks for a test (so the fix has a verification artifact you can run independently of trusting the summary). The resulting diff will be smaller, more predictable, and dramatically faster to review than whatever comes back from the vague version — where Codex has to guess scope and will reasonably choose a broader interpretation "to be safe."
This is a general pattern worth internalizing: every constraint you put in the prompt is a constraint you don't have to verify by hand in the diff. Scope discipline in the prompt is review discipline for free.
Handling the moments Codex asks for elevated permission
Even in auto-edit or full-auto mode, Codex will sometimes hit a wall — a command that needs network access, a file outside the sandboxed directory, a destructive operation it's not confident about — and surface an explicit permission request. How you respond to these matters more than most people treat it.
The wrong instinct is to approve immediately because you're mid-flow and don't want to break momentum. The right instinct is to treat every permission escalation as a deliberate checkpoint the tool is handing you, and to ask one question before approving: *do I understand why it needs this, specifically?*
If Codex wants to run npm install because it added a dependency, check which dependency and why before approving — this is the same new-dependency scrutiny from the diff checklist, just surfaced earlier. If it wants to write outside the project directory, that's almost always worth a hard no unless you specifically asked for a change there (a global config file, a shared library in a sibling directory). If it wants network access to fetch documentation or check a package registry, that's usually benign, but it's still worth noticing how often it's happening — a task that needs five network round-trips to fix a typo suggests the model has lost the plot and is thrashing, which is itself useful signal to stop and re-prompt rather than keep approving.
Treat repeated permission requests as a signal, not noise. If you're clicking "approve" reflexively three or four times in a row, stop and read what you're approving. The whole value of the approval gate evaporates the moment it becomes a rubber stamp.
Team conventions worth adopting
Approval workflow discipline breaks down fastest when it's an individual habit rather than a team norm. A few conventions make it durable across a team using Codex on shared repositories:
- Never run full-auto mode directly against a shared branch. Work on a feature branch, always, regardless of how well-scoped the task looks. This gives you
git diffagainst a known base and an easy escape hatch (delete the branch) if something goes sideways. - Require a clean working tree before starting a Codex session. If you start with uncommitted changes already in play, you lose the ability to cleanly distinguish "what Codex did" from "what I already had in flight."
git stashyour own work first, or commit it, before letting Codex loose. - Treat Codex-authored commits like any other contributor's commits in code review. Don't wave them through because "the AI already checked it." Your CI pipeline, your linters, and your human reviewers should apply the same bar they'd apply to a new team member's first week of pull requests.
- Log which approval mode was used for which task, even informally. When something breaks two weeks later, knowing whether the change was made in suggest mode (heavily reviewed) or full-auto (lightly reviewed) tells you where to look first.
- Rotate who reviews Codex-heavy PRs. A second set of human eyes catches the specific failure mode of "the primary author got used to the agent's style and stopped noticing small issues," which is a real phenomenon after a few weeks of heavy agentic use.
None of these conventions are exotic. They're the same practices good engineering teams already apply to human contributors — scoped branches, clean review gates, CI as a backstop. The insight is that Codex doesn't get an exemption from them just because it's fast.
When to trust it more, and when to trust it less
Calibrating your approval mode over time is itself a skill. A few honest signals worth tracking:
Trust Codex more, and move toward auto-edit or full-auto, when: the task is mechanical and well-defined, your test suite has real coverage over the code being touched, the repo has clear conventions Codex has already demonstrated it follows, and the blast radius of a mistake is small (a script, a test file, an internal tool).
Trust Codex less, and stay in suggest mode, when: the change touches authentication, payments, data migrations, or anything with compliance implications; the task is genuinely ambiguous and you're not sure what "correct" looks like yourself; the codebase lacks tests in the area being changed, so you have no independent signal besides reading the diff carefully; or you've noticed Codex making the same category of mistake twice in recent sessions — that's a pattern, not a fluke.
This calibration is dynamic, not a one-time setup step. A repo that starts life needing suggest-mode scrutiny for every change can, after a few months of consistent good outcomes and a solid test suite, graduate to auto-edit for most work. Conversely, if you onboard Codex onto a new, unfamiliar codebase, drop back down to suggest mode even if you've been running full-auto elsewhere — familiarity with your specific conventions doesn't transfer between repos.
The review habit is the actual skill
It's tempting to think of approval workflow as a settings toggle you configure once. It's more accurate to think of it as a reviewing skill you build, the same way code review itself is a skill that improves with deliberate practice. The mechanics — approval modes, sandbox flags, git diff, git add -p — are simple to learn in an afternoon. What takes longer is developing the instinct for which diffs deserve five seconds of glance and which deserve five minutes of line-by-line scrutiny, and building the discipline to actually stop and look even when the agent has been right nine times in a row.
That instinct is exactly what separates teams that use Codex to genuinely ship faster from teams that use it to accumulate quiet technical debt they'll discover during an incident review six months later. The tool rewards the same rigor you'd apply to any fast, capable, occasionally-wrong collaborator — human or otherwise.
If you want to go deeper on the mechanics covered here — sandbox profiles, prompt scoping techniques, setting up review checkpoints inside multi-step Codex sessions, and building team conventions around agentic coding tools — our OpenAI Codex CLI Tutorial course on teachyou.ai walks through the full workflow hands-on, from first install to running Codex safely against a real production-style repository.
AI CodingShip full-stack AI apps at conversation speed — specs, agents, deploys, all from the terminal.
CodexLearn to drive OpenAI's coding agent: real tasks, safe sandboxing, and terminal-to-cloud workflows that ship.