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

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, 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.

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.


Four losses one pack can stop.

disksmkfs, dd of=/dev/disk2
root and homerm -rf ~, rm -rf /, rm -rf /usr
permissionschmod -R 777 /
the machinea fork bomb

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


Five rule types, one per thing an agent touches.

sitespastebin.com and its subdomains
commandsterraform destroy, git push to main
scriptsnpm run deploy
filesreads of ~/.ssh or .env
tool serversmcp__github__create_issue

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

productionterraform destroy, DROP TABLE, npm publish
secrets~/.aws, .env, printenv, paste sites
the repowrites outside the project
packagescurl … | sh, unknown registries

See what your agents tried.

decision logeach block, its rule and tool, no command text
seen, not ruledwhat no rule covers, with Block and Allow
testtype a command and see which rule decides it

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.

exportone policy.json that diffs cleanly in git
importa dry run first
historywho 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.


Compared

Next to the controls you may already have.

ControlWhere the check runsInstall on each machineClaude Code and Codex under one policyDecision logAsk a person first
CageThe gateway, on the request pathA base URL, set by one commandYesYes, exportable; policy changes are hash-chainedNo
Claude Code managed settings and hooksThe clientNothing extra; policy arrives by MDM, a file or the claude.ai consoleClaude Code onlyOpenTelemetry tool_decision events, with their source; you run the collectorYes
Codex requirementsThe client and its OS sandboxNothing extraCodex onlyOpenTelemetry codex.tool_decision events, once you opt inYes
CC Safety Net (MIT)A hook in each clientA hook, per clientBoth supported, a hook in each; policy shared through gitCommand decisions, on the machineNot stated
dcg (a custom license based on MIT, with an OpenAI/Anthropic rider)A hook in each clientA binary and a hook, per clientBoth supported, a hook in eachwarn and log rules record decisionsAn ask rule, "where the hook protocol supports it"
LassoClient hooks, with scanning in Lasso's cloudHooks, rolled out with managed settingsBoth namedAudit trailNot stated
ZenityHooks on the machine, and an MCP gatewayHooksBoth named, one central policyThrough hooks and OpenTelemetryNot stated
Prisma AIRSEndpoint, network and cloud, plus an AI gatewayDepends on the part you deployBoth named, one policySession timelinesAn exception request
LiteLLM tool permission guardrailA proxy you host, on the request pathA base URLYes, regex rules on tools and argumentsNot stated on the guardrail pageNo
Docker SandboxesA microVM with a network proxyThe sbx CLI and a microVMBoth named; network policy onlyNot statedNo

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 →

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.

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.