Harness Notes

JSON

Permissions

4 records · Updated 2026-10-14

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 CLIClaude CodeCursor Agentpi
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
prefix_rule(
    pattern = ["git", "push"],
    decision = "forbidden",
    justification = "Pushing is a human decision",
    match = ["git push", ["git", "push", "origin", "main"]],
)
{
  "permissions": {
    "deny": [
      "Bash(git push:*)"
    ]
  }
}
{
  "permissions": {
    "deny": [
      "Shell(git:push*)"
    ]
  }
}
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { isToolCallEventType } from "@earendil-works/pi-coding-agent";

export default function (pi: ExtensionAPI) {
  pi.on("tool_call", async (event) => {
    if (isToolCallEventType("bash", event) && /(^|[;&|]\s*)git\s+push\b/.test(event.input.command)) {
      return { block: true, reason: "git push is blocked by policy" };
    }
  });
}
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 CLIClaude CodeCursor Agentpi
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

Built in

Cover: shell, read, write, web fetch, MCP

Match by: permission tokens with patterns

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

Built in

Limits: filesystem, network

Enforced separately from permission rules.

Docs

Not established

Not supported

No built-in execution sandbox is claimed.

Approval prompts

Built in

Modes: untrusted, on-request, never

approval_policy and sandbox_mode are separate inputs

Docs

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

PreToolUse, PermissionRequest

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

PreToolUse, PermissionRequest, PermissionDenied

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

preToolUse, beforeShellExecution, beforeMCPExecution, beforeReadFile

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

tool_call, tool_result

An extension can implement a permission gate, but it must emit its own evidence.

Docs
Where rules live
  • ~/.codex/config.toml · user
  • .codex/config.toml · project
  • CLI flags and -c overrides · session

Priority between these files is not recorded here.

  • managed settings · managed
  • CLI flags · session
  • .claude/settings.local.json · project-local
  • .claude/settings.json · project
  • ~/.claude/settings.json · user

Listed highest priority first.

  • <project>/.cursor/cli.json · project
  • ~/.cursor/cli-config.json · user

Project settings override global ones.

No permission settings

Sources

Codex CLI
Claude Code
Cursor Agent
pi