How to stop an agent doing something, and what each harness gives you to control it. Permission rules decide what the agent may do; a sandbox limits what a command can reach even when it is allowed.
No research recorded for OpenCode.
Block a command, for example git push
| Codex CLI | Claude Code | Cursor Agent | pi | |
|---|---|---|---|---|
| How | A command rule file | A deny rule in the permission settings | A deny rule in the permission settings | An extension that blocks the tool call Only with an extension |
| File | .codex/rules/deny-push.rules | .claude/settings.json | .cursor/cli.json | .pi/extensions/block-git-push.ts |
| Example | | | | |
| How it matches | ordered argv-token prefix matching; .rules files are auto-discovered below the rules directory of each configuration layer | shell-operator-aware Bash command matching with wrapper stripping and leading environment-assignment handling | Shell(commandBase) with an optional command:args glob; exact argument-string behavior is not fully documented | extension-defined string matching over bash tool input |
| What wins | forbidden is stricter than prompt and allow and cannot be approved interactively | deny, then ask, then allow; a matching deny survives every permission mode and cannot be overridden by a hook allow | deny takes precedence over allow and survives --force/--yolo | no native policy precedence; extension ordering and later input mutation matter |
| Watch out for | Command rules belong in .codex/rules/*.rules, not config.toml. --ignore-rules skips user and project rule files; use a managed layer or OS containment when the invoking user must not be able to bypass the rule. Wrappers and nested interpreters require separate coverage unless Codex's nested-command parser recognizes the invocation. | Environment runners and nested interpreters such as sh -c can hide the inner command; deny those runners too or use OS containment for a hard boundary. | Matching details are only partly documented. Shell(git) is the unambiguous declarative form but blocks every git command. For exact git-push matching, use a beforeShellExecution hook that returns permission deny or exits 2; other non-zero hook exits fail open. | Stock pi has no declarative deny rule or built-in sandbox. The extension owns shell parsing and must explicitly cover wrappers, interpreters, aliases, and scripts. Project extensions load only after project trust. |
What you can control
| Codex CLI | Claude Code | Cursor Agent | pi | |
|---|---|---|---|---|
| Decisions | allow · ask · deny | allow · ask · deny | allow · ask · deny | None built in |
| Permission rules | Built in Cover: sandbox escalation, command rules, MCP elicitation, permission request, skill approval Match by: approval_policy plus command rules Docs | Built in Cover: tool, command, path, network, MCP Match by: tool rules with tool-specific specifiers Conflicts: deny, then ask, then allow; first match within the winning class Docs | Not supported Stock pi has no built-in tool permission model; extensions run with the user's authority. Docs | |
| Sandbox | Built in Limits: filesystem, network Modes: read-only, workspace-write, danger-full-access Enforced separately from permission rules. Docs | Not established | Not supported No built-in execution sandbox is claimed. | |
| Approval prompts | Built in Modes: default, acceptEdits, plan, auto, dontAsk, bypassPermissions Remember an approval: once, session, project-command Docs | Not established | Not supported An extension must implement its own approval UI and policy. | |
| Skills granting tools | Not supported Codex does not interpret SKILL.md allowed-tools as a skill-scoped permission grant. Docs | Built in Field: allowed-tools turn-scoped pre-approval while the skill is active; not a tool-availability restriction Docs | Not established | Not supported |
| Hooks that decide | Built in
Can: allow · deny PreToolUse can only deny; PermissionRequest can allow or deny, and any deny wins. Hook-definition trust and tool approval are separate controls. Docs | Built in
Can: allow · ask · deny A hook allow does not override matching ask or deny rules; a blocking hook takes precedence over allow rules. Docs | Built in
Can: allow · deny · ask Hook permission decisions are a separate surface from CLI permission files. ask is not enforced for preToolUse. Docs | Only with an extension
An extension can implement a permission gate, but it must emit its own evidence. Docs |
| Where rules live |
Priority between these files is not recorded here. |
Listed highest priority first. |
Project settings override global ones. | No permission settings |