Configure permissions changedagent-sdk/permissions
Nearest release: v2.1.318, published 20 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 4 Nov 2026 18:09 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 4 Nov 2026 18:37 UTC.
Upstream edited
Recorded here
Lines+58added
Lines−31removed
From line
10
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits32to this page, all time
### Path patterns in rules
The whole hunk
from line 10, old and new numbered
/
from line 10
1010>
1111> If you load a plugin that contains a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md), see [where a mod's decisions fit among rules and hooks](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).
1212
13When Claude requests a tool, the SDK checks permissions in this order:
13When Claude requests a tool, Claude Code checks the call at these steps. Each step can decide the call, send it to your `canUseTool` callback, or pass it on:
1414
1515**1. Hooks**
1616
17Run [hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md) first. A hook can deny the call outright or pass it on. A hook that returns `allow` doesn't skip the deny and ask rules below, which are evaluated regardless of the hook result.
17Run [hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md). A hook can deny the call outright or pass it on. A hook that returns `allow` doesn't skip the deny and ask rules below, which are evaluated regardless of the hook result.
1818
1919A `PreToolUse` hook that returns `allow` also can't approve an `rm` or `rmdir` command whose target Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths), such as `rm -rf ~`. For what that `allow` does in plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode).
2020
2121**2. Deny rules**
2222
23If a deny rule from `disallowed_tools` or [settings.json](https://code.claude.com/docs/en/settings-reference.md#permission-settings) matches, the call is denied and [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/user-input) isn't called, even in [`bypassPermissions`](#bypass-permissions-mode-bypasspermissions) mode and even when a hook returned `allow`.
23If a deny rule from `disallowed_tools` or from a [settings file the SDK loads](#rules-in-settings-files) matches, the call is denied and [`canUseTool`](https://code.claude.com/docs/en/agent-sdk/user-input) isn't called. The call is denied this way even in [`bypassPermissions`](#bypass-permissions-mode-bypasspermissions) mode and when a hook returned `allow`.
2424
2525In the TypeScript SDK, if you set the `permission_policy` of a [custom tool](https://code.claude.com/docs/en/agent-sdk/custom-tools.md#require-approval-for-specific-tools) to [`always_deny`](https://code.claude.com/docs/en/agent-sdk/typescript#mcpservertoolpolicy), a call to that tool is denied at this step.
2626
from line 28
2828
2929Check `ask` rules from [settings.json](https://code.claude.com/docs/en/settings-reference.md#permission-settings). If an ask rule matches, the call falls through to your [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input) for confirmation, even in `bypassPermissions` mode.
3030
31Tools that require user interaction behave the same way: `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool) always fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode never prompts. The MCP annotation requires Claude Code v2.1.199 or later.
31Tools that require user interaction behave the same way. `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool) fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode turns each prompt into a denial. The MCP annotation requires Claude Code v2.1.199 or later.
3232
3333[claude.ai connector](https://code.claude.com/docs/en/mcp.md#organization-controls-on-connector-tools) tools your organization has set to `ask` also leave the flow at this step. Every call falls through to the callback, even in `bypassPermissions` mode and even when an allow rule matches. The callback receives the reason `Your organization requires approval for this tool`. In `dontAsk` mode the call is denied instead, because that mode never prompts.
3434
from line 38
3838
3939Apply the active [permission mode](#permission-modes):
4040
41* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) and Bash commands flagged [`Dangerous rm operation not ruled out`](https://code.claude.com/docs/en/permission-modes#dangerous-rm-operation-not-ruled-out), which fall through instead.
42 * To run those removals with no prompt, see [Turn off the critical-path removal prompt](https://code.claude.com/docs/en/permission-modes.md#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode).
41* In `bypassPermissions` mode, Claude Code approves each call that reaches this step unless it's one of the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves). For which of those actions go to your `canUseTool` callback, see [Bypass permissions mode](#bypass-permissions-mode-bypasspermissions).
4342* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).
44* In `plan` mode, Claude Code sends file-edit tools to your `canUseTool` callback regardless of allow rules.
45* In other modes, the request falls through.
43* In `plan` mode, some calls reach your callback, and when auto mode is available, others go to its classifier instead. For more information, see [Plan mode](#plan-mode-plan).
44* In `default` and `dontAsk` mode, the call goes on to the allow rules.
45* For `auto` mode, see [Auto mode](#auto-mode-auto).
4646
4747**5. Allow rules**
4848
from line 87
8787
8888Allow rules accept tool-name globs only after a literal `mcp__<server>__` prefix. The server segment must be glob-free so the rule names a specific server you configured: `mcp__puppeteer__*` matches every tool from the `puppeteer` server, and `mcp__github__get_*` matches its `get_` tools. An unanchored entry like `allowed_tools=["*"]` or `allowed_tools=["mcp__*"]` is ignored and doesn't auto-approve anything.
8989
90Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`; a `Write(path)` rule is never matched by the file permission checks.
91
92Use `//path` for an absolute filesystem path: a deny rule of `Edit(//secrets/**)` blocks writes anywhere under `/secrets` on disk. With a single leading slash, `Edit(/secrets/**)` anchors at the rule's source instead. For rules passed through `allowed_tools` or `disallowed_tools`, that means the session's working directory, so the rule doesn't block `/secrets` on disk. See [Read and Edit rules](https://code.claude.com/docs/en/permissions.md#read-and-edit) for the four anchor forms and how rules from settings files resolve.
93
9490> [!WARNING]
9591>
9692> **Auto-approved tools never reach `canUseTool`.** A tool call approved at any earlier step, by `acceptEdits` or `bypassPermissions`, or by an allow rule, skips your `canUseTool` callback, so permission checks you put there are silently bypassed for that tool.
from line 97
10197>
10298> * Custom tools your application marks [`always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools): decide the call in the callback. To stop these calls arriving, [change the policy mid-session](https://code.claude.com/docs/en/agent-sdk/typescript.md#mcpsdkserverconfigwithinstance). In `auto`, `plan`, and `bypassPermissions` mode the call can instead be approved before the callback, in the cases listed under [Permission modes that can approve an `always_ask` call](https://code.claude.com/docs/en/agent-sdk/typescript#permission-modes-that-can-approve-an-always_ask-call)
10399>
104> * Recognized `rm` and `rmdir` [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths): in `default`, `acceptEdits`, and `bypassPermissions` mode, allow or deny the removal in the callback, where [`decisionReason`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool) starts with `Dangerous rm`. For `auto` and `plan` mode, see [Critical-path removals in each permission mode](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode). The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths)
100> * Recognized `rm` and `rmdir` [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths): in `default`, `acceptEdits`, and `bypassPermissions` mode, allow or deny the removal in the callback, where [`decisionReason`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool) starts with `Dangerous rm`. For `auto` and `plan` mode, see [Critical-path removals in each permission mode](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode)
105101>
106102> * **Bare name**: an entry like `Read` or `mcp__github__get_issue` auto-approves every call to that tool apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths).
107103>
108> * **Scoped rule**: an entry like `Bash(npm test *)` auto-approves only matching calls, and other `Bash` calls that need approval still fall through to the callback.
104> * **Scoped rule**: an entry like `Bash(npm test *)` auto-approves calls that match it, and other `Bash` calls that need approval fall through to the permission mode.
109105>
110> For checks that must run on every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.
106> To check calls that an allow rule, `acceptEdits`, or `bypassPermissions` approves, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks), which runs for those calls too. A hook deny applies even in `bypassPermissions` mode.
111107
112108For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`:
113109
from line 120
124120
125121> [!WARNING]
126122>
127> **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` pre-approves the tools you list. Other unlisted tools are not matched by any allow rule and fall through to the permission mode, where `bypassPermissions` approves them. Setting `allowed_tools=["Read"]` alongside `permission_mode="bypassPermissions"` still approves every tool, including `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`.
123> **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` pre-approves the tools you list. In `bypassPermissions` mode, Claude Code approves a call to an unlisted tool unless it's one of the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves).
124>
125> If you set `allowed_tools=["Read"]` with `permission_mode="bypassPermissions"`, Claude Code still approves calls to tools such as `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`. For the calls that still reach your `canUseTool` callback in this mode, see [Bypass permissions mode](#bypass-permissions-mode-bypasspermissions).
128126
129127You can also configure allow, deny, and ask rules declaratively in `.claude/settings.json`. These rules are read when the `project` setting source is enabled, which it is for default `query()` options. If you set `setting_sources` (TypeScript: `settingSources`) explicitly, include `"project"` for them to apply. See [Permission settings](https://code.claude.com/docs/en/settings-reference.md#permission-settings) for the rule syntax.
130128
129For when allow rules in a project's `.claude/settings.json` apply, see [Project allow rules and workspace trust](https://code.claude.com/docs/en/permissions.md#project-allow-rules-and-workspace-trust).
130
131### Path patterns in rules
132
133Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`, so write a path rule for any of them as `Edit(path)`. If you write a path rule as `Write(path)` or `NotebookEdit(path)`, it [matches no call](https://code.claude.com/docs/en/permissions.md#path-rules-that-never-match) and has no effect.
134
135In `allowed_tools` and `disallowed_tools`, start a path pattern with `//` for an absolute path, or with a single `/` for a path inside the session's working directory:
136
137* **`//path`**: with a deny rule of `Edit(//secrets/**)`, Claude Code blocks writes under `/secrets` on disk from Claude's file tools and from [Bash commands such as `tee` and `> file` redirection](https://code.claude.com/docs/en/permissions#what-read-and-edit-rules-cover). A script that Claude runs and that opens files itself can still write under `/secrets`. For enforcement by the operating system, see [Configure the sandboxed Bash tool](https://code.claude.com/docs/en/sandboxing.md).
138* **`/path`**: `Edit(/secrets/**)` matches the `secrets` directory inside the working directory.
139
140For other ways to start a path pattern, see [Read and Edit rules](https://code.claude.com/docs/en/permissions.md#read-and-edit).
141
131142## Permission modes
132143
133144Permission modes provide global control over how Claude uses tools. You can set the permission mode when calling `query()` or change it dynamically during streaming sessions.
from line 153
142153| :- | :- | :- |
143154| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |
144155| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Calls approved by `allowed_tools` or `settings.json` allow rules run, and so do calls that need no approval in `default` mode. Some calls, such as [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), are denied even when `allowed_tools` or an allow rule matches them. For the list, see [Don't ask mode](#don’t-ask-mode-dontask) |
145| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |
156| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) inside your [working directories](https://code.claude.com/docs/en/permissions.md#working-directories) are automatically approved |
146157| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and, outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools). Use with caution |
147| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |
158| `plan` | Planning mode | Claude explores and plans. Edits made with Claude's file tools go to your `canUseTool` callback even when an allow rule matches them |
148159| `auto` | Model-classified approvals | A model classifier reviews actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order |
149160
150161> [!WARNING]
from line 274
263274
264275**Auto-approved operations:**
265276
266* File edits (Edit, Write tools)
277* File edits with the Edit, Write, and NotebookEdit tools
267278* Filesystem commands: `mkdir`, `touch`, `rm`, `rmdir`, `mv`, `cp`, `sed`
268279
269Both apply only to paths inside the working directory or `additionalDirectories`. In `acceptEdits` mode, Claude Code doesn't auto-approve the request when Claude:
280Both apply to paths inside the working directory or a directory you add. In Python, add one with `add_dirs`, and in TypeScript with `additionalDirectories`. In `acceptEdits` mode, Claude Code doesn't auto-approve the request when Claude:
270281
271282* Works on a path outside that scope
272* Writes to a protected path
283* Writes to a [protected path](https://code.claude.com/docs/en/permission-modes.md#protected-paths)
273284* Removes a path that Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths) with `rm` or `rmdir`
274285* Runs [`touch`](https://code.claude.com/docs/en/permission-modes#auto-approve-file-edits-with-acceptedits-mode) with, for example, an option, a glob, or a `timeout 5` or `LANG=C` prefix
275286
from line 300
289300
290301If your `PreToolUse` hook returns `allow` for a recognized critical-path removal, a read from a network path, or a call to a tool marked `always_ask`, the call is still denied. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).
291302
292**Use when:** you want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent.
303**Use when:** you run a headless agent and want a hard deny for each call that would otherwise prompt.
293304
294305#### Bypass permissions mode (`bypassPermissions`)
295306
from line 310
299310>
300311> Use with extreme caution. Claude has full system access in this mode. Only use in controlled environments where you trust all possible operations.
301312>
302> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:
313> `allowed_tools` doesn't constrain this mode, and calls to tools you didn't list are approved too. These controls still apply:
303314>
304315> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.
305> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths), and you can [turn off the critical-path removal prompt](https://code.claude.com/docs/en/permission-modes.md#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode). Outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), calls to custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) fall through to the callback too.
316> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths), and Bash commands flagged [`Dangerous rm operation not ruled out`](https://code.claude.com/docs/en/permission-modes#dangerous-rm-operation-not-ruled-out) still fall through to your `canUseTool` callback. The check that recognizes critical-path removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths), and you can [turn off the critical-path removal prompt](https://code.claude.com/docs/en/permission-modes.md#turn-off-the-critical-path-removal-prompt-in-bypasspermissions-mode). Outside a [cloud session](https://code.claude.com/docs/en/claude-code-on-the-web.md), calls to custom tools your application [marks `always_ask`](https://code.claude.com/docs/en/agent-sdk/custom-tools#require-approval-for-specific-tools) fall through to the callback too.
306317> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.
307318
308319#### Plan mode (`plan`)
309320
310Claude explores the codebase and produces a plan without editing your source files. File edits are never auto-approved in plan mode, even when an allow rule matches or a `PreToolUse` hook returns `allow`. They prompt through your `canUseTool` callback instead.
321Claude explores the codebase and produces a plan. During planning, edits made with Claude's file tools outside [protected paths](https://code.claude.com/docs/en/permission-modes.md#protected-paths) reach your `canUseTool` callback, even when an allow rule matches or a `PreToolUse` hook returns `allow`. [`AskUserQuestion`](https://code.claude.com/docs/en/agent-sdk/user-input#handle-clarifying-questions) calls reach your callback too, even when an allow rule names the tool.
311322
312While auto mode is available to the session, commands Claude runs during planning don't reach your callback by default, because the classifier model that [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) uses [reviews them instead](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode). With that review on, the classifier can also approve read-only calls that would otherwise reach your callback, such as a `WebFetch` call with no allow rule.
323When [auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) is available, Claude Code sends these calls during planning to [auto mode's classifier](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode) for review instead of to your callback, when no allow rule approves them:
313324
325* Shell commands
326* Web fetches
327* Web searches
328* Calls to MCP tools that their server marks read-only
329
330This review is on by default. To turn it off, set [`useAutoModeDuringPlan`](https://code.claude.com/docs/en/settings-reference#useautomodeduringplan) to `false` in the `settings` option you pass to `query()`, or in your user settings. While the review is off, web searches and calls to MCP tools marked read-only reach your callback.
331
332For shell commands and web fetches, the table shows whether each call reaches your callback:
333
334| Call during planning | Review on | Review off, or auto mode not available |
335| :- | :- | :- |
336| A [read-only](https://code.claude.com/docs/en/permissions.md#read-only-commands) shell command, such as `ls` | Runs without reaching your callback | Runs without reaching your callback |
337| Any other shell command that no allow rule approves, except a [critical-path removal](https://code.claude.com/docs/en/permission-modes.md#critical-paths) | Goes to the classifier, which approves or refuses it without your callback | Reaches your callback |
338| A `WebFetch` call to a [preapproved documentation domain](https://code.claude.com/docs/en/tools-reference.md#webfetch-tool-behavior) | Runs without reaching your callback | Runs without reaching your callback |
339| Any other `WebFetch` call that no allow rule approves | Goes to the classifier, which approves or refuses it without your callback | Reaches your callback |
340
341For what happens after the classifier refuses several calls in a row, see [Repeated-block thresholds](https://code.claude.com/docs/en/permission-modes.md#repeated-block-thresholds).
342
314343> [!NOTE]
315344>
316345> In the TypeScript SDK, if you set `allowDangerouslySkipPermissions: true` alongside `permissionMode: 'plan'`, file edits still reach your `canUseTool` callback. To switch a session that starts in plan mode to `bypassPermissions` later with `setPermissionMode()`, you need `allowDangerouslySkipPermissions` set from the start.
317346
318Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for handling these prompts.
319
320**Use when:** you want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made.
347**Use when:** you want Claude to produce a plan first, such as during code review or before a large change.
321348
322349#### Auto mode (`auto`)
323350
No line in this hunk matches that.