Skip to content
Agentic Control Plane

The Codex CLI control model, explained

Codex CLI’s control story used to be easy to summarize: strong sandbox, coarse approvals, no extension surface. That summary is now wrong in every clause. Through spring and summer 2026 OpenAI shipped a full hooks system (on by default, Claude Code-compatible), fine-grained permission profiles, an enterprise constraints file, a native Windows sandbox, and — in 0.147 — a reviewer agent that approves on your behalf. This page is the current reference, and several widely-repeated facts about Codex are stale; we flag each. Current to 0.147.

This page covers Codex CLI’s own controls. For wiring ACP into Codex, see the install guide.

Approvals: three policies and a Guardian

The approval policy is one of untrusted (prompt for anything not known-safe), on-request (the agent escalates when it needs more than its sandbox allows — the default pairing in the standard “Auto” preset with a workspace-write sandbox), or never. Stale-fact flag #1: on-failure was removed in 0.143 — a lot of 2025-era writeups still list it. The /approvals slash command is likewise gone, replaced by /permissions.

Approval answers include a design we’d like others to copy: approved_with_amendment — approve and persist a prefix rule to ~/.codex/rules/default.rules, so the approval becomes reviewable standing policy instead of invisible session memory. Enterprises can constrain what those rules may say (managed prefix rules can only prompt or forbid, never auto-allow).

The Guardian (0.147) is the headline: --approve-for-me (honest alias: --not-so-yolo) routes sandbox escalations, blocked-network requests, and side-effecting calls to a reviewer agent that checks for exfiltration, credential probing, persistence, and destruction. Critical findings deny outright; high-risk ones escalate to the human; reviewer failures fail closed. With Claude Code’s auto mode and Cursor’s Auto-review, that’s all three major harnesses replacing the human prompt with a model in the same season — the pattern and its gaps apply to all three.

The rules and profiles

Config is layered TOML: CLI flags → project .codex/config.toml (trusted projects only — untrusted projects skip all .codex/ layers, and 0.147 requires explicit trust for unfamiliar ones) → profile file → ~/.codex/config.toml → system → managed. Stale-fact flag #2: profiles are now separate files selected with --profile; [profiles.x] blocks inside config.toml are rejected since 0.134.

Permission profiles (beta) are the new fine-grained layer: named profiles with filesystem path→read|write|deny maps (deny beats write beats read; glob deny-reads like "**/*.env" = "deny") and per-domain network allow/deny — declarative resource policy rather than command patterns.

For command patterns, the exec-policy docs deserve credit for stating the limits precisely: compound bash -lc scripts are only split into rule-checkable subcommands for linear &&/||/;/| chains of plain words — redirections, command substitution, env-var assignments, wildcards, or control flow disable splitting entirely, and the rule matches the whole blob or nothing. That’s the honest version of the caveat every string-matching permission system carries.

Enterprise: requirements.toml (filesystem, MDM, or cloud-delivered from the ChatGPT workspace) sets hard constraints — which approval policies, sandbox modes, reviewers, and permission profiles are even selectable, network allowlists, and allow_managed_hooks_only. This is real fleet policy — for this one harness. It can carry ACP’s hook to every seat: the Codex enterprise rollout.

The sandbox

Three modes: read-only, workspace-write (network off inside it by default), danger-full-access. Subprocesses inherit the boundary. Platform mechanics — both stale-fact flags: Linux is now bubblewrap + seccomp with Landlock demoted to fallback, and Windows has a native sandbox as the default (low-privilege sandbox users, ACLs, firewall rules; elevated and unelevated variants) rather than “use WSL.” The old codex debug seatbelt/landlock subcommands are gone; codex sandbox runs arbitrary commands under the policy, which is a genuinely useful way to test what your profile allows before an agent finds out for you.

The hooks

Stale-fact flag #3, and the biggest one: Codex ships a native hooks system, stable and enabled by default from 0.145.0 — the earlier codex_hooks flag was under development and off by default, and is now a deprecated alias that warns on launch.

Hooks have their own page. hooks.json, every event, the PreToolUse deny and rewrite contract, exit code 2, trust review, async hooks, and troubleshooting: the Codex CLI hooks reference. That page is kept current as Codex moves; this one keeps only what the hooks mean for the control model.

Three things about hooks bear on the control model rather than the mechanics. The trust step: a non-managed hook does not run until a person reviews and trusts its exact definition, and the trust is recorded against the hook’s hash, so an edited hook goes back to review. The fleet step: requirements.toml can set allow_managed_hooks_only = true, which skips user, project, session, and plugin hooks and runs only the managed ones — the enterprise rollout page has the file. And the sentence in OpenAI’s docs that every hooks page should carry: treat tool hooks as “a useful guardrail, not a complete enforcement boundary.”

The record

Session rollouts as JSONL under $CODEX_HOME/sessions/ with a local state DB, resume/fork/archive, and opt-in OTel. Deliberate anti-records exist too: codex exec --ephemeral skips persistence, history.persistence = "none", and codex delete is permanent — fine for privacy, worth knowing when you’re reasoning about what evidence will exist later. No independent decision ledger; the rollout is the run’s own account.

Escape hatches and the empty chair

The hatches are explicit and tiered: --sandbox danger-full-access (drops the boundary, keeps approvals), --yolo (drops both), --approve-for-me (keeps the sandbox, delegates approvals to the Guardian), --dangerously-bypass-hook-trust (one invocation’s hook review). --full-auto was deprecated and removed from codex exec in 0.147.

Headless, Codex gets the empty chair right: codex exec defaults to a read-only sandbox and never prompts — blocked actions fail back to the model as errors it can adapt to. Every would-be ask resolves to deny-and-continue, which is exactly what the empty-chair test asks for. The risk profile is therefore concentrated in the flags: an unattended invocation is one --yolo in a cron job away from no controls at all, and nothing records that the flag was set.

Where the native model ends

Codex’s 2026 arc is the fastest control-surface improvement of any harness — from coarse approvals to profiles, Guardian, native hooks, and fleet constraints in about six months. The structural edges that remain:

  • Reviewer opacity. The Guardian’s verdicts, like every classifier gate, are judgment without a queryable rationale trail. Fail-closed is the right default; explainability isn’t there yet.
  • Per-harness fleet policy. requirements.toml is real enterprise control — for Codex. The same constraints don’t exist for the other harnesses on the same laptops, and each vendor’s channel carries a different file: what the four admin channels share.
  • The record is the run’s own, local, and deliberately deletable.
  • String rules stop at the documented line. The exec-policy splitting rules are honest about exactly where pattern matching gives up; past that line, enforcement has to live in the sandbox, a profile, or a hook.

The composition: keep the sandbox (it’s excellent), keep exec’s deny-and-continue posture, and put workspace policy on the hook seam — which, now that Codex speaks the Claude Code hook contract natively, is the same seam we already stand on everywhere else. Our integration carries the same rules across Codex, Claude Code, and the rest, with every decision — including which escape-hatch flags a session ran under — in a ledger off the machine.

Frequently asked questions

What are Codex CLI's approval modes?

Three approval policies as of 0.143: untrusted (prompt for anything not known-safe), on-request (the default pairing with the workspace-write sandbox — the agent escalates when it needs more than the sandbox allows), and never. The old on-failure policy was removed in 0.143. Since 0.147 there’s also a Guardian reviewer: –approve-for-me routes escalations to a reviewer agent that checks for exfiltration, credential probing, persistence, and destruction — critical findings deny, high-risk ones escalate to the human, and failures fail closed.

Does Codex CLI have hooks?

Yes — native, on by default since 0.145, with a deliberately Claude Code-compatible schema. The config file, the events, the deny and rewrite contract, trust review, and troubleshooting are all in the Codex CLI hooks reference at /blog/codex-cli-hooks-reference. This page covers the controls around the hooks: approval policies, the Guardian reviewer, permission profiles, the sandbox, and requirements.toml.

How does the Codex sandbox work on each platform?

Three modes — read-only, workspace-write (network off inside it by default), danger-full-access — enforced by Seatbelt on macOS, bubblewrap plus seccomp on Linux (Landlock is now the fallback, not the primary), and a native Windows sandbox (low-privilege sandbox users with ACLs and firewall rules) that replaced the WSL recommendation. Subprocesses inherit the boundary.

What happens when Codex runs headless and something needs approval?

codex exec defaults to a read-only sandbox and never prompts — a blocked action fails back to the model as an error it can adapt to, effectively resolving every would-be ask to deny-and-continue. That’s the correct unattended posture. The escape hatches are explicit: –sandbox danger-full-access, or –yolo to drop both sandbox and approvals.

Just want to govern Codex? If you're here to actually see, control, and price every Codex tool call, that's one command — hooks for Bash plus an MCP connector for everything else, in a single installer:

macOS · Linux · WSL
curl -sf https://agenticcontrolplane.com/install.sh | bash
Windows · PowerShell
irm https://agenticcontrolplane.com/install.ps1 | iex

Full Codex install guide →  ·  see your first governed call →  ·  free up to 5 agents