Permissions ↗
yesEditorial Notes
Permissions are critical for production deployments where agents interact with external systems or sensitive data. Focus on the least-privilege principle: grant only the capabilities an agent actually needs, and be especially careful with tool permissions that allow file system access or network calls. A common pitfall is developing with permissive settings and forgetting to lock them down before deployment, which can expose your system to prompt injection attacks that leverage overly broad tool access. Read this alongside the secure deployment guide for a complete security posture.
Original Documentation
Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules.
The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what’s allowed automatically, and the canUseTool callback to handle everything else at runtime.
This page covers permission modes and rules. To build interactive approval flows where users approve or deny tool requests at runtime, see Handle approvals and user input.
How permissions are evaluated#
When Claude requests a tool, the SDK checks permissions in this order:
Run hooks first, which can allow, deny, or continue to the next step
Check rules defined in settings.json in this order: deny rules first (block regardless of other rules), then allow rules (permit if matched), then ask rules (prompt for approval). These declarative rules let you pre-approve, block, or require approval for specific tools without writing code.
Apply the active permission mode (bypassPermissions, acceptEdits, dontAsk, etc.)
If not resolved by rules or modes, call your canUseTool callback for a decision
This page focuses on permission modes (step 3), the static configuration that controls default behavior. For the other steps:
- Hooks: run custom code to allow, deny, or modify tool requests. See Control execution with hooks.
- Permission rules: configure declarative allow/deny rules in
settings.json. See Permission settings. - canUseTool callback: prompt users for approval at runtime. See Handle approvals and user input.
Permission modes#
Permission 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.
Available modes#
The SDK supports these permission modes:
| Mode | Description | Tool behavior |
|---|---|---|
default | Standard permission behavior | No auto-approvals; unmatched tools trigger your canUseTool callback |
acceptEdits | Auto-accept file edits | File edits and filesystem operations (mkdir, rm, mv, etc.) are automatically approved |
bypassPermissions | Bypass all permission checks | All tools run without permission prompts (use with caution) |
plan | Planning mode | No tool execution; Claude plans without making changes |
Subagent inheritance: When using bypassPermissions, all subagents inherit this mode and it cannot be overridden. Subagents may have different system prompts and less constrained behavior than your main agent. Enabling bypassPermissions grants them full, autonomous system access without any approval prompts.
Set permission mode#
You can set the permission mode once when starting a query, or change it dynamically while the session is active.
Pass permission_mode (Python) or permissionMode (TypeScript) when creating a query. This mode applies for the entire session unless changed dynamically.
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Help me refactor this code",
options=ClaudeAgentOptions(
permission_mode="default", # Set the mode here
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
```
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
for await (const message of query({
prompt: "Help me refactor this code",
options: {
permissionMode: "default" // Set the mode here
}
})) {
if ("result" in message) {
console.log(message.result);
}
}
}
main();
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="During streaming"></span>
Call `set_permission_mode()` (Python) or `setPermissionMode()` (TypeScript) to change the mode mid-session. The new mode takes effect immediately for all subsequent tool requests. This lets you start restrictive and loosen permissions as trust builds, for example switching to `acceptEdits` after reviewing Claude's initial approach.
```python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
q = query(
prompt="Help me refactor this code",
options=ClaudeAgentOptions(
permission_mode="default", # Start in default mode
),
)
# Change mode dynamically mid-session
await q.set_permission_mode("acceptEdits")
# Process messages with the new permission mode
async for message in q:
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
```
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
const q = query({
prompt: "Help me refactor this code",
options: {
permissionMode: "default" // Start in default mode
}
});
// Change mode dynamically mid-session
await q.setPermissionMode("acceptEdits");
// Process messages with the new permission mode
for await (const message of q) {
if ("result" in message) {
console.log(message.result);
}
}
}
main();
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
### Mode details
#### Accept edits mode (`acceptEdits`)
Auto-approves file operations so Claude can edit code without prompting. Other tools (like Bash commands that aren't filesystem operations) still require normal permissions.
**Auto-approved operations:**
- File edits (Edit, Write tools)
- Filesystem commands: `mkdir`, `touch`, `rm`, `mv`, `cp`
**Use when:** you trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory.
#### Bypass permissions mode (`bypassPermissions`)
Auto-approves all tool uses without prompts. Hooks still execute and can block operations if needed.
<span class="callout-start" data-callout-type="warning"></span>
Use with extreme caution. Claude has full system access in this mode. Only use in controlled environments where you trust all possible operations.
<span class="callout-end"></span>
#### Plan mode (`plan`)
Prevents tool execution entirely. Claude can analyze code and create plans but cannot make changes. Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](/docs/en/agent-sdk/user-input#handle-clarifying-questions) for handling these prompts.
**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.
## Related resources
For the other steps in the permission evaluation flow:
- [Handle approvals and user input](/docs/en/agent-sdk/user-input): interactive approval prompts and clarifying questions
- [Hooks guide](/docs/en/agent-sdk/hooks): run custom code at key points in the agent lifecycle
- [Permission rules](https://code.claude.com/docs/en/settings#permission-settings): declarative allow/deny rules in `settings.json`