How do I configure Claude Code permissions so dangerous tools need approval?
Configure Claude Code so dangerous tools need approval: Manual mode, permissions.ask/deny, and managed disableBypassPermissionsMode.
To make dangerous Claude Code tools need approval: run in Manual mode (default), add permissions.ask (and deny) rules for high-risk patterns such as Bash(git push *) or Bash(rm *), and optionally set managed disableBypassPermissionsMode: "disable". Content-scoped ask rules still prompt in auto mode before the classifier. Leaving auto entirely is a companion Spec; why prompts fire on readonly/git-shaped actions is another Spec.
Shift+Tab / defaultMode: "default") + permissions.ask / deny. Org lock bypass → disableBypassPermissionsMode: "disable". Optional org lock for auto → disableAutoMode: "disable". Bash rules match written command text, not an OS security boundary. Checked docs + CHANGELOG 2.1.281 on 2026-09-24. Primary Labs seed: claude code permissions (720 / KD 10).Pick a permission mode that expects approval
| Mode (config) | UI label | Without asking | For this JTBD |
|---|---|---|---|
default | Manual | Reads only | Primary: you approve edits, shell, network |
acceptEdits | Edit automatically | Reads + in-dir edits + common fs cmds | Fewer edit prompts: not a full dangerous-tool gate |
plan | Plan | Explore; classifier may review cmds when available | Plan before edit |
auto | Auto | Everything with classifier checks | Hands-off: classifier ≠ your ask rules |
dontAsk | Don’t ask | Pre-approved only; would-prompt → denied | Locked CI |
bypassPermissions | Bypass | Everything (isolated env only) | Opposite of this Spec |
Switch mid-session: CLI/JetBrains Shift+Tab, VS Code mode indicator, Desktop mode selector. Persist Manual:
claude --permission-mode default
Or in user settings (~/.claude/settings.json):
{
"permissions": {
"defaultMode": "default"
}
}
manual is an alias for default from v2.1.200+. Project .claude/settings.json / .claude/settings.local.json: starting auto and bypassPermissions do not take effect. Full leave-auto steps (Shift+Tab essay, org disableAutoMode walkthrough) live on the auto-mode Spec: bridge only here.
Force approval with ask / deny rules
Open /permissions to view and edit rules and see which settings.json each rule comes from. Rules evaluate deny → ask → allow; first match wins. An allow rule cannot carve an exception out of a deny.
| Lever | Effect |
|---|---|
permissions.ask | Always prompt when matched: primary answer for dangerous tools |
permissions.deny | Never run (stronger than ask) |
permissions.allow | Skip prompt when matched: pre-approve safe tools only |
Example pattern for approval on push/rm while hard-blocking force-push:
{
"permissions": {
"defaultMode": "default",
"ask": [
"Bash(git push *)",
"Bash(gh pr create *)",
"Bash(rm *)"
],
"deny": [
"Bash(git push --force *)"
]
}
}
In auto mode, content-scoped ask rules (for example Bash(git push *)) still force a prompt before the classifier. You can stay in auto for routine work and still gate named danger. MCP tools use mcp__server / mcp__server__tool forms the same way.
Honest limit (docs, “What a Bash rule doesn’t match”): Bash rules match the command text Claude writes after split/wrappers, not an OS security boundary. Bash(rm *) stops rm -rf build/ but not /bin/rm … or bash -c 'rm …'. Pair with sandboxing and/or PreToolUse hooks when the restriction must hold. Why some readonly/git prompts still appear: readonly-git Spec.
Org locks + dangerous-rm notes (2.1.281)
{
"permissions": {
"disableBypassPermissionsMode": "disable"
}
}
Blocks bypass / --dangerously-skip-permissions. Works from any scope; typically managed. Optional: "disableAutoMode": "disable" removes auto from the cycle; --permission-mode auto starts Manual instead.
Docs Critical paths: rm / rmdir targeting a critical path are never auto-approved via an allow rule or a PreToolUse "allow"; mode decides ask / classifier / deny. Even bypassPermissions still asks on those removals.
CHANGELOG 2.1.281 (HEAD 2026-09-24): Desktop/gateway desktop policy keys include disableBypassPermissionsMode. Recursive rm whose target is only command-substitution output (e.g. rm -rf "$(pwd)") now asks even with a Bash allow in auto / --dangerously-skip-permissions. Dangerous-rm prompt there waits 2 minutes, then denies with a rewrite hint; the check also flags shell-variable + top-level dir cases. Shift+Tab double-press no longer lands on the wrong mode. Opt-out envs exist in CHANGELOG (not the default recommendation). Do not treat CLAUDE_CODE_AUTO_MODE_SERVER as approval config (classifier routing: auto-mode Spec).
Pitfalls
- Using bypass /
--dangerously-skip-permissionsfor “more control”: that removes prompts (isolated envs only). - Expecting project
defaultMode: "auto"/ bypass to stick as starting mode. - Thinking
Bash(rm *)covers/usr/bin/rmor nestedbash -c. - Treating this Spec as the leave-auto or why-readonly-git essay: link those instead.
- Teaching
CLAUDE_CODE_AUTO_MODE_SERVER=0as approval config.
Ops neighbor (link only): parallel agents.
FAQ
What’s the fastest way to require approval for most tools?
Manual mode: Shift+Tab to Manual, or "defaultMode": "default" in ~/.claude/settings.json / claude --permission-mode default.
Can I stay in auto but still approve git push?
Yes. Add Bash(git push *) under permissions.ask. Ask evaluates before the classifier.
How do I block bypass permissions for the org?
Set "permissions": { "disableBypassPermissionsMode": "disable" } (typically in managed settings).
Is this the same as stopping auto mode?
No. This Spec configures modes + ask/deny so dangerous tools need approval. Leaving auto for routine confirmation: stop auto mode Spec.
Why does Claude still ask on some git/read actions?
Rules, mode, and tool type interact (including built-in readonly sets and regressions fixed in later versions). See why readonly/git prompts.
Sources
Checked 2026-09-24.
- Choose a permission mode: modes table; Manual/
default; Shift+Tab;defaultMode;disableAutoMode; critical paths; ask-before-classifier - Configure permissions: ask/deny/allow; evaluation order deny→ask→allow; Bash honesty limits;
disableBypassPermissionsMode - CHANGELOG: ## 2.1.281 (disableBypassPermissionsMode desktop/gateway keys; substitution-target
rmprompt; 2-min dangerous-rm timeout; Shift+Tab double-press) - Supporting: Settings · live bridges: leave auto · readonly git
