Permission Strategies
Permission File Location
~/.claude/settings.json # Global defaults
.claude/settings.local.json # Project-specific (gitignored)Permission Structure
json
{
"permissions": {
"allow": [],
"deny": [],
"ask": [],
"defaultMode": "ask"
}
}Default Modes
| Mode | Behavior |
|---|---|
"ask" | Prompt for everything not in allow/deny |
"acceptEdits" | Auto-approve file edits, ask for bash |
"full" | Trust fully (use with caution) |
Permission Pattern Syntax
Tool(command:args)
Tool(pattern:*) # WildcardExamples:
json
"Bash(npm install:*)" // Any npm install
"Bash(git status:*)" // Git status only
"Read(./.env)" // Specific file
"Read(**/*.md)" // Glob patternRecommended Configuration
json
{
"permissions": {
"allow": [
"Edit",
"Write",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(npm:*)",
"Bash(pnpm:*)",
"Bash(pip:*)",
"Bash(pytest:*)",
"Bash(ls:*)"
],
"deny": [
"Bash(rm -rf:*)",
"Bash(rm -r:*)",
"Bash(sudo:*)",
"Bash(git push --force:*)",
"Bash(git reset --hard:*)",
"Read(./.env)",
"Read(./.env.*)",
"Read(~/.ssh/**)"
],
"ask": [
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(docker:*)",
"Bash(rm:*)"
],
"defaultMode": "acceptEdits"
}
}Permission Categories
Safe to Allow
json
[
"Edit",
"Write",
"Bash(git status:*)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(npm:*)",
"Bash(pip:*)",
"Bash(ls:*)",
"Bash(cat:*)"
]Always Deny
json
[
"Bash(rm -rf:*)",
"Bash(rm -r:*)",
"Bash(sudo:*)",
"Bash(git push --force:*)",
"Bash(git reset --hard:*)",
"Read(./.env)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)"
]Should Ask
json
[
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(docker:*)",
"Bash(rm:*)"
]Best Practices
- Start restrictive — Add permissions as needed
- Deny secrets — Never auto-allow reading sensitive files
- Ask for git writes — Review commits before they happen
- Use wildcards carefully —
Bash(*)is very permissive - Gitignore local settings — Keep
.claude/settings.local.jsonout of repo