Permissions & Safety
After this lesson, you will be able to:
- Pick the right permission mode — `auto`, `acceptEdits`, `plan`, `dontAsk`, `bypassPermissions` — for any workflow
- Write a Bash allowlist that auto-approves safe commands without leaving security holes
- Understand what `--dangerously-skip-permissions` actually does and when it's appropriate (rarely)
- Recognize the four safety failure modes and the patterns that prevent each
Before You Start
#The Five Permission Modes
| Mode | Behavior | When to Use |
|---|---|---|
auto (default) | AI classifier decides; prompts on uncertainty | Most interactive sessions |
acceptEdits | Auto-approve all edit tool calls; prompt on Bash | Trusted refactors, you'll review the diff |
plan | Read-only, no edits or commands | Planning + analysis without changes |
dontAsk | Only run pre-approved (allowlist) commands | Strict workflows, CI, prod environments |
bypassPermissions | All tool calls auto-approved | DANGEROUS — automated scripts only |
Set the mode at session start:
claude --permission-mode acceptEdits # Trust me, I'll review edits
claude --permission-mode plan # Just plan, don't touch anything
claude --permission-mode dontAsk # Strict allowlist only
Or change mid-session:
> /mode acceptEdits
#The Allowlist / Denylist System
{
"permissions": {
"allow": [
"Bash(npm run *)", // any npm run X
"Bash(git status)", // exact match
"Bash(git diff *)", // any git diff variant
"Bash(pytest *)",
"Bash(python -m pytest *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(sudo *)",
"Bash(curl * | sh)",
"Bash(curl * | bash)",
"Bash(wget -O- * | sh)"
]
}
}
Pattern semantics
- Exact:
Bash(git status)— only matchesgit statusexactly - Wildcard:
Bash(npm run *)— matchesnpm run lint,npm run build, etc. - Path-scoped:
Bash(rm /tmp/*)— only matches rm in /tmp
What auto Mode Actually Does
auto permission mode runs an AI classifier on every Bash command. The classifier categorizes:- Safe: read operations, status checks, commands that don't modify state → auto-approved
- Risky: anything that modifies state → prompts user
- Dangerous: matches
denypatterns or known-bad signatures → blocked outright
auto is the safest default. For speed, layer an explicit allowlist on top — exact matches skip the classifier.The --dangerously-skip-permissions Flag
Sometimes called "YOLO mode". This flag bypasses permission prompts entirely — Claude can run any tool call without confirmation.
When this is appropriate
- ✅ Automated CI/CD with vetted prompts and a contained environment (Docker container, sandbox)
- ✅ Personal scripts where you've reviewed exactly what Claude will do
When this is NOT appropriate
- ❌ Interactive use on your laptop with sudo access
- ❌ Production systems
- ❌ When you don't fully trust the prompt source
The 2026 hardening: even with this flag, Claude Code REFUSES to touch:
.claude/(config directory).git/(git internals).vscode/(editor config)node_modules/(deletion)- System paths (
/etc,/usr/bin, etc.)
#Bash Injection Hardening
rm -rf if the LLM emitted a malformed Bash command.2026 fix: Claude Code now validates Bash commands at multiple layers:
- Pattern matching against the allow/deny lists (your settings.json)
- Lint check for shell-injection signatures (
$( … )substitutions, backticks, suspicious redirects) - AI classifier in
automode
--dangerously-skip-permissions, the lint layer is enforced.#Four Safety Failure Modes
#Hands-On
Tests · Verify deny rules block destructive commands. Verify allow rules skip prompts. Verify unknown commands trigger the prompt in auto mode.
#Key Takeaways
- Five permission modes. Pick
autofor interactive,acceptEditsfor trusted refactors,planfor analysis-only,dontAskfor strict workflows, neverbypassPermissionsinteractively - Allowlist common safe commands to skip prompts — npm, pytest, git status are obvious starters
- Denylist destructive patterns explicitly: rm -rf, sudo, curl-piped-to-shell. Do not trust the AI classifier alone
--dangerously-skip-permissionsis for automated CI/CD only. Never interactively- 2026 hardening: protected paths (
.claude/,.git/, system dirs) are always safe regardless of mode
#Quick Check
You're refactoring a 50-file change and tired of approving each Edit call. Best mode?
Which command line is appropriate for a long, trusted refactor on a feature branch you've already reviewed the plan for?