Claude Code vs Codex CLI: Permission Models Compared
Claude Code and OpenAI’s Codex CLI both ship permission systems, both ship hooks, and both get run unattended by people who read neither system’s fine print. The models look similar from a distance — PreToolUse, PostToolUse, JSON in, JSON out — and behave differently in exactly the places that matter for governance. This is the side-by-side, with sources.
The comparison
| Dimension | Claude Code | Codex CLI |
|---|---|---|
| Hook config | ~/.claude/settings.json |
~/.codex/hooks.json (user) merged with <repo>/.codex/hooks.json |
| Hook events | PreToolUse, PostToolUse |
PreToolUse, PostToolUse |
| Enabled by default | Yes | No — requires [features].codex_hooks = true; silent no-op without it |
| Tool coverage | All native tools: Bash, Edit, Read, Write, MCP |
shell (Bash) only, by design — apply_patch, file tools, and MCP calls never fire hooks |
| Operational decisions | allow / deny / ask, plus input rewriting |
deny only — allow, ask, updatedInput are parsed and rejected (output_parser.rs) |
| Output-side control | PostToolUse can redact/rewrite tool output |
Observe-only (updatedMCPToolOutput rejected) |
| Unattended mode | --dangerously-skip-permissions — disables hooks entirely |
codex exec --full-auto — keeps hooks running, sandboxes writes, blocks network by default |
| Sandbox | OS-level sandboxing on supported platforms | workspace-write sandbox + opt-in network (sandbox_workspace_write.network_access=true) |
| Hook timeout | ~4s default | ~30s — headroom for remote policy lookups |
| Approval prompt | Per-action ask with allow-once/always | Per-step Y/N; suppressed (not disabled) in --full-auto |
Both are real permission systems. Neither is a complete one, and they’re incomplete in opposite ways.
Where Claude Code is stronger: coverage and decisions
Claude Code’s hook surface sees everything the agent does natively — shell, file edits, reads, writes, MCP tool calls — and its hooks can make every decision worth making: allow, deny, escalate to a human (ask), or rewrite the input before it runs. If your governance model needs “redact the secret from that tool output before the model sees it,” Claude Code’s PostToolUse can do it and Codex’s cannot.
The catch sits at the flag people actually use for automation. --dangerously-skip-permissions doesn’t just suppress the approval prompts — it disables hooks. The moment a Claude Code deployment goes unattended with that flag, its entire interception surface is gone, which is precisely the moment you wanted it most. (Details and safer patterns: our dangerously-skip-permissions breakdown.)
Where Codex is stronger: unattended behavior
Codex made the opposite call: --full-auto removes the human, not the policy. Hooks keep firing, filesystem writes stay sandboxed to the workspace, and network is off unless you grant it. For CI agents, scheduled jobs, and headless deployments, that’s the correct architecture — and it’s the single strongest governance property in either CLI.
The catch is reach. Hooks intercept the shell tool only, and the only decision Codex acts on is deny with a reason. No ask escalation, no input rewriting, no coverage of apply_patch or MCP-routed tools. A Codex hook is a tripwire, not a control plane. (Full reference, including the flag that silently no-ops everything: Codex CLI hooks reference.)
The shared gap
Both models decide per call with local context: this command, this session, this machine. Neither can answer the questions that make unattended operation actually safe:
- Identity — which human is accountable for this agent’s actions, and does the record survive the machine?
- Cumulative behavior — the 400th
curlin an hour is a different event than the 1st; per-call rules can’t see the series. - Spend — neither CLI meters cost at decision time; a retry loop at 3am is invisible until the invoice.
- Fleet policy — a deny-list edited per machine, per developer, drifts. There’s no “this rule, everywhere, now.”
That’s the layer ACP adds to both — the same server-side policy, audit trail, and spend metering behind Claude Code’s full-coverage hooks and Codex’s deny-only ones, with each harness’s mapping documented honestly (Codex needs an MCP-connector supplement for the tools its hooks can’t see). One install covers either: Ways to set up ACP.
Choosing, if you must
- Interactive daily driving: either — both approval UIs are fine with a human present.
- Unattended with governance requirements: Codex’s
--full-autois architecturally right; pair it with server-side policy to compensate for deny-only/Bash-only reach. Unattended Claude Code should never mean--dangerously-skip-permissions; keep hooks alive and add the wrapper-level controls. - Output redaction / PII handling in the loop: Claude Code — it’s the only one with an operational output-side hook.
- Mixed fleet: stop choosing per-harness semantics; put the policy at a layer both route through, and let the harness-level systems be the local reflexes they’re good at.
Frequently asked questions
What's the main difference between Claude Code and Codex CLI permissions?
Coverage versus decisions. Claude Code’s hooks cover every native tool (Bash, Edit, Read, Write, MCP) and support allow / deny / ask plus input rewriting. Codex’s hooks cover the shell tool only and act on exactly one decision — deny. Codex wins on one axis that matters for unattended use: its –full-auto mode keeps hooks running, where Claude Code’s –dangerously-skip-permissions disables them entirely.
Do Claude Code hooks work with --dangerously-skip-permissions?
No. The flag suppresses the permission system including hooks — an agent run this way has no enforcement layer at all. If you need unattended operation with governance intact, that flag is the wrong tool; route governance through a layer the flag can’t disable, or use a harness whose unattended mode keeps hooks alive (Codex’s –full-auto does).
Do Codex hooks work in --full-auto mode?
Yes — this is Codex’s standout permission property. codex exec –full-auto suppresses the per-step approval prompt but keeps PreToolUse and PostToolUse firing, sandboxes writes to the workspace, and blocks network by default. Unattended Codex deployments retain policy enforcement; only the human confirmation is removed.
Can Codex hooks block a tool call the way Claude Code's can?
For Bash, yes: emit permissionDecision “deny” with a reason. But that’s the only operational decision — Codex’s parser rejects allow, ask, and updatedInput, and PreToolUse fires for the shell tool only, so apply_patch, file edits, and MCP calls never reach a hook. Claude Code hooks can allow, deny, ask, and rewrite input across all tools.
Which is safer to run unattended?
Neither is safe on configuration alone; they fail differently. Claude Code has the broader interception surface but loses it exactly when people go unattended (the skip-permissions flag). Codex keeps its hooks in –full-auto but they’re deny-only and Bash-only. In both cases, unattended safety comes from an external policy layer at a boundary the harness can’t switch off — plus a spend meter, because the 3am failure mode is a bill.
Where to read more
- Codex CLI hooks reference — the full Codex hook surface, with source cites
- Claude Code’s dangerously-skip-permissions — what the flag actually disables
- Which Claude Code tools to deny out of the box — posture, tool by tool
- The Tool Surface Index — Claude Code’s 76 declared tools next to Codex’s 17, from live traffic
- Ways to set up ACP — both planes, per stack, ending with your coverage state