Quick Start
How It Works
On each tool call, the backend builds a target string (tool_name:arg) and PermissionManager.check() returns allow, deny, or ask. Non-interactive runs honour declared rules; ask without a human present falls back to deny.
Pattern Syntax
Patterns use<tool_name>:<arg-glob>:
| Pattern | Meaning |
|---|---|
read:* | Any read tool call |
bash:git * | Git shell commands |
write:/etc/* | Writes under /etc/ |
is_regex, priority, agent_name, and description:
Configuration Surfaces
| Surface | Where | Example |
|---|---|---|
| YAML | Top-level or per-agent approval.permissions: | "bash:rm *": deny |
| CLI | --allow, --deny, --permissions <file>, --permission-default | --deny 'bash:rm *' |
| Python | ApprovalConfig(permissions={...}) | {"read:*": "allow"} |
approval.permissions → top-level YAML permissions: → CLI --allow/--deny (override file) → --permission-default → built-in defaults.
Load from file:
Common Patterns
Read-only CI runner —--permission-default deny with --allow 'read:*'.
Git-only worker — allow bash:git *, deny everything else.
Deny destructive commands — baseline "bash:rm *": deny and "write:/etc/*": deny.
Best Practices
Set permission-default deny in CI
Set permission-default deny in CI
Use
--permission-default deny or "*": deny so undeclared tools are blocked.Prefer specific patterns first
Prefer specific patterns first
Higher-priority rules win — declare
bash:git push * before broad bash:*.Version-control policy files
Version-control policy files
Keep
permissions.yaml next to agents.yaml in git.Test with --no-tty locally
Test with --no-tty locally
Verify rules before deploying to CI.
Related
Permissions
Programmatic PermissionManager API
Approval
Interactive approval backends
Tool Approval CLI
CLI flags reference

