Permissions: Stop Clicking 'Allow' on Everything
Permission fatigue is the number two complaint about Claude Code. Five minutes of config fixes it permanently. Here's exactly what to set and why.
Five clicks before anything actually happens.
That's what default Claude Code feels like. You ask it to fix a test. It wants to read the file. Allow. Edit the file. Allow. Run the test. Allow. Check the output. Allow. It's like having an assistant who asks permission before touching anything in the office.
The fix takes five minutes. You configure it once. Then it just works.
With permission rules set, none of those steps stopped to ask. On a default setup, each one waits for your approval first.
Setting up permission rules
The config lives in settings.json. Two places to put it:
Project-level (.claude/settings.json in your repo): gets checked into git, shared with your team. Good for project-specific tools like your test runner or lint commands.
User-level (~/.claude/settings.json): your personal defaults across every project you work on.
Here's a solid starting config:
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(npm test *)",
"Bash(npm run lint *)",
"Bash(npx tsc *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)"
]
}
}Read operations are always safe. Your test and lint commands are safe. Anything that deletes files or pushes to remote: always keep human review on those.
Mind the space before the *. Bash(ls *) matches ls -la but not lsof. Bash(ls*) with no space matches both.
When rules overlap, deny wins, then ask, then allow. A deny rule like Bash(rm -rf *) blocks the command even if a broader allow rule also matches it.
There's a third place for rules too: .claude/settings.local.json applies to one project and stays on your machine, out of git.
The /permissions Command
Mid-session and tired of clicking? Type /permissions to manage it on the fly.
It opens your allow, ask and deny rules, where you can add or remove a rule without editing settings.json by hand.
What to Auto-Accept vs What to Always Review
Always auto-accept:
Read: reading files literally never changes anythingGlob: searching file names, harmlessGrep: searching file contents, harmlessBash(git status *),Bash(git diff *),Bash(git log *): read-only git commands
Auto-accept with patterns (mostly safe):
Bash(npm test *): running your testsBash(npm run lint *): running lintersBash(npx tsc *): type checkingEdit: once you've used Claude Code for a week and trust the edit quality, most people add this
Always review:
Bash(rm *): file deletionBash(git push *): pushing to remoteBash(git checkout *): branch switchingBash(git reset *): resetting changesBash(npm publish *): publishing packagesBash(curl *): making network requests- Anything touching production
The Progressive Trust Approach
Don't try to configure everything perfectly on day one. You don't yet know what Claude Code actually does in your workflow.
Week 1: Auto-accept reads only. Watch what it actually does before each operation.
Week 2: Add test and lint commands to auto-accept. You've seen enough by now to know it's not running weird shell commands.
Week 3: Add Edit if you're confident in the edit quality. Most people get here.
Week 4+: You're reviewing only destructive operations and network calls. That's the sweet spot: 90% of operations flow without interruption, 10% get a human eye where it matters.
{
"permissions": {
"allow": ["Read", "Glob", "Grep", "Edit", "Bash(npm test *)", "Bash(npm run lint *)"],
"ask": ["Bash(git push *)", "Bash(rm *)", "Bash(curl *)", "WebFetch"]
}
}Auto mode, plan mode and headless runs
Rules decide single tool calls. The permission mode decides what happens when no rule matches. Five recent changes are worth knowing:
- Headless runs start in Manual mode. Since v2.1.302, every
claude -pand Agent SDK run with no permission mode set starts in Manual mode, which settings and SDK options calldefault. Before that, runs on a third-party provider or with telemetry off started in auto. In Manual mode nobody is there to click Allow, so a call that needs approval is denied unless an allow rule, a hook, acanUseToolcallback or--permission-prompt-toolapproves it. For a script or cron job, pass--allowedTools "Bash(npm test)"for the calls you expect, or--permission-mode autoto let the classifier decide. - You can pick the classifier model.
CLAUDE_CODE_AUTO_MODE_MODEL(v2.1.302) sets the model the client-side auto mode classifier uses. It doesn't change the model for server-side auto mode. - Long conversations no longer lock auto mode. With the server-side classifier, a conversation too long for the safety check is now compacted (v2.1.302). Before, every checked tool call was denied.
- Plan mode warns you once when it won't ask. If bypass permissions is available, plan mode won't ask before most edits or commands, and since v2.1.299 Claude Code tells you so the first time.
- Bypass mode still stops
rmon critical paths, unless you switch that off. Even inbypassPermissionsmode,rmandrmdiraimed at a critical path such as your home folder get a prompt, and no allow rule or PreToolUse hook can approve them. In the desktop app and VS Code the command is denied at once with a hint to rewrite it (v2.1.309). Since v2.1.311 you can turn the prompt off by starting Claude Code withCLAUDE_CODE_EVEN_MORE_DANGEROUSLY_SKIP_PERMISSIONS=1set in your shell. It only works from the launch environment: Claude Code ignores it in a settings file'senvblock, and in the desktop app or the VS Code chat panel it has no effect. With it on, a command likerm -rf ~can run without asking, so keep it to throwaway containers and VMs.
One More Thing: The Accept Button
When a permission prompt does appear, you've got more options than just yes:
- Yes: allow this once
- Yes, and don't ask again: allow it and save a rule, so Claude Code stops asking for this command in this project
- No: deny this request
- Escape: cancel the current operation
"Don't ask again" is underused. For a shell command, Claude Code writes the rule to .claude/settings.local.json, so you build your allow list just by working. Check that file now and then to see what you've approved.
New guides, when they ship
One email, roughly weekly. CLAUDE.md templates, workflows I actually use, and the cut-for-length stuff that does not make the public guides. One-click unsubscribe.
Or read Product Field Notes, the Substack
