Skip to content
Agentic Control Plane

Govern OpenAI Codex CLI with Agentic Control Plane

See, control, and price every tool call Codex makes — the shell commands, the file edits, the model calls — from one dashboard. One command, no code changes, first governed call in about 30 seconds.

TL;DR

curl -sf https://agenticcontrolplane.com/install.sh | bash

MIT-licensed and auditable — read it before you run it.

Three things you get the moment it's running — click any to see it full-size:

ACP tool-surface control table: every tool the agent can call, Allow/Deny per tool
ControlEvery tool Codex can call, one row each — Allow / Deny per tool. Deny-by-default on rm -rf, force-push, and the rest. Enforced at the call, outside the model.
ACP cost-per-run distribution for one agent across many runs, log scale
PriceRoute model calls through the proxy and every one is metered — each run split loop-vs-leaf and plotted across runs, so you see which step is the bill and which runs blow the budget.
ACP session trace: per-call timeline of one agent run with cost and decision
AuditEvery tool + model call in a run, in order — what ran, what it returned, the policy decision, and what it cost. Exportable.

See your first governed call →Free for individuals · full install below

OpenAI Codex CLI ships a Claude-style hook system that’s gated behind a feature flag and currently only intercepts the Bash tool. To govern Codex end-to-end you want both the hook (Path 1) and the MCP connector (Path 2) — hook handles Bash, MCP covers Read, Edit, Write, web fetch, and any tool you’ve configured via [mcp_servers.*] in config.toml.

The installer detects Codex (command -v codex or ~/.codex/ exists), then wires three layers in one command:

  1. Hooks — Enables [features].codex_hooks = true in ~/.codex/config.toml, writes ~/.codex/hooks.json with PreToolUse + PostToolUse entries pointing at ~/.acp/govern.mjs. Governs every Bash call Codex makes.
  2. MCP connector — Adds [mcp_servers.acp] to ~/.codex/config.toml so non-Bash tools (Read, Edit, Write, web fetch, custom MCP servers) flow through the ACP MCP endpoint.
  3. AGENTS.md directive — Writes an ACP-governance section to ~/.codex/AGENTS.md instructing Codex to call acp_check before non-Bash tool calls (instruction-layer enforcement for the gap between what hooks cover and what policy needs).

The MCP block uses a shell substitution (sh -c ... Bearer $(cat ~/.acp/credentials)) so the Authorization header reads your credentials file every time Codex starts the server. No install-time API key needed, and credential rotation just means overwriting the file.

Important: Codex hooks are off by default

OpenAI’s Codex hook engine is marked Stage::UnderDevelopment in the Codex source. It works — full Claude-style PreToolUse and PostToolUse — but you have to opt in by adding to ~/.codex/config.toml:

[features]
codex_hooks = true

The ACP installer will do this for you and prompt before writing, so you know what’s changing. Without the flag, hooks are silently ignored — no error, no log line, just no governance. If you’ve enabled hooks and they’re not firing, this flag is the first thing to check.

How it works

ACP installs at three layers, designed to compose:

  1. Hook layer (Path 1) — ~/.codex/hooks.json registers PreToolUse and PostToolUse events pointing at ~/.acp/govern.mjs. Same script as Claude Code; same permissionDecision: "deny" semantics.
  2. MCP connector (Path 2) — [mcp_servers.acp] in ~/.codex/config.toml points Codex at mcp.agenticcontrolplane.com/mcp. Codex routes any tool call configured to use that MCP server through ACP.
  3. Audit layer — every Codex tool call (whether intercepted by hook or MCP) lands in your ACP activity log with client.name: "codex", the turn_id, the subagent context (Codex’s SessionSource is finer-grained than Claude Code’s tier), and the full delegation provenance.

What gets installed and where

Path Purpose
~/.acp/govern.mjs Hook script — shared with Claude Code/Cursor installs
~/.acp/credentials Bearer token from browser OAuth (written after auth)
~/.codex/config.toml Adds [features].codex_hooks = true and [mcp_servers.acp] block
~/.codex/hooks.json Adds PreToolUse + PostToolUse entries registering node $HOME/.acp/govern.mjs

The installer is idempotent. Running it again on a machine where Codex already has the entries will skip them. Running on a machine without Codex installed is a no-op for the Codex section.

How MCP coverage works (no API-key-at-install-time needed)

Codex’s PreToolUse hook only intercepts the Bash tool. Non-Bash tools (Read, Edit, Write, web fetch, etc.) are covered by the MCP connector the installer also wires.

The [mcp_servers.acp] block the installer writes looks like:

[mcp_servers.acp]
command = "sh"
args = ["-c", 'exec npx -y mcp-remote https://mcp.agenticcontrolplane.com/mcp --header "Authorization: Bearer $(cat ~/.acp/credentials)"']

The sh -c wrapper is load-bearing: it evaluates $(cat ~/.acp/credentials) every time Codex launches the MCP server, which means:

  • No API key is required at install time (hooks install → browser auth → credentials saved → first Codex restart picks it up)
  • Credential rotation is a one-step operation — overwrite ~/.acp/credentials and restart Codex
  • The literal API key never appears in config.toml, which is safer for dotfile checkins

Limitations — read this before relying on Codex hooks alone

This is the section that matters most. Codex hooks are powerful but partial.

PreToolUse only intercepts the Bash tool

Per OpenAI’s Codex hooks documentation: “Currently PreToolUse only supports Bash tool interception.” Read, Write, Edit, Apply Patch, web fetch, and MCP tool calls do not fire PreToolUse.

This is why ACP installs both the hook and the MCP connector. The hook handles Bash (where most of the destructive-action risk lives — rm -rf, gh repo delete, psql DROP TABLE). The MCP connector handles everything routed through MCP servers, which is where Codex’s file edits and structured tool calls increasingly live.

If you don’t have any tools wired through MCP and you only care about governing Bash, the hook alone is enough.

Tool input/output mutation is not yet supported

Codex’s hook engine parses but rejects updatedInput (PreToolUse) and updatedMCPToolOutput (PostToolUse). Specifically:

You can observe and deny today; you cannot redact or rewrite. The MCP connector path supports both — another reason to wire both layers.

Only permissionDecision: "deny" is operational

PreToolUse parses but rejects "allow" and "ask" decisions. The only response that does anything is deny with a permissionDecisionReason. Effectively the only output shape your hook should emit.

type: "command" is the only working handler

Codex’s schema also defines prompt and agent handler types but they parse-and-warn-skip. Use command exclusively.

Hooks merge across config layers without namespacing

~/.codex/hooks.json and <repo>/.codex/hooks.json both load. There’s no marker to identify ACP-owned entries. The installer uses a stable statusMessage: "ACP policy check" string so it can find and idempotently update its own entries on re-install. If you hand-edit hooks, leave that statusMessage alone.

Schema is evolving fast

Codex ships multiple releases per day (75K stars, 410 contributors). The wire types use deny_unknown_fields so additive changes can break strict parsers. ACP pins to tested Codex versions and updates the adapter when fields land. If you’re on bleeding-edge Codex (alpha releases), things may shift under you.

What you’ll see in the dashboard

Once Codex is governed, cloud.agenticcontrolplane.com/agents shows a codex row with activity broken down by Codex’s session source — cli, vscode, exec, appServer, subAgent (with the SubAgentSource subtype: Review, ThreadSpawn, MemoryConsolidation, Compact). Codex exposes finer-grained subagent metadata than Claude Code does — including parent_thread_id and depth for ThreadSpawn — which gives you better A2A signal automatically.

Setting up policy

The same three-axis model applies (Tool / Agent / User policies). Specifically for Codex:

  • Tool policies — restrict the Bash subcommands Codex can run (Bash.git, Bash.npm, Bash.docker — already classified server-side).
  • Agent policies — limit which session sources can run high-risk operations. subAgent.MemoryConsolidation should probably never delete files, for example.
  • User policies — gate Codex enterprise installs to specific identities.

Troubleshooting

Hook isn’t firing. Check ~/.codex/config.toml has [features].codex_hooks = true. The flag is off by default and hooks are silent without it.

Hook fires for Bash but not for Read/Edit. Expected — see Limitations. Use the MCP connector for non-Bash tools.

Codex says “ACP policy check timed out”. Default hook timeout is 30 seconds in hooks.json. A timed-out check follows your fail mode — allowed-but-flagged-ungoverned by default, denied if you’ve opted into fail-closed (echo closed > ~/.acp/failmode).

updatedInput rejection error in Codex logs. Don’t return updatedInput from PreToolUse — only permissionDecision: "deny" with a reason. Codex’s parser strict-rejects unsupported fields.

Multiple hook layers conflicting. Both user (~/.codex/) and repo (<repo>/.codex/) hooks load and merge. Repo-level entries override user-level for matching tools. Inspect the merged config with codex --debug-hooks (alpha command).

Add the cost X-ray

The MCP coverage above governs and audits tool calls — it doesn’t see the model’s token usage, so it can’t show cost. To meter spend, prompt-cache hit rate, and the loop-vs-leaf cost X-ray, route Codex’s model calls through the ACP proxy: point Codex’s model provider base_url at https://api.agenticcontrolplane.com/openai/v1 and authenticate with your ACP key (gsk_...). Same responses, now metered — and the proxy governs the tool-use blocks the model emits as a second layer.

Full walkthrough: Turn on Cost X-Ray.

Verify the installer

The installer is open source — read every line before you run it.

Review before you pipe to bash:
· Source code: github.com/agentic-control-plane/acp-install (MIT, auditable)
· SHA-256: /install.sh.sha256 (compare with GitHub to verify you got the published version)
· Dry read: curl -sf https://agenticcontrolplane.com/install.sh | less — see every line before running
· License: MIT · Issues: github
  • Claude Code — same hook pattern, broader tool coverage (PreToolUse fires for all tools, not just Bash)
  • Cursor — different IDE, hook-based governance
  • OpenAI Agents SDK — for building OpenAI-model-backed agents with full A2A delegation chains
  • Agent-to-Agent governance — how delegation chains carry identity through Codex’s SubAgentSource hops