# Keep API keys out of Codex CLI

What Codex CLI's model can see, what zn-gate's hooks check in Codex before and after each step and on your prompts, what they cannot do, how to set them up and a short test with fake values.

Source: https://usezn.com/docs/integrations/codex-keys/

Codex CLI sends to its model whatever enters the conversation: the prompts you type, the files the agent reads, the output of shell commands and the results of MCP tools. An API key in any of those can reach the model. zn-gate installs hooks in Codex that check these points. This page explains what each hook does according to zn-gate's documentation, what it cannot do, and gives you a test to run yourself.

## Where a key can reach the model

zn-gate's Codex hooks look at four points in a session:

- **A prompt you type.** A secret pasted into it can be blocked before it is sent.
- **A shell command or a patch (`apply_patch`).** Reads of `.env` files with values and of credential files can be blocked.
- **The output of a tool.** It can be scrubbed before the model sees it.

Codex's own session log keeps the original output, whatever zn-gate does to what the model sees.

## What zn-gate checks in Codex

`zn hooks install codex` writes Codex's `hooks.json`. This table follows [compat.md](https://github.com/usezn/zn/blob/main/docs/compat.md) in the zn-gate repository, which lists each Codex hook event and whether it has been run against a live Codex.

| Hook event | What zn-gate does |
|---|---|
| `PreToolUse` | Checks shell commands and patches (`Bash`, `apply_patch`) before they run, and denies the call with a reason when it finds a secret, a credential file or `~/.zn`. It does not check MCP tool calls. Checked on Codex CLI 0.163.0. |
| `PostToolUse` | Scrubs the tool output: the result is replaced by its scrubbed text. Checked on Codex CLI 0.163.0. |

A third event, `UserPromptSubmit`, blocks a secret pasted into a prompt (checked on Codex CLI 0.163.0).

In `PreToolUse`, zn-gate does not answer `allow`, so your own Codex approval policy still applies.

## What zn-gate does not cover in Codex

- Codex describes its hooks as "a guardrail, not an enforcement boundary". If the zn hook cannot run, Codex reports it as failed and the call or prompt goes ahead.
- Scrubbing is lossy. Codex has no field that rewrites a tool result, so the result is replaced by zn-gate's scrubbed text and the model gets text instead of the structured result.
- Codex's own session log keeps the original output.
- A secret with no known format that is not in the vault or in a `.env` file can get through the scrubber.
- A server set on the Codex command line with `-c mcp_servers.secrets...`, or in a profile, is not visible to the hook.
- zn-gate's `PreToolUse` check covers shell commands and patches, not MCP tool calls, and zn-gate does not use Codex's other hook events.
- On Windows, the hook command was run by hand from PowerShell and from Command Prompt, not in the automated tests.

## Set it up

You need Node.js 18 or later:

```bash
npm install -g zn-gate
zn hooks install codex
```

Open Codex and review the new or changed hooks with `/hooks`. Codex runs new hooks only after you trust them there. Then run `zn-gate check` in a terminal. It should show **OK** for Codex CLI ([what the output means](https://usezn.com/docs/check/)). The full steps are on the [Codex CLI install page](https://usezn.com/docs/install/codex/).

To keep real values out of your `.env` altogether, move them into zn-gate's vault. Your `.env` then holds markers such as `__ZN_STRIPE_KEY__`:

```bash
zn unlock
zn env shadow .env
```

More in [Scrubber](https://usezn.com/docs/zn-gate/scrubber/). To undo the hooks: `zn hooks uninstall codex`.

## Test it on your own machine

This test uses fake values. Parts of it follow what the documentation says should happen and have not been run end to end by us in Codex, so check each step yourself.

1. In a new empty folder, create a `.env` file with fake values only:

   ```text
   EXAMPLE_API_KEY=sk-test-EXAMPLE-not-a-real-key
   EXAMPLE_URL=https://example.com
   ```

2. Install the hooks (`zn hooks install codex`), open Codex in that folder, trust the hooks in `/hooks`, and run `zn-gate check` in another terminal.
3. Ask Codex: "Run cat .env and tell me what it prints." According to compat.md, zn-gate's `PreToolUse` hook blocked `cat .env` on Codex CLI 0.163.0, and you should see a message from the hook instead of the values.
4. Paste into the prompt the AWS documentation example key `AKIAIOSFODNN7EXAMPLE`. If zn-gate recognizes the format, the prompt should be blocked. If it is not blocked, the format may not be one zn-gate detects.
5. Optional: run `zn unlock` and `zn env shadow .env`, open the file and check that it holds markers. Ask Codex to read it again and compare.
6. Remove the sample folder when you are done. To remove the hooks: `zn hooks uninstall codex`.

Only your own results count here. If a step behaves differently from what this page says, [tell us](https://usezn.com/contact/) and include your Codex CLI version.

## Frequently asked questions

**Can Codex's model see my API keys?** Anything the agent reads, runs or receives can reach the model: files, shell output, MCP results and prompts. zn-gate's hooks check those points, with the limits above.

**Does zn-gate stop Codex from reading `.env`?** Its hooks block reads of `.env` files with values in shell commands and patches. Codex calls hooks a guardrail, not an enforcement boundary.

**Why is the scrubbed output plain text?** Codex has no field that rewrites a tool result, so zn-gate replaces the whole result with its scrubbed text.

**How do I undo it?** `zn hooks uninstall codex`.

## Related pages

- [Keep API keys out of OpenCode](https://usezn.com/docs/integrations/opencode-keys/)
- [I pasted an API key into my coding agent. What now?](https://usezn.com/docs/integrations/pasted-key/)

## Sources

- zn-gate, per-agent compatibility and Codex hook events: [compat.md](https://github.com/usezn/zn/blob/main/docs/compat.md)
- zn-gate, Codex CLI install page: [/docs/install/codex/](https://usezn.com/docs/install/codex/)
- Codex CLI, hooks documentation: <https://learn.chatgpt.com/docs/hooks>
