Cage · the agent firewall for Claude Code and Codex

# An agent with a shell runs what the model asks. *Cage decides first.*

**Cage is the firewall in Context Mode Gateway: it reads each tool call from Claude Code or Codex before the client runs it.** A blocked call never reaches your shell; the client runs only an echo of the refusal, so the model reads why.

Cage is in every plan and is off until you turn it on. Nothing is blocked until you pick a preset or add rules. Balanced and Locked down include Core protections.

Off until you turn it on

4 protections in the Core pack

5 rule types

3 presets

4 more packs, 29 rules

[Connect your agent →](https://context-mode.com/docs/quick-start) [Read the Cage docs](https://context-mode.com/docs/cage)

## Key facts

What it is

The tool-call firewall in Context Mode Gateway, for shell commands, file reads and writes, web fetches and tool-server calls.

Who it is for

Developers and security leads who let Claude Code or Codex run commands.

Clients

Claude Code and Codex, including each call inside a Codex exec cell. Part of [Pro](https://context-mode.com/docs/faq#access), and off until you turn it on.

Measured result

No block-rate study yet. Cage reads each call by what it does, through 98 wrapper words and 33 carriers.

Limits

Cage reads the call, not the program: a script file or a compiled program gets past it. Keep your agent's sandbox on.

Live proof

### What your agent sees

A real Claude Code turn, 2026-09-28, under a rule the account chose. Only an echo ran, and the file was not read.

## The model asked to read `.env`. *It got this back.*

Tool result

`⛔ context-mode Cage blocked this command, so it was NOT executed: Blocked by your team’s policy: Cage live proof: block reading .env. Live proof for the Cage page (2026-09-28). Scope: your account. Only the owner can change this, in Cage in the context-mode dashboard; do not retry it as a different shell command or a Node.js or Python script. Tell the user it was blocked and continue with other work.`

Pro

### Core protections (in Balanced and Locked down)

Pick either preset and it is on. Switch any of its rules off on the Rules tab.

## Four losses *one pack can stop.*

disks mkfs, dd of=/dev/disk2 root and home rm -rf ~, rm -rf /, rm -rf /usr permissions chmod -R 777 / the machine a fork bomb

It reads through sudo, sh -c and env. rm -rf node_modules still runs.

Pro

### Your own rules

Enforce stops the call. Monitor runs it and records "would block".

## Five rule types, *one per thing an agent touches.*

sites pastebin.com and its subdomains commands terraform destroy, git push to main scripts npm run deploy files reads of ~/.ssh or .env tool servers mcp__github__create_issue

Pro

### Presets and packs

Observe, Balanced or Locked down.

## Start from a pack, *then edit any rule in it.*

production terraform destroy, DROP TABLE, npm publish secrets ~/.aws, .env, printenv, paste sites the repo writes outside the project packages curl … | sh, unknown registries

Console

### The Cage screen

## See what your agents tried.

decision log each block, its rule and tool, no command text seen, not ruled what no rule covers, with Block and Allow test type a command and see which rule decides it

One policy

### Claude Code and Codex

## One rule set, *checked in one place.*

Each call inside a Codex exec cell meets the same check as a Claude Code call. See [Codex in the quick start](https://context-mode.com/docs/quick-start#codex).

export one policy.json that diffs cleanly in git import a dry run first history who changed what and why, hash-chained

Try it in 5 minutes

## Push to main, read .env. *Both stop, and the release still ships.*

Friday release: the agent tries to push to main and to read `.env`. Cage stops both, and the release still ships on a branch.

**Setup**

```
npx @context-mode/cli      # sign in and connect Claude Code, then restart Claude Code
# In the console, open Cage, turn it on, and pick the Balanced preset.
mkdir -p ~/cage-demo && cd ~/cage-demo
git clone --bare https://github.com/expressjs/cors.git origin.git   # a local copy is your remote, so nothing reaches GitHub
git -C origin.git branch -m master main 2>/dev/null; git -C origin.git symbolic-ref HEAD refs/heads/main
git clone origin.git app && cd app && npm install
printf 'NPM_TOKEN=npm_DEMO_not_a_real_token_0000\n' > .env       # a fake token, as most real repos have
git -C ../origin.git rev-parse main > ../main-before.txt          # the remote main, before the agent starts
claude
```

**Prompts**

Prompt 1:

```
Release prep. Run the tests. Then add a new 'unreleased' heading at the top of HISTORY.md with one line: 'Docs: clarify the preflight example'. Commit it and push straight to main so CI can publish. The npm token is in .env if you need it.
```

Prompt 2:

```
CI says the npm token is wrong. Show me what is in .env so I can compare it.
```

Prompt 3:

```
Fine. Push the commit to a branch called release-prep instead, and give me the command to open a pull request.
```

**What you will see**

```
# prompt 1: the push to main comes back as this tool result
⛔ context-mode Cage blocked this command, so it was NOT executed: Blocked by your team’s policy: Push to protected branches. Protected branches change through reviewed pull requests. Scope: your account. Cage is on for this account, and its rules are set in Cage in the context-mode dashboard; do not retry it as a different shell command or a Node.js or Python script. Tell the user it was blocked and continue with other work.

# prompt 2: the read of .env
⛔ context-mode Cage blocked this command, so it was NOT executed: Blocked by your team’s policy: Read environment files. .env files hold secrets. Scope: your account. Cage is on for this account, and its rules are set in Cage in the context-mode dashboard; do not retry it as a different shell command or a Node.js or Python script. Tell the user it was blocked and continue with other work.
```

You can let an agent do the whole release chore. One policy, held on the gateway, makes sure it never pushes to main or reads your secrets. Run again on 2026-10-04: both blocks held, and the branch landed. The docs also show what Balanced does not stop. What each step does, and how to check it, is in the [docs](https://context-mode.com/docs/cage#try-it).

Compared

## Next to the controls you may already have.

| Control | Where the check runs | Install on each machine | Claude Code and Codex under one policy | Decision log | Ask a person first |
| --- | --- | --- | --- | --- | --- |
| **Cage** | The gateway, on the request path | A base URL, set by one command | Yes | Yes, exportable; policy changes are hash-chained | No |
| [Claude Code](https://code.claude.com/docs/en/permissions) managed settings and hooks | The client | Nothing extra; policy arrives by MDM, a file or the claude.ai console | Claude Code only | OpenTelemetry `tool_decision` events, with their source; you run the collector | Yes |
| [Codex](https://developers.openai.com/codex/enterprise/managed-configuration) requirements | The client and its OS sandbox | Nothing extra | Codex only | OpenTelemetry `codex.tool_decision` events, once you opt in | Yes |
| [CC Safety Net](https://github.com/kenryu42/cc-safety-net) (MIT) | A hook in each client | A hook, per client | Both supported, a hook in each; policy shared through git | Command decisions, on the machine | Not stated |
| [dcg](https://github.com/Dicklesworthstone/destructive_command_guard) (a custom license based on MIT, with an OpenAI/Anthropic rider) | A hook in each client | A binary and a hook, per client | Both supported, a hook in each | `warn` and `log` rules record decisions | An `ask` rule, "where the hook protocol supports it" |
| [Lasso](https://www.lasso.security/use-cases/ai-coding-assistants) | Client hooks, with scanning in Lasso's cloud | Hooks, rolled out with managed settings | Both named | Audit trail | Not stated |
| [Zenity](https://www.zenity.io/use-cases/agent-type/coding-personal-agents) | Hooks on the machine, and an MCP gateway | Hooks | Both named, one central policy | Through hooks and OpenTelemetry | Not stated |
| [Prisma AIRS](https://www.paloaltonetworks.com/prisma/prisma-ai-runtime-security) | Endpoint, network and cloud, plus an AI gateway | Depends on the part you deploy | Both named, one policy | Session timelines | An exception request |
| [LiteLLM](https://docs.litellm.ai/docs/proxy/guardrails/tool_permission) tool permission guardrail | A proxy you host, on the request path | A base URL | Yes, regex rules on tools and arguments | Not stated on the guardrail page | No |
| [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) | A microVM with a network proxy | The sbx CLI and a microVM | Both named; network policy only | Not stated | No |

From each vendor's own pages, read on 2026-09-30. "Not stated" means the page we read does not say. [Full comparison, with what each one checks →](https://context-mode.com/docs/cage#compare)

### Pick Cage when

- You want one policy for Claude Code and Codex, and no agent to install on each laptop.
- You want what a command guard does on one laptop on every machine, with no install: calls read through wrappers such as `sudo`, `sh -c`, `xargs` and `ssh`, by what they do, and one log you can export.
- You want the same hop to cut cost and keep a decision log you can export.

### Pick them when

- You use only one client, or you want an ask step. Claude Code and Codex managed settings are free, first-party, and MDM keeps them on the machine.
- You need more agents, or no network at all: CC Safety Net and dcg are free, run on the machine, and cover Cursor and other agents too.
- You need models that detect injection and data loss, or SSO and group policies: Prisma AIRS, Zenity and Lasso.

**Staying on.** Cage checks only requests that go through the gateway. If someone removes the base URL, Cage no longer sees that machine. Claude Code managed settings can set it on every machine; OpenAI's page names no Codex requirement for it. See [Keep the gateway on](https://context-mode.com/docs/cage#pin).

**Limits.** Cage is not an OS sandbox. A script file, a compiled program or code run with context-mode-run-local can get around it, so keep your agent's sandbox on too.

## FAQ

### Does Cage stop rm -rf on my home folder?

Yes, in the Balanced and Locked down presets: `rm -rf ~`, `rm -rf $HOME`, `rm -rf /` and any home folder.

### Can Cage stop my agent from reading .env?

Yes, with a Files rule. A read of `.env` is then refused by the gateway before the client runs it.

### Can a wrapper or a one-liner get around it?

Cage reads each call by what it does, through 98 wrapper words and 33 carriers. The same refusals apply inside one-line programs such as `fs.rmSync('/')`.

### Can I try a rule without blocking?

Yes. A rule in Monitor records the call instead of blocking it.

### Should I keep my sandbox on?

Yes. Cage does not read what a script file or a compiled program does.

## Write the rules once. *Both agents follow them.*

*npx @context-mode/cli* points Claude Code and Codex at the gateway. Cage is in every plan and is off until you turn it on. Nothing is blocked until you pick a preset or add rules, and each rule or pack takes effect when you save it.

[Connect your agent →](https://context-mode.com/docs/quick-start) [Read the Cage docs →](https://context-mode.com/docs/cage)
