Permission Rules
A permission rule names a tool, and it can name a pattern for that tool.
Three lists hold the rules. allow runs a call with no prompt. ask always prompts. deny blocks the call.
For example, Bash(git push:*) in deny stops each git push command.
Add rules to permissions.allow, permissions.ask, or permissions.deny in a settings file, run /permissions, or pass --allowedTools and --disallowedTools for one session. Remove a rule to turn it off. allowManagedPermissionRulesOnly turns off rules from every scope except managed settings.
Example
{
"permissions": {
"allow": ["Bash(bun test)", "Bash(git diff *)", "Read(src/**)"],
"ask": ["Bash(git commit *)"],
"deny": ["Bash(git push:*)", "Read(.env)", "WebFetch"],
"additionalDirectories": ["../shared-lib"]
}
}
The permissions Keys
Lists from all scopes merge. Official pages: Configure Permissions and Choose a Permission Mode.
| Item | Status | What it does | How it works | Where to set it |
|---|---|---|---|---|
permissions. | Documented | List of rules for allowed operations | Lists from all scopes merge. Project allow rules wait for workspace trust. allow limits them to managed settings | Each settings scope |
permissions. | Documented | List of rules that always prompt | ask and deny rules apply at once, before trust. An allow rule in a local file does not outrank an ask rule from a project or managed file | Each settings scope |
permissions. | Documented | List of rules for denied operations | A bare tool name hides the tool from the model. See Tools | Each settings scope |
permissions. | Documented | Default permission mode | manual is an alias of default. auto and bypass do not take effect from project or local settings | User, managed, -- |
permissions. | Documented | Value disable removes bypass | Checked when a session starts in or can return to that mode | Mainly managed settings |
permissions. | Documented | Refuses Read, Grep, Glob, and LSP reads outside the working directories in each mode | true from any scope wins, also over a managed false. Needs 2. | Each settings scope |
permissions. | Documented | Extra directories in the permission scope | Applies after workspace trust. -- and / do the same for one session | Each settings scope |
permissions. | Documented | Value disable turns auto mode off | The reason text is disable. See Auto Mode | Settings, mainly managed |
Related Top-Level Keys
| Item | Status | What it does | How it works | Where to set it |
|---|---|---|---|---|
allow | Documented | Only managed settings supply permission rules | Rules from other scopes are ignored with a notice that names this key | Managed settings |
skip | Documented | The user accepted the bypass dialog | Boolean | User settings |
skip | Documented | The user accepted the auto mode opt-in dialog | Boolean | Settings |
use | Documented | Plan mode uses auto mode semantics when auto mode is available | Default true. A false from managed, --, user, or local settings wins | Settings |
auto | Documented | Classifier rules | See Auto Mode | User, --, managed |
sandbox | Documented | Bash sandbox | See Sandbox | Each settings scope |
Rule Syntax
A rule has the form Tool or Tool(content).
The tool name is case-sensitive. The content has no space at its start or end inside the parentheses.
Source: the program text tool name case-sensitive, non-empty content with no leading/trailing whitespace inside the parens.
| Form | Status | What it matches | Notes |
|---|---|---|---|
Bash(bun test), Power | Documented | Shell commands by pattern. | * is a wildcard. \* is a literal star. A pattern that ends in a space and one star also matches the bare command. |
Bash(git push: | Documented | The legacy prefix form. | The suffix : matches the prefix before it. Use Bash(git push *) in new rules. |
Read(src/, Edit(... | Documented | Files by glob. | ** crosses folders. A rule that starts with / anchors at the primary working folder. |
Web | Documented | One host. | The prefix domain: is required. domain: is allowed. A full URL is rejected. |
Web | Documented | Exact search terms. | Wildcards * and ? are rejected. |
mcp__, mcp__ | Undocumented | All tools of one MCP server, or one tool. | The program pattern is ^mcp__. |
Skill(name) | Documented | One skill. | The program text is Skill execution blocked by permission rules. |
Bash (no content) | Documented | The whole tool. | In deny, a bare tool name hides the tool from the model. |
Explicit deny and ask rules apply before allow rules.
See Permission Flow.
Flags and Hooks That Touch Permissions
| Item | Status | What it does | How it works | Where to set it |
|---|---|---|---|---|
-- | Documented | Sets the mode for one session | Choices accept, auto, bypass, manual, dont, plan | CLI |
--, -- | Documented | Allow or deny tool rules for one session | Comma or space separated, such as "Bash(git *) Edit" | CLI |
-- | Documented | Same as -- | Use only in sandboxes with no internet | CLI |
-- | Documented | Makes bypass available without enabling it | Mode can be chosen later | CLI |
-- | Documented | Who answers prompts with -- | none denies every prompt. The mode still decides the rest | CLI print mode |
-- | Documented | Restricted mode | Refuses bypass, confines file tools to the working directories. Env CLAUDE_ | CLI |
Permission hook | Documented | Answers a prompt | Output decision. is allow (with updated, updated) or deny (message, interrupt) | Hooks |
Permission hook | Documented | Fires on an auto mode denial | Output retry | Hooks |
Permission Updates
A PermissionUpdate changes rules or the mode. Hooks and SDK hosts send and receive them.
| Field | Values |
|---|---|
type | add, replace, remove, set, add, remove |
destination | user, project, local, session, cli |
| rule value | An object with tool and rule. |
Source: PermissionUpdate in the program types (types-2.1.304.d.ts).
How It Works
Permission Flow shows how Claude Code walks the lists, the hooks, and the mode.