Skip to main content
Permissions provide fine-grained control over tool execution. You can configure which tools run automatically (without asking), which require user confirmation, and which are blocked entirely.
Evaluation order: Deny → Allow → Ask. Deny patterns are checked first. If no deny matches, allow patterns are checked. Anything else requires user confirmation by default.

Configuration

Permissions are set at the top level of the config file and apply globally to all agents:
permissions:
  # Auto-approve these tools
  allow:
    - "read_file"
    - "read_*"
    - "shell:cmd=ls*"

  # Block these tools entirely
  deny:
    - "shell:cmd=sudo*"
    - "shell:cmd=rm*-rf*"

  # Always ask for these (even if normally auto-approved)
  ask:
    - "write_file:path=/etc/*"

Fields

allow
string[]
Tool name patterns that are auto-approved without user confirmation. Glob patterns and argument matching are supported.
deny
string[]
Tool name patterns that are always rejected. Deny takes priority over allow — denied tools cannot be overridden even with --yolo.
ask
string[]
Tool name patterns that always require user confirmation, even for tools that would normally be auto-approved (e.g., read-only tools).

Pattern syntax

Permissions use glob-style patterns with optional argument matching.

Simple patterns

PatternMatches
shellExact match for the shell tool
read_*Any tool starting with read_
mcp:github:*Any GitHub MCP tool
*All tools

Argument matching

Match tools based on the value of a specific argument using tool:arg=pattern syntax:
permissions:
  allow:
    - "shell:cmd=ls*"          # shell tool when cmd starts with "ls"
    - "shell:cmd=cat*"
    - "edit_file:path=/home/user/safe/*"

  deny:
    - "shell:cmd=sudo*"
    - "write_file:path=/etc/*"
    - "write_file:path=/usr/*"

Multiple argument conditions

Chain conditions with colons. All conditions must match:
permissions:
  allow:
    - "shell:cmd=ls*:cwd=."   # ls only in current directory

  deny:
    - "shell:cmd=rm*:cmd=*-rf*"  # rm with -rf flag

Glob pattern rules

  • * matches any sequence of characters (including spaces)
  • ? matches any single character
  • [abc] matches any character in the set
  • [a-z] matches any character in a range
  • Matching is case-insensitive
Trailing wildcards like sudo* match any characters including spaces, so sudo* matches sudo rm -rf /.

Decision types

DecisionBehavior
AllowTool executes immediately without user confirmation
AskUser must confirm before the tool executes (default)
DenyTool is blocked and returns an error to the agent

Examples

Read-only agent

Allow all read operations, block all writes and shell access:
permissions:
  allow:
    - "read_file"
    - "read_multiple_files"
    - "list_directory"
    - "directory_tree"
    - "search_files_content"
  deny:
    - "write_file"
    - "edit_file"
    - "shell"

Safe shell agent

Allow specific safe commands, block dangerous ones:
permissions:
  deny:
    - "shell:cmd=rm *"
    - "shell:cmd=sudo *"
    - "shell:cmd=chmod *"
    - "shell:cmd=sh *"
    - "shell:cmd=bash *"
    - "shell:cmd=git push --force*"
    - "shell:cmd=git reset --hard*"

  allow:
    - "shell:cmd=ls *"
    - "shell:cmd=cat *"
    - "shell:cmd=head *"
    - "shell:cmd=tail *"
    - "shell:cmd=grep *"
    - "shell:cmd=find *"
    - "shell:cmd=git status*"
    - "shell:cmd=git log*"
    - "shell:cmd=git diff*"
    - "shell:cmd=go test*"
    - "shell:cmd=go build*"

MCP tool permissions

Control MCP tools by their qualified names:
permissions:
  allow:
    - "mcp:github:get_*"
    - "mcp:github:list_*"
    - "mcp:github:search_*"
  deny:
    - "mcp:github:delete_*"
    - "mcp:github:close_*"

Interaction with hooks

Permissions and hooks work together. The full evaluation order for a tool call is:
  1. Check deny patterns — if matched, tool is blocked immediately
  2. Check allow patterns — if matched, tool is auto-approved
  3. Run pre_tool_use hooks — hooks can allow, deny, or ask
  4. If no decision reached, ask user for confirmation
Hooks can override allow decisions but cannot override deny decisions.
Permissions are enforced client-side and help prevent accidental operations. For stronger isolation — especially with untrusted agents — use sandbox mode.

Build docs developers (and LLMs) love