# Codex

> Connect OpenAI's Codex to Golem through its hooks and MCP settings, approve the hooks once, and lock its riskiest settings through requirements.toml.

Codex is connected when you [install Golem](/install), or when the Golem agent finds Codex installed later. Golem registers itself as Codex's hook command, so Codex's tool calls are checked against your rules before they run and signed into the record. There is one step only you can do: Codex runs a new hook only after you approve it.

## What Golem adds

| File | What Golem adds |
|---|---|
| `~/.codex/hooks.json` | Golem's hook on `SessionStart`, `UserPromptSubmit`, `PreToolUse` and `PostToolUse`. Each runs `golem codex-hook` with the event's name. |
| `~/.codex/config.toml` | Golem's MCP servers, `golem-witness` and `golem-context`, in a marked block at the end of the file |
| `~/.codex/skills` | The `golem-fleet` and `safely` skills, and `sandbox` and `golem-sandbox` on a Mac with the sandbox |

Golem's hooks sit beside any you already have. In `config.toml`, Golem writes only between its own markers and leaves the rest of the file as it was, comments included. If you already declare a server under one of Golem's names, yours is kept. Golem's tools that only read, such as `list_agents` and the record's search tools, are set to run without asking; anything that writes or acts, such as `send_message` or the sandbox, still asks.

If your shell sets `CODEX_HOME`, run `golem setup-client` once from that shell. The Golem agent runs as a background service and cannot see your shell's environment, so this is how it learns the folder. It then keeps both that folder and `~/.codex` connected, since Codex started from the Dock reads `~/.codex`.

## Approve the hooks

Codex skips hooks nobody has approved. After installing, open Codex and accept Golem's hooks when it asks you to review them. Until you do, nothing from Codex is checked or recorded, and messages from other agents do not reach it. If you use more than one Codex folder, each needs its own approval.

`golem doctor` names any hook Codex has not approved.

## What a block looks like

A call a rule blocks is refused before it runs. Codex hands the reason to its model, which passes it on to you:

```text
blocked by Golem policy (rule "no-force-push-to-main", decision gd_3f9a1c07b2e4d815). Trying again won't change this; if you need it, ask your security team and quote the decision id.
```

To ask your security team for an exception, run `golem exception <decision-id> --reason "why"`. See [Block, hold and contain](/response).

## What a hold looks like

Codex's hooks have no way to ask you a question, so a rule set to Ask behaves differently here:

- **The person at the keyboard decides:** the call is refused, with a message that the agent could not ask you here and the decision id to quote. A hold is never turned into an allow.
- **Golem's reviewer agent decides:** the hook holds the call for up to 35 seconds while the reviewer decides, then lets it through or refuses it. If no decision has come by then, Codex is told to wait and retry the same call.
- **Your team decides:** the call is refused, with a message that your security team holds it.

If you need a person to approve calls as they happen, use a client that can ask, such as [Claude Code](/agents/claude-code).

A rule set to Warn lets the call run and records the match. `/safely` works in Codex too, as a skill. See [Safely](/response#safely).

## What is captured

| What | From |
|---|---|
| Every tool call before it runs, and its permission mode | `PreToolUse` |
| Every tool call's result, checked for prompt injection when that check is on | `PostToolUse` |

Sessions are recorded as agent `codex`, under Codex's own session id. The full content goes to your storage; the record holds its hash and signature. See [What Golem captures](/coverage#what-golem-captures).

`SessionStart` and `UserPromptSubmit` are how `/safely`, what other agents are doing, and messages from them reach Codex. Your prompts and Codex's replies are not recorded.

## Lock the riskiest settings

The Golem agent reads `config.toml`, and the `.codex/config.toml` of each repository Codex works in, for the settings that matter most:

| Setting | Shown as |
|---|---|
| `sandbox_mode = "danger-full-access"`, at the top level or in a profile | No sandbox (full access); alerts |
| A session run with `--yolo` or `--dangerously-bypass-approvals-and-sandbox` | Ran with approvals and sandbox off; alerts |
| `approval_policy = "never"` | Never asks; listed only |
| `network_access = true` in `[sandbox_workspace_write]` | Sandbox reaches the network; listed only |

They appear in the console under **Security Inventory → Agent settings**. Golem never changes them. The lock is Codex's own: `requirements.toml` lets an admin limit `allowed_sandbox_modes` and `allowed_approval_policies` for every user on a machine, and you deploy it through your MDM. See [The posture report](/fleet#the-posture-report).

A rule can also act on a session while it runs: Codex reports its permission mode on every call, and the built-in rule **Shell command with permission prompts off** reads it. In Codex, Ask on that rule means a refusal, as above.

## Check it is working

1. Restart Codex and approve Golem's hooks when it asks.
2. Run `golem doctor`. The Codex hook check should say Codex has approved all of Golem's hooks.
3. Ask Codex to run a harmless command, such as `git status`. The session appears in the console under **Conversations**.

## Limits

- **The hook fails open.** If the Golem agent is down or does not answer in time, Codex carries on, and nothing is checked or recorded until it is back.
- **No asking.** A hold for a person is a refusal in Codex.
- **Unapproved hooks do nothing,** silently. Check with `golem doctor` after every new Codex folder.
- **The shell jail does not cover Codex.** Its commands are checked and recorded by the hooks, and run in Codex's own sandbox if you keep it on, not in [Golem's shell jail](/shield#the-shell-jail).

See also [Rules and CEL](/rules), [Block, hold and contain](/response), [Coverage](/coverage), [Limits](/limits) and [Install Golem](/install).
