Chapter 01 · Section V · 12 min read
1.5 Permissions: modes, tool approval, working dirs
The permission surface controls what runs without asking, what prompts, and what is denied outright. The right settings save you from clicking; the wrong ones save you from disasters.
Every tool call goes through the permission system before it runs. Learning where the knobs are — modes, allowlists, denylists, working-directory scope — is what turns “constant approval popups” into “auto-approve the safe stuff, prompt for the interesting stuff.”
Permission modes
Set globally via --permission-mode, or per-session via /config:
default— the “prompt on tool use” behaviour, minus what your allowlist auto-approves. Sane starting point.acceptEdits— auto-approve Read/Write/Edit; still prompt for Bash and any tool with side effects.plan— Claude produces a plan; nothing executes. Great for planning.bypassPermissions— no prompts. Only use in a hermetic container.
The allow / deny lists
In settings.json:
{
"permissions": {
"allow": [
"Read",
"Grep",
"Glob",
"Bash(npm run test:*)",
"Bash(git status)",
"Bash(git diff*)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(git reset --hard*)"
]
}
}
Precedence: deny beats allow beats mode. A denied pattern will not run even if the mode is bypassPermissions. That is the property to lean on: your denylist is the last-line guardrail.
Bash allowlist patterns are shell globs, matched against the exact command Claude proposes. Bash(npm run test:*) matches npm run test:unit and npm run test:e2e but not npm test.
Working directories
The session’s workspace is scoped to the launch directory plus any --add-dir you passed. Every file tool resolves against that scope; shell commands run inside it.
Adding a directory expands what Claude can see and act on. Removing one requires a session restart. If you find yourself constantly typing --add-dir, it might be worth configuring in ~/.claude/settings.json:
{
"additionalDirectories": ["/Users/you/shared-utils"]
}
Interaction with tool approvals
When Claude proposes a tool call, three things determine what happens:
- Denylist check. If the exact call matches a deny pattern → refused. No prompt.
- Allowlist check. If it matches an allow pattern → auto-approved. No prompt.
- Permission mode. Otherwise, the mode decides: prompt in
default, auto-approve inacceptEdits(for file tools), etc.
This composability is what lets you set a permissive mode for productivity without losing the guardrails.
Check your understanding
Quick check
—