Cage docs: rules for commands, sites, files and tool servers

Cage is the firewall in the Context Mode gateway. It reads each tool call from Claude Code and Codex before the client runs it, and answers a blocked call with a refusal. This page lists every feature and every limit. For the short version, see Cage.

Key facts

What it is
The tool-call firewall in Context Mode Gateway. It checks shell commands, file reads and writes, web fetches and tool-server calls by what they do, across 22 capabilities.
Who it is for
Developers and security leads who let Claude Code or Codex run commands.
Clients
Claude Code and Codex are enforced, including each call inside a Codex exec cell. Other agents are recorded, not enforced. Part of Pro.
Measured result
No block-rate study yet. A command hidden behind one of 98 wrapper words or 33 carriers meets the same rule as the bare command.
Limits
Cage reads the call, not the program: a script file, a compiled program or a path built at run time gets past it. Keep your agent's sandbox on.

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.

Overview

Cage is off until you turn it on. Turning it on alone blocks nothing, and no preset is picked for you: you choose what it blocks.

All rules decide on the gateway. When a call is blocked, the client runs an echo of the refusal instead of the call, so the model reads why and the command never reaches your terminal. Every block is written to the decision log.

Core protections (in Balanced and Locked down)

Core protections blocks nothing until you pick Balanced or Locked down. Once on, it matches what a call does, not its exact text. It reads through wrappers: sudo, sh -c, env X=1, timeout, nice, noglob, eval with a literal string, and about 130 others (98 wrapper words plus 33 carriers such as xargs, find -exec, ssh, docker exec and npx).

ProtectionBlockedStill runs
Wipe or format a diskdd of=/dev/disk2, mkfs.ext4 /dev/sda1, diskutil eraseDisk, shred /dev/sdadd if=a of=b.img, diskutil list, ls > /dev/null 2>&1
Delete the root or home folderrm -rf /, rm -rf ~, rm -rf $HOME, rm -rf /Users/you, rm -rf /*, rm -rf ~/.*, a folder right under / such as rm -rf /usr, /etc or /tmp, rm -rf /usr/*, cd /usr && rm -rf *, any home folder such as rm -rf /Users/alice, /home/alice/* or /root, cd ~ && rm -rf *, find / -delete, echo / | xargs rm -rf, T=/; rm -rf $T, T=~; rm -rf "$T", rm -rf ${X:-/}, cmd=rm; $cmd -rf /usrrm ~/notes.txt, rm -rf node_modules, rm -rf /tmp/build, rm -rf /tmp/*, rm -rf /etc/foo, rm -rf /Users/alice/proj/dist, T=build; rm -rf $T, T=$(mktemp -d); rm -rf "$T"
Open permissions on the whole machinechmod -R 777 /, chmod 755 /, chown -R me ~, chmod 777 ~, chmod 600 ~, chmod -R 700 ~, chmod 777 /Users/alicechmod +x ~/bin/x, chmod -R g+w ~/shared, chmod 700 ~, chmod 755 ~, chmod go-w ~
Make the machine unusablea fork bomb such as :(){ :|:& };:shutdown, killall

The same refusals apply inside one-line programs (fs.rmSync('/'), shutil.rmtree(os.path.expanduser('~'))), in a Codex exec cell, and in a Codex patch that deletes /.

Core protections does not block ordinary work: installs, force pushes, curl … | sh and network calls all run. The other packs cover those.

Each Core protections rule has its own switch on the Rules tab. Switching to Observe keeps the rules that are on.

What Core protections does not catch

Core protections reads the call text before it runs. It does not run code and does not look at the disk. So it does not catch:

It also covers only the root folder, the folders right under it and home folders. A folder two or more levels down, such as rm -rf /usr/local, is not a Core protections block; your own rules can cover it.

Core protections never refuses a call only because it could not read it. Treat it as a guard against accidents and runaway agents. For a hard boundary, also run the agent in the Claude Code sandbox or Codex workspace-write.

Rule types

A rule has one type. Its match is a list of conditions, any, and a list of carve-outs, except. It matches when any condition matches and no carve-out does. There are no regular expressions and no wildcards: a wildcard is refused with a hint.

Sites

hostexact host, such as pastebin.com
subdomainsthe host and every subdomain; evilgithub.com never matches github.com
cidran IPv4 or IPv6 range, matched against IP addresses written in the call
portoptional; absent means any port

Cage finds hosts in shell commands (with or without https://, git remotes, nc, ssh, openssl, /dev/tcp), one-line programs, web fetches, tool-server inputs and nested URLs: curl https://r.jina.ai/https://pastebin.com/x is refused on the inner host. A search query is not a destination.

Other sites. By default other sites are allowed. Set it to block and every host a call names must match an allow entry. localhost is exempt. A host built at run time, or a one-line program that opens its own sockets, is then refused. Probe under Locked down: WebFetch https://example.com answered "Only approved sites are allowed, and example.com is not on the list".

Commands

Each condition is one of three kinds.

program wordsprogram, subcommand, flags_any, flags_all, flag_values (equals, starts_with, contains, host_not_in), env_values, args_any, paths, and for git push push_to and push_force. Example: terraform destroy.
capabilityone of 22 capabilities, optionally limited to paths. Example: cloud.mutate catches aws s3 rm and terraform apply.
shapedownload_run (curl or wget output handed to a shell, piped or through a file) or env_dump (env, printenv, export -p, a bare set, /proc/<pid>/environ)

Conditions can name settings: $PRODUCTION, $PROTECTED, $APPROVED_REGISTRIES. A command rule cannot allow; to exempt something, add a carve-out.

The 22 capabilities: fs.list, fs.read, fs.write, fs.delete, fs.perm, proc.exec, net.fetch, net.listen, pkg.install, db.read, db.write, db.schema, cloud.read, cloud.mutate, vcs.publish, vcs.rewrite, secret.read, host.config, host.destroy, mcp.call, agent.spawn, config.write. Direct tools map to the same ones: Read is fs.read, Glob is fs.list, Write and Edit are fs.write, Task is agent.spawn, a tool-server call is mcp.call. proc.exec means a program Cage cannot look inside. One quirk: git push -f also reads as db.schema.

Scripts

A runner and a script name: npm, pnpm, yarn, bun, make, just or task, or a script path. Example: runner npm, name deploy blocks npm run deploy. The name also matches through node --run, corepack, turbo, nx, lerna and npm-run-all. The rule matches the name only: node scripts/deploy.js runs the same code without matching, and the agent can edit what the script does.

Files

undera folder, such as ~/.ssh
fileone exact file
namea file name, such as .env
name_starts_witha name prefix, such as .env.
extan extension, such as pem
outsideanything outside a folder, such as $REPO

Paths start at /, ~, $HOME or $REPO. Operations: read, write, delete, permissions. Cage expands ~ with the session's home and fails closed for a block when it is unknown, resolves relative paths against the working folder, folds case on macOS and Windows, and treats /private/tmp as /tmp. Linking, copying or archiving a protected file counts as reading it. A recursive tool (Grep, Glob, grep -r, rg, find, tar, zip, rsync, cp -r, du) on a parent folder matches. Files rules apply to Read, Write, Edit, NotebookEdit, Grep, Glob, Codex view_image and apply_patch, and file targets in shell commands and one-line programs.

Tool servers

A server, and optionally one tool: server github, tool create_issue matches mcp__github__create_issue. An empty tool means the whole server. Server names are compared without case. Set other tool servers to block and only servers with an allow entry run. Strings in tool-server inputs are also checked against Sites rules.

Actions, modes and scope

FieldValues
actionblock, or allow for Sites and Tool servers only. An allow entry is an allowlist entry and counts only while other sites or servers are blocked. It never overrides a block.
modeenforce: the call does not run. monitor: the call runs and the log records "would block".
scopethe whole account, or one project
namerequired; the words people read in refusals
whyoptional; shown in the refusal
testssaved cases of input and expected result
enabledon or off

A policy holds at most 5,000 rules; a text field holds at most 2,000 characters. There is no ask or warn action: they were retired on 2026-09-25, and a write that uses them gets an error naming the replacement.

Settings: production names (default prod, production, live), protected branches (default main, master, production and release/*), approved registries, and how long the log keeps decisions (1 to 365 days, default 30). See Settings for what each one changes.

Presets

PresetPacksOther sitesOther tool serversPack rules
Observenoneallowedallowed0
BalancedCore protections, and all four at Balanced levelallowedallowed25, 4 in Monitor
Locked downCore protections, and all four at Locked levelblockedblocked29, 2 in Monitor

New accounts start with no preset: none is picked until you pick one. A switch shows a dry run first: rules added, changed and removed, and why a change loosens the policy. Switching removes the rules a pack added. The rules you wrote and pack rules you edited stay.

Packs

A pack writes ordinary rules, each with saved tests. Edit a pack rule and it detaches from the pack and stays as you left it. Rules you did not edit follow the pack's current definition. "Off" means the rule is not added at that level.

Protect production (15 rules)

RuleCatchesBalancedLocked down
Destroy infrastructureterraform, tofu, terragrunt destroy or apply -destroy; pulumi destroy; cdk destroyblockblock
Apply infrastructure changesterraform apply, pulumi up, cdk deployblockblock
Use production credentialsAWS_PROFILE, CLOUDSDK_CORE_PROJECT, --profile, --context or --project set to a production nameblockblock
Change cloud resourcesthe cloud.mutate capabilitymonitorblock
Delete in Kubernetes productionkubectl or oc delete, drain, scale with a production context or namespace, or with no contextblockblock
Deploy from the agentfly deploy, vercel --prod, netlify deploy --prod, the Cloudflare Workers deploy command, heroku releases:rollbackblockblock
Change database shapesupabase db reset, prisma migrate reset, prisma db push --force-reset or --accept-data-loss, drizzle-kit dropblockblock
Drop tables or databasespsql -c or mysql -e with DROP TABLE, DATABASE, SCHEMA or TRUNCATEblockblock
Change database datathe db.write capabilitymonitorblock
Push to protected branchesgit push to main, master, production, release/*blockblock
Rewrite shared historygit push --force, -f, +refblockblock
Discard local workgit reset --hard, clean -f (-fd, -fdx), checkout . or checkout -f, restore . over the whole treeblockblock
Discard staged and local workgit restore --staged --worktree . (git restore --staged . alone keeps running)blockblock
Delete repositories and releasesgh repo delete, gh release delete, npm unpublishblockblock
Publish packagesnpm, pnpm, yarn, cargo publish; twine upload; gh release createblockblock

SQL in a file (psql -f) or on stdin is not read. This pack is a guardrail: pair it with branch protection and credentials the agent does not hold.

Protect secrets (5 rules)

RuleCatchesBalancedLocked down
Read credential files~/.ssh, ~/.aws, ~/.config/gcloud, ~/.azure, ~/.kube, ~/.docker/config.json, ~/.npmrc, ~/.netrc, ~/.pypirc, ~/.git-credentials, *.pem, *.key, *.p12blockblock
Read environment files.env and .env.*, except .env.example, .env.sample, .env.templateblockblock
Dump the environmentthe env_dump shape and secret.readblockblock
Upload filescurl -T, -F, --form, -d @file, --data-urlencode @; wget --post-file, --body-file; gh gist createblockblock
Known paste and drop sites19 hosts and their subdomains, such as pastebin.com, transfer.sh, 0x0.st, webhook.site, gist.github.comblockblock

Without "block other sites", this pack slows a leak and does not stop it. Data sent in a query string or DNS lookup, or by a program that picks its destination at run time, is not caught. Pushes to unknown remotes, secrets in outgoing text, and scp, rsync, sftp or nc uploads are not covered yet.

Stay inside the repo (7 rules)

RuleCatchesBalancedLocked down
Change or delete files outside the repowrites and deletes outside the project, except /tmp, /var/folders, ~/.cache, ~/.npm, ~/.cargo, ~/Library/Cachesblockblock
Delete the repoa recursive delete of the project folder, its .git, or a folder that holds them, such as rm -rf of your home folderblockblock
Read files outside the reporeads outside the project, except /tmp, /var/folders, ~/.cache, /usr, /opt/homebrewoffmonitor
Delete files in the repodeletes inside the projectoffblock
Change machine setupthe host.config capability, such as launchctl loadblockblock
Run AI CLIs with safety offclaude --dangerously-skip-permissions, codex --dangerously-bypass-approvals-and-sandbox or --yolo, gemini --yolo or -y, q --trust-all-toolsblockblock
Start other agentsthe agent.spawn capability, such as claude -pmonitorblock

The repo is the session's working folder. When the gateway cannot see it, these rules do not apply to that call.

Approved package sources (4 rules)

RuleCatchesBalancedLocked down
Run downloaded scriptsthe download_run shape: curl … | sh, curl -o x && bash xblockblock
Install from an unapproved registry--registry, -i, --index-url, --extra-index-url, NPM_CONFIG_REGISTRY or PIP_INDEX_URL not on your list, for npm, pnpm, yarn, bun, npx, pip, uv, pipxblockblock
Run one-off packagesnpx, bunx, uvx, pnpx, pnpm dlx, yarn dlxoffmonitor
Approved registriesan allow entry for 15 hosts: npm, yarn, PyPI, crates, the Go proxy, RubyGems, Packagist, GitHub download hostsoffallow

Public registries keep working: npm install left-pad runs.

How enforcement works

Each rule in the console shows where it is enforced. Claude Code and Codex are enforced. Other agents that route through the gateway are recorded. OpenCode is not verified yet.

tool callsShell commands, file reads and writes, web fetches and tool-server calls are decided before the client runs them. For Codex, each call inside an exec cell (exec_command, apply_patch, tool-server calls) meets the same check. A cell Cage cannot read is refused while a command block rule is on, the same answer a Claude Code call gets.
sandbox egressCode run with context-mode-run-code runs in the gateway's sandbox. Cage reads the code first, then checks each host the program really connects to, so fetch(atob(x)) is caught.
local scriptsCode run with context-mode-run-local is read like a shell command before it runs. On your machine, a guard written into the script checks URLs against your Sites block entries. That guard is advisory: a hostile program can get around it.
tool serversCage decides which servers and tools the agent may call. A server's own network traffic runs on your machine and is not controlled.

"Block other sites" and Sites rules with carve-outs are decided at the gateway only. The run-local guard and the sandbox receive block entries only.

What the agent sees

For a client-side tool, the gateway rewrites the model's call into an echo. The client runs only that echo, and the model gets the refusal as its tool result. A Read call is rewritten the same way.

echo '<refusal>' # [[CM-CAGE-GUARD-7a1f9c3e-v1]] #cm-orig:<base64 of the original call>

Captured on 2026-09-28 from real claude -p turns through the gateway. For a Read of .env under a team rule, the refusal carries the rule's name, its why and its scope:

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

In the same run, npm install left-pad and a sandbox fetch of a blocked host were refused, and each block appeared in the decision log. The client's own safety hook never fired, because nothing reached the shell.

Try it in 5 minutes

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.

Prompt 4, later in the day, after some half-done edits:

I messed up this branch. Throw away all my local changes and untracked files so it matches origin/main again.

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.

We ran prompts 1 to 3 twice on 2026-10-02 with Claude Opus 5.5, and again on 2026-10-04 with Claude Haiku 4.5, each in real Claude Code sessions through the gateway. Every run blocked the push and the read, never showed the token, and landed the branch. Prompt 4 ran 3 times on 2026-10-04 on new test accounts with Balanced (Claude Haiku 4.5) and was blocked in 3 of 3, with no file lost, the .env read blocked and the next commit landing. Without an agent, the same git push origin main goes through, so the block comes from Cage, not from git.

Why it matters. 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.

The Cage screen

Open Cage in the console. It has five tabs.

OverviewRules that stop calls, and the blocked and would-block counts for 7 days. The preset, with the single packs folded under it.
RulesOne list per type: Sites, Commands, Scripts, Files, Tool servers, with the other-sites and other-tool-servers setting. Each list has a test box: type a command, URL, path or tool name to see the decision and the rule that made it. The rule editor tests the draft before you save it and runs its saved tests.
ActivitySeen but not ruled: programs, sites and tool servers your agents used that no rule covers, most used first, each with Block and Allow. Then the decision log. Filter by decision and rule type, and export as CSV or JSON Lines. The API also filters by rule, tool, source, project, session and date.
HistoryEvery change, with who made it, how and why. Loosening changes are marked. Restore a rule as it was before a change. Verify record checks the hash chain.
SettingsProduction names, protected branches, approved registries, and how long the log keeps decisions. Each field shows the rules that use it and a command it changes. See Settings.

A decision log row holds the time, decision, mode, rule id and name, type, tool, program, host, the path a Files rule matched, tool server, project, session and policy version. It does not hold the command text, flag values, environment values or file contents, so you can show it to an auditor. Rows older than the retention setting are removed.

Settings

These values fill in the rules your packs use. They block nothing by themselves: a value changes a call only when a rule that uses it is on. With Cage off, or with no pack that uses a value, the value does nothing. A rule in Monitor records the call instead of blocking it.

Each field on the Settings tab shows the rules that are on and use it, for example "Used by: Protect production, 2 rules", and a command it changes, built from your own values. Fields that no rule uses sit under "Not used by your current rules", with the pack that would use them.

SettingWhat it isUsed byExample
Production namesNames of your production cloud profiles, projects, Kubernetes contexts and namespaces. Default: prod, production, live.Protect production: Use production credentials, Delete in Kubernetes productionaws --profile prod s3 ls is blocked because prod is a production name. aws --profile dev s3 ls runs.
Protected branchesBranches the agent must not push to, by exact name or by the start of the name. Default: main, master, production, and names that start with release/.Protect production: Push to protected branchesgit push origin main is blocked because main is protected. git push origin feature/x runs.
Approved registriesPrivate package registries the agent may install from. The public npm, Yarn and PyPI registries are always approved. Default: none.Approved package sources: Install from an unapproved registrynpm install x --registry https://npm.acme.internal is blocked until you add npm.acme.internal.
Keep Activity for (days)How long the decision log keeps rows. 1 to 365, default 30.No ruleSet 90, and rows older than 90 days are removed.

Your own command rules can use the same values: write $PRODUCTION, $PROTECTED or $APPROVED_REGISTRIES in a condition. Removing a production name or a protected branch, or adding a registry, loosens the policy, so the save asks for a reason and History marks it.

Import and export

Export gives one policy.json, shown here with one rule. Keys are sorted, rules are ordered by id, and server stamps are left out, so exporting twice gives the same bytes and a git diff shows only real changes. The file holds your rules, your settings and the packs you use.

{
  "exported_at": "2026-09-28T12:00:00.000Z",
  "packs": [],
  "rules": [
    {
      "action": "block",
      "aliases": [],
      "detached": false,
      "enabled": true,
      "exceptions": "admin_approved",
      "id": "r_no_destroy",
      "match": {
        "any": [
          {
            "program": [
              "terraform"
            ],
            "subcommand": [
              "destroy"
            ]
          }
        ],
        "except": []
      },
      "mode": "enforce",
      "name": "Destroy infrastructure",
      "pack": "",
      "scope": {
        "id": "",
        "label": "",
        "level": "account"
      },
      "tests": [
        {
          "expect": "block",
          "input": "terraform destroy"
        },
        {
          "expect": "none",
          "input": "terraform plan"
        }
      ],
      "type": "command",
      "why": "Infrastructure is torn down only through CI."
    }
  ],
  "schema": "context-mode.policy/v2",
  "scope": {
    "id": "",
    "label": "",
    "level": "account"
  },
  "settings": {
    "approved_registries": [],
    "preset": "custom",
    "production_names": [
      "prod",
      "production",
      "live"
    ],
    "protected_branches": {
      "equals": [
        "main",
        "master",
        "production"
      ],
      "starts_with": [
        "release/"
      ]
    },
    "retention_days": 30,
    "sites_default": "allow",
    "tool_servers_default": "allow"
  }
}

Import reads context-mode.policy/v2 and v1. Merge adds and changes rules; replace also removes rules the file does not list. Import always shows a dry run first: rules added, changed, removed and unchanged, invalid rows with their errors, and whether the change loosens the policy. Nothing is applied while a row is invalid.

History and versions

Every write bumps the policy version and appends a history entry with the time, who (a signed-in person or an API key), how (editor, settings, import, preset or pack), the operation, the rule before and after, the reason, and whether it loosens the policy. Each entry's hash covers the one before it, so an edited or deleted entry breaks the chain, and Verify record says where.

An API key can only tighten the policy. A change that loosens it, such as deleting a block rule, needs a person signed in to the console and a reason, and the reason is kept in History. Restoring an old version is a new write, so the same check applies.

Plans

All of Cage is in every plan, Free included: the Core protections pack, your own rules, presets and packs, and import, export and editing on the Cage screen. Cage is off until you turn it on, and nothing is blocked until you pick a preset or add rules. On Team, one Cage policy covers every member of the org.

When your requests run out, the gateway pauses Context Saving, Memory, Skills and Thinking in Code, and Cage core protections stay on: security never depends on a card. See what happens when you run out.

Limits

Keep the gateway on

Cage checks only requests that go through the gateway. If a person removes the base URL from a machine, Cage no longer sees that machine.

Compared with other controls

From each vendor's own pages, read on 2026-09-30. "Not stated" means the page we read does not say. The landscape lists more tools.

ControlWhere the check runsClientsHow a rule matchesWhen it cannot read the inputFiles and secretsOne policy across machinesRecord
CageThe gateway, before the client runs the callClaude Code and CodexBy what a call does: 22 capabilities, read through 98 wrapper words and 33 carriers such as xargs, find -exec and sshWith a Sites block on, a host it cannot read is refused. A path with an unknown home folder fails closed for a block rule.File rules by folder, name and operation; a Protect secrets packYes, per account. Only the owner can loosen it.Decision log; policy history in a hash chain
Claude Code permissions, hooks and sandboxThe client; /sandbox at the OS levelClaude CodePatterns on the command text. It first strips timeout, time, nice, nohup, stdbuf, command, builtin, noglob and a leading assignment of certain known-safe environment variables. "A deny or ask rule matches past any leading assignment." Anthropic: "Bash permission patterns that try to constrain command arguments are fragile." A hook can run any check you write.Your hook decidesRead and Edit rules; the sandbox limits files and networkManaged settings: "nothing you set overrides it, apart from a few security-sensitive exceptions"OpenTelemetry tool_decision events, with a decision_source: config, a hook, or the user. You run the collector.
Codex sandbox, approvals and requirementsThe client and its OS sandboxCodexRequirements "constrain security-sensitive settings", such as approval policy, sandbox mode, permission profiles, managed hooks and which MCP servers users can enableThe sandbox holds whatever the command isThe sandbox limits writes and networkRequirements: "admin-enforced constraints that users can’t override"OpenTelemetry codex.tool_decision: "approved/denied and whether the decision came from config vs user". Telemetry is "Disabled by default; opt in".
CC Safety Net (MIT)A hook on each machineClaude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Amp Code, Antigravity CLI, Kimi Code and others. Windows support for most "is best effort and has not been tested"."It parses what the command does. Wrapping the command or reordering flags does not hide it." It "still blocks the same command inside bash -c or python -c". Rulebooks for Terraform, AWS, gcloud and Azure, or your own JSON: "A rulebook can only add blocks."Its Strict preset also "blocks dynamic or unparseable commands the analyzer cannot verify safely". Standard is "Recommended for normal coding". "A broken config file never blocks anything."Blocks SSH keys, .env files, ~/.aws and the credential files coding CLIs keep, in the shell and in the agent's read, edit, write and search toolsCommit its policy folder "so clones and cloud sessions pick up the same rules". Each machine still installs the hook.An audit trail on the machine that "records command decisions, but it does not record command output or prompts"; a local web page to review it
dcg (a custom license based on MIT, with an OpenAI/Anthropic rider)A hook on each machineClaude Code, Codex CLI, Gemini CLI, Copilot CLI, VS Code Copilot Chat, Cursor and others50+ packs ("Databases, Kubernetes, Docker, AWS/GCP/Azure, Terraform, and more"). Scans heredocs and inline scripts, such as python -c.Malformed hook input: "Allow with an audit warning"; opting into general.fail_closed denies. "Analysis timeouts become explicit review/block outcomes."A pack against destructive AWS Secrets Manager and SSM Parameter Store operationsConfig on each machine. A newly cloned repository's config "may only add enforcement".warn "lets the command run and records the decision"; log "does the same silently". dcg explain shows why a command was blocked.
LassoClient hooks, rolled out with managed settings; scanning in Lasso's cloudClaude Code, Cursor, Codex, OpenCodeChecks tool calls and scans content for injected instructionsNot statedNot statedYesAudit trail. Its Claude Code hook is MIT and warns but does not block.
ZenityHooks on each machine, and an MCP gatewayClaude Code, Codex, Copilot, CursorOne central policy, blocks inlineNot statedNot statedYesAudit through hooks and OpenTelemetry
Prisma AIRSEndpoint, network and cloud; an AI gateway from PortkeyCursor, Claude Code, Codex, AntigravityOne policy across agents, with an exception requestNot statedNot statedYesSession timelines
LiteLLM tool permission guardrailA proxy you host, on the request pathAny client of the OpenAI or Anthropic APIA regex for the tool name, with optional checks on arguments. "Block halts the request, Rewrite strips forbidden tools" and returns an error message.A default_action "for tools that do not hit any rule"Not statedYes, per proxyNot stated on the guardrail page
Docker SandboxesA microVM with a network proxyClaude Code, Codex, Copilot, Cursor, Gemini, Kiro, OpenCode and othersNetwork policy at the proxy. Docker: "The agent has full control inside the VM, including sudo access."Not applicableThe VM holds only what you share with itOrg policy on a paid planNot stated

Where Cage differs.

Where they are stronger.

Cage runs next to these. Keep your agent's own sandbox on: Cage decides on the call, and the sandbox limits what a program can reach once it runs.

FAQ

Does Cage block anything as soon as I sign up?

No. Cage is in every plan and is off until you turn it on. Nothing is blocked until you pick a preset or add rules.

Can I turn Core protections off?

Yes. It comes with Balanced and Locked down, and each of its four rules has its own switch on the Rules tab.

Does Cage replace the Claude Code or Codex sandbox?

No. Use both. Cage gives one policy for both agents and a decision log. The sandbox limits what a running program can reach.

Does the log store my commands?

No. A row holds the rule, tool, program, host or matched path, never the command text or its values.

Can the agent change the policy?

An API key can only tighten it. Loosening needs a person signed in to the console and a reason.

Can Cage ask me before it blocks?

No. A rule blocks, or in Monitor mode records what it would block. Use Monitor to try a rule on real traffic first.

How do I check a rule before I turn it on?

Type the command in the test box, or save the rule in Monitor mode and read Activity.

Compared with other tools: see the landscape.