Permissions and modes
Permission rules, allow/ask/deny precedence, modes, Bash/Read/Edit/WebFetch/MCP patterns, and enforcement boundaries.
Claude Code's permission system controls commands, file edits, path access, and tools. CLAUDE.md provides guidance; permission rules provide enforcement.
#Default safety model
| Tool category | Examples | Confirmation by default |
|---|---|---|
| Read-only tools | Read, Grep, Glob, read-only shell | Usually not required |
| Bash commands | npm test, git push, scripts | Required |
| File changes | Edit, Write, NotebookEdit | Required |
“Yes, don't ask again” saves a rule in the project context or settings. Bash approvals are usually associated with the project and command; automatic file-edit approval often lasts only for the current session.
#Rule order
Three rule types:
- allow: run without asking again.
- ask: require confirmation.
- deny: prohibit the operation.
Evaluation order is fixed:
- deny
- ask
- allow
A more specific allow rule cannot override a deny. To allow only selected commands by default, use dontAsk with allow entries rather than a blanket deny plus exceptions.
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Read(./en/docs/**)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}#Permission modes
| Mode | Behavior | Use |
|---|---|---|
| default | Ask when needed | Everyday default |
| acceptEdits | Automatically accept file edits and common filesystem operations | Personal projects with Git recovery |
| plan | Read-oriented planning without source edits | Research before major changes |
| auto | Automatic mode with background safety classification | Research preview; use deliberately |
| dontAsk | Deny tools without pre-approval | Restricted CI or scripts |
| bypassPermissions | Skip most permission prompts | Isolated containers or VMs |
Start from the CLI:
claude --permission-mode plan
claude --permission-mode acceptEditsUse Shift+Tab or /permissions to adjust the mode in-session.
Bypass mode skips many prompts for sensitive directories such as .git, .claude, .vscode, and .husky. Reserve it for isolated or recoverable environments.
Modes determine whether a tool can run. Filesystem, network, and credential isolation after execution requires sandboxing. See Enterprise administration for centralized policy.
#Rule syntax
Tool
Tool(specifier)| Rule | Matches |
|---|---|
Bash | All Bash calls |
Bash(npm run build) | Exact command |
Bash(npm run *) | Matching command prefix |
Read(./.env) | Current-directory .env access |
Edit(/src/**) | src under the settings source directory |
WebFetch(domain:example.com) | Specified domain |
mcp__github__get_* | GitHub MCP get tools |
#Bash rules
Bash supports wildcard matching. Each subcommand in a compound command must independently pass permission checks.
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(* --version)"
],
"deny": [
"Bash(git push *)",
"Bash(rm -rf *)"
]
}
}Bash(ls *) differs from Bash(ls*): the former requires a word boundary after ls, while the latter can also match lsof.
Some read-only commands, including ls, cat, pwd, grep, find, wc, and read-only Git operations, may be treated as safe. Add ask or deny if you want those checked too.
#Read/Edit path patterns
| Pattern | Anchor | Example |
|---|---|---|
//path | Absolute filesystem path | Read(//home/alex/secrets/**) |
~/path | User home | Read(~/.zshrc) |
/path | Settings source directory | Edit(/src/**) |
path or ./path | Current working directory | Read(./.env) |
In user settings, Read(/secrets/) refers to ~/.claude/secrets/, not every project's secrets directory. Use // or ~/ for the appropriate cross-project scope.
#WebFetch and networking
{
"permissions": {
"allow": [
"WebFetch(domain:docs.example.com)",
"WebFetch(domain:*.example.com)"
],
"deny": [
"Bash(curl *)",
"Bash(wget *)"
]
}
}Restricting WebFetch does not restrict all network access. An allowed Bash process can still use curl or scripts. Combine command rules, hooks, or an OS sandbox for strict boundaries.
#MCP rules
{
"permissions": {
"allow": [
"mcp__github__get_*"
],
"ask": [
"mcp__database__write_*"
],
"deny": [
"mcp__*"
]
}
}A blanket mcp__* deny removes all MCP tools, including ones matched by allow entries. Claude will not see those tools.
#Suggested configurations
#Personal development
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run typecheck)",
"Bash(git status)",
"Bash(git diff *)"
],
"deny": [
"Read(//**/.env)",
"Read(//**/.env.*)"
]
}
}#Team repository
{
"permissions": {
"ask": [
"Bash(git push *)",
"Bash(npm publish *)"
],
"deny": [
"Read(./production/**)",
"Edit(./production/**)"
]
}
}#Official references
Support
Need help?
For setup, billing, or model issues, email us. Check the status page for uptime.
WeChat / QQ support is available at the bottom right.

