Configure what Claude Code is allowed to do: restrict shell commands, limit file access, set up per-project permissions, and use allowedTools in CLI mode.
Claude Code uses a tiered permission system to control what tools Claude can invoke. Understanding the layers lets you run sessions that are both safe and friction-free.
| Method | Scope | Syntax |
|---|---|---|
| Interactive prompt | Single tool call (y/n) | Runtime dialog |
--allowedTools CLI flag | One session | claude --allowedTools "Read,Grep,Bash(git:*)" |
.claude/settings.json | Project (all sessions) | JSON config |
~/.claude/settings.json | Global (all projects) | JSON config |
// .claude/settings.json
{
"permissions": {
"allow": [
"Read",
"Grep",
"Glob",
"Bash(git status)",
"Bash(git diff*)",
"Bash(git log*)",
"Bash(npm run *)",
"Bash(pytest *)",
"Edit",
"Write"
],
"deny": [
"Bash(rm -rf*)",
"Bash(curl*)",
"Bash(wget*)"
]
}
}
# Allow a specific tool (all uses):
"Read"
# Allow Bash with a prefix filter (glob):
"Bash(git *)" # any git command
"Bash(npm run *)" # npm run only (not npm install)
"Bash(pytest*)" # any pytest invocation
# Allow specific file patterns for Edit:
"Edit(src/**)" # edits inside src/ only
# Deny takes precedence over allow:
# If a command matches both allow and deny, it is denied.
# Only allow non-mutating tools:
claude --allowedTools "Read,Grep,Glob,Bash(git log*),Bash(git diff*),Bash(git status)"
# Or via CLI flag shorthand for a one-liner audit:
claude --print "Summarize the authentication system" --allowedTools "Read,Grep,Glob"
# settings.json for a CI context — allow tests + read, deny all writes:
{
"permissions": {
"allow": [
"Read", "Grep", "Glob",
"Bash(pytest *)",
"Bash(npm test)",
"Bash(go test *)"
],
"deny": ["Edit", "Write", "Bash(git commit*)", "Bash(git push*)"]
}
}
// .claude/settings.json
{
"permissions": {
"allow": ["Edit"]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "if echo "$CLAUDE_TOOL_INPUT_FILE_PATH" | grep -qE '\.(env|pem|key)$|secrets/|credentials'; then echo 'Blocked: sensitive file' >&2; exit 2; fi"
}
]
}
]
}
}
# Resolution order (highest to lowest priority):
# 1. CLI flags (--allowedTools, --dangerouslySkipPermissions)
# 2. .claude/settings.json (project-level)
# 3. ~/.claude/settings.json (user global)
# 4. Built-in defaults (prompt for anything not listed)
# Tip: put team-wide permissions in .claude/settings.json (commit it).
# Put personal preferences in ~/.claude/settings.json (don't commit).
For hook-based blocking patterns (blocking individual file paths, blocking specific commands), see Claude Code hooks tutorial. For a complete command reference, see Claude Code slash commands.