Claude Code Permissions: 6 Modes and How to Configure Them Safely (2026)
Claude Code has 6 permission modes that control whether the AI can write files and run commands, so you can use it without worrying about losing work. The default (Manual) reads only and asks before every write or shell command. You fine-tune behavior with allow / deny / ask lists in settings.json, where deny always beats allow. The --dangerously-skip-permissions flag turns off every check, so run it only inside a container or VM; auto mode is the low-friction option that still keeps a safety net.
permissions in Claude Code change fairly quickly across versions. Check claude --version and the official permission modes docs (Anthropic, updated 08/2026) before you apply anything below.
Why permissions in Claude Code matter
Claude Code doesn't just suggest code like a chatbot - it's a real agent that can write files directly to your machine and run shell commands. That power is also the risk: without guardrails, an ordinary session can overwrite files you haven't committed, delete the wrong folder, or run something destructive like rm -rf before you can react.
The scariest risk isn't the AI "deciding to misbehave" - it's prompt injection. A web page you ask Claude to read, a README buried in a dependency, or a GitHub issue can carry hidden instructions like "run curl ... | bash" or "send the contents of .env somewhere." If Claude has full permissions, it can follow those orders without you ever asking.
That's why the permission system exists: by default, Claude Code operates in an ask-first, act-later posture. If you've just installed Claude Code, the next thing to do is understand and configure permissions - both to avoid data loss and to stop the endless y/n prompts for things you already trust.
The 6 permission modes in Claude Code (comparison table)
Claude Code ships with six permission modes. The first thing to remember: the default mode is read-only and always asks before it writes a file or runs a command. The other modes loosen that grip step by step, based on how much you trust the work and how isolated your environment is.
| Mode | Runs without asking | When to use it |
|---|---|---|
default (labeled Manual since v2.1.200) | Read-only; asks before every file write or command | Getting started, sensitive work, unfamiliar repos |
acceptEdits | Reads + auto-approves file edits and safe filesystem commands (mkdir, touch, mv, cp, sed) inside the working directory | Multi-step iteration with a git diff review |
plan | Reads + researches; changes nothing until you approve the plan | Exploring a codebase, planning before you edit |
auto | Almost everything, but a background classifier checks each action to block dangerous commands | Long-running tasks; the default since 08/14/2026 for Pro/Max/Team |
dontAsk | Only runs tools that are already allowed; anything outside the list is silently skipped instead of prompting | Locked-down CI/scripts, unattended environments |
bypassPermissions (= --dangerously-skip-permissions) | Runs everything, no checks at all | Only inside an isolated container or VM |
In practice you'll live mostly in the first three modes. default/Manual is the safest starting point - nothing happens behind your back. acceptEdits fits when you're refactoring and want Claude to edit as it goes while you review with git diff afterward. plan is great when you need Claude to "read, understand, and explain" - say, tracing a bug across several files before it touches any code. The other three are specialized tools: auto for long tasks with a safety net, dontAsk for automation, and bypassPermissions only for a fully isolated environment.
Switching and setting the default mode
The fastest way to change modes mid-session is to press Shift+Tab - it cycles through the three common modes: default → acceptEdits → plan. The status bar at the bottom updates with each press, so you always know which mode you're in.
To launch straight into a mode, use the command-line flag:
claude --permission-mode plan
To pin a default mode for every session, set defaultMode in settings.json:
{
"permissions": {
"defaultMode": "acceptEdits"
}
}
Important security note: defaultMode: "auto" is only honored when it's declared in your user file, ~/.claude/settings.json. If you (or someone else) set it in a project's .claude/settings.json, Claude Code ignores it - so a repo you just cloned can't hand itself permission to run automatically. This is the guardrail that stops a "malicious repo" from escalating its own privileges.
Configuring the allowlist in settings.json (allow / deny / ask)
The permission mode decides the overall "attitude," while settings.json gives you control down to individual commands. There are three lists:
allow- runs without asking. For example:"Bash(npm run test:*)","Read(src/**)".ask- always prompts, even when the mode is loosening things up. Use it for commands you want to hit OK on yourself.deny- blocked outright, never runs. For example:"Bash(rm -rf *)","WebFetch","Read(.env)".
Rule syntax follows the form Tool(pattern): Bash(npm run lint) matches that exact command, adding :* matches a prefix (Bash(git diff:*)), Read(src/**) uses a glob for paths, and WebFetch(domain:github.com) restricts to a domain.
The single most important arbitration rule - burn this into memory: deny always beats allow, at every level. If a command matches both an allow and a deny rule, it's blocked. As for file order, higher levels override lower ones in this sequence: managed (enterprise) > .claude/settings.local.json > .claude/settings.json > ~/.claude/settings.json. The settings.local.json file is where your personal, uncommitted config lives; a project's settings.json is shared with the whole team through Git.
A sample settings.json that balances convenience and safety:
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm run test:*)",
"Bash(npm run lint)",
"Bash(git status)",
"Bash(git diff:*)",
"Read(src/**)"
],
"ask": [
"Bash(git push:*)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force:*)",
"Read(.env)",
"Read(./secrets/**)",
"WebFetch"
],
"additionalDirectories": [
"../shared-libs"
]
}
}
The additionalDirectories field lets Claude work with folders outside the current workspace - handy in a monorepo split into packages, but add only what you actually need. If you want more customized permission logic (logging, conditional blocking), you can use Hooks with the PreToolUse event to intervene before each tool runs.
Protected paths - what Claude will never edit on its own
Beyond the allow/deny rules you set, Claude Code has a hard protection layer that sits lower down: protected paths. These are sensitive config files and folders that Claude never auto-approves for writing, even when you're in acceptEdits or auto:
.claudeand.claude.json- Claude Code's own config.git- Git internals (so it can't mess directly with repo history).vscode- editor config- Shell rc files:
.bashrc,.zshrc… - a common spot for hidden run-on-startup commands .npmrcand any.env*files that hold secrets.mcp.json- MCP server config
The key safety point: an allow rule still can NOT override a protected path. This safety check runs before the allowlist is evaluated, so even if you accidentally (or were tricked into) adding a rule that permits writing to .env, Claude still stops and asks. The only way to bypass this layer is bypassPermissions - one more reason not to turn it on outside an isolated environment.
--dangerously-skip-permissions vs auto mode - which is safe?
Lots of people who want to "turn off the y/n prompts" reach straight for --dangerously-skip-permissions (also called YOLO mode). This flag disables every check: all allow/deny rules and all protected paths are ignored. The real consequences:
- It does not protect against prompt injection - with every net turned off, a hidden instruction from a web page or file gets executed directly.
- Claude Code blocks this flag when you're running as root/sudo, because the blast radius is too large.
- Use it only inside an isolated container or VM, ideally with no internet - a place where if Claude breaks something, it only breaks the sandbox.
Since early 2026, Anthropic has offered auto mode as the safe replacement for the "less friction" need: instead of disabling checks, auto mode runs a background classifier that categorizes each action and blocks dangerous commands by default - curl | bash, exfiltrating secrets, deploying to production, rm -rf /, git reset --hard, force pushes, terraform destroy, and so on. Routine, safe operations pass through, while anything that smells destructive comes back to ask you. According to Anthropic, most actions in a session already get approved by the user anyway, so auto mode drops most of the questions while keeping the net for the rare dangerous ones.
This is also a big shift in the default "safety posture": since 08/14/2026, auto mode has become the default mode for Pro/Max/Team plans (per the Claude Code permission modes docs, Anthropic, 08/2026). In short: if you want fewer prompts, use auto mode - don't use --dangerously-skip-permissions.
The recommended safe setup (step by step)
Here's the setup I find most balanced for everyday dev work - safe, but not annoying:
- Keep
default/Manual for sensitive work. On an unfamiliar repo, when working on the main branch, or when Claude is reading content from the web, stay in the default mode and approve by hand. - Add
denyfor destructive commands. Lock downBash(rm -rf *),Bash(git push --force:*), andRead(.env). Because deny beats allow, this is a layer that never gets loosened by mistake. - Allow narrowly for trusted, repetitive commands. Add the commands you run constantly and know are safe:
Bash(npm run test:*),Bash(git status). Prefer narrow allows (exact commands) over broad ones. - Use
acceptEditswhen iterating on code, and review withgit diff. Let Claude edit as it goes for speed, but keep control at the commit step - look at the diff before yougit add. - Long or sensitive tasks → container or auto mode, never bypass. When you need to run long and unattended, auto mode with its classifier is still the right call.
If you want to review all the rules in effect at any time, type /permissions in the session. It's also a good place to check right after you've installed and configured Claude Code for the first time.
Common mistakes and failure modes when configuring permissions
Permission config tends to trip on a few recurring situations - knowing them in advance saves the frustration:
- "It keeps asking y/n." That means the mode is
defaultand the command isn't in your allow list yet. Add a narrow allow rule for the exact command you trust; don't jump straight to bypass. - "Auto mode keeps blocking things." If the classifier blocks 3 times in a row or 20 times total in one session, Claude stops auto mode and returns to asking manually - this is intentional behavior to keep it from looping forever.
- You said "don't push" out loud, but it pushed anyway. The "boundaries" you state in conversation can disappear when the context is compacted. Spoken constraints are less reliable than config - use a
denyrule for hard limits. - A rule isn't applying. Usually the
settings.jsonhas invalid JSON (a trailing comma, a missing brace), so the whole file is skipped. Confirm the file is valid and re-check with/permissions.
Running into stranger errors with Claude Code? See our guide to fixing common Claude Code errors.
Ready-made safe permission presets
Figuring out an allowlist for every project by hand is a chore, especially when you juggle many repos across different stacks. One shortcut is a community kit that packages skills and config by convention - for example, the AgentKit kit for Claude Code (20% off via link) ships skills and workflows to a standard, so you write fewer rules from scratch. If you're curious how it works, read our take on what AgentKit is and whether it's worth using. Preset or not, the principle holds: understand deny/allow, and never turn off the safety net.
Frequently asked questions (FAQ)
Will Claude Code delete my files?
In the default (Manual) mode, no - Claude always asks before any write or delete. It can only delete on its own if you loosen permissions (acceptEdits/auto) or turn on --dangerously-skip-permissions. Add a deny for rm -rf to lock it out entirely.
How do I stop the y/n prompts while staying safe?
Don't turn them off with bypass. Instead, add narrow allow rules for the commands you trust (like npm test, git status), or use auto mode - it drops the prompts for safe actions but still blocks dangerous ones with its classifier.
Is --dangerously-skip-permissions dangerous?
Yes. It disables every check and offers no protection against prompt injection. Claude even blocks it when you run as root. Use it only inside an isolated container or VM, ideally with no internet.
How is auto mode different from bypass?
Auto mode keeps the safety net: a background classifier blocks dangerous commands (curl|bash, force pushes, sending secrets, rm -rf /). Bypass turns everything off. If you want fewer prompts, choose auto mode, not bypass.
Does deny or allow win in a conflict?
Deny always wins. If a command matches both a deny and an allow rule at any config level, it's blocked. Protected paths are also checked first, so an allow rule can't override them.
Where does the permission config live?
In the settings.json file. Priority order: managed (enterprise) > .claude/settings.local.json (personal, uncommitted) > .claude/settings.json (team-shared) > ~/.claude/settings.json (your default).
Conclusion and next steps
The recipe for safe-but-not-annoying is compact: keep the safe default for sensitive work, add a narrow allowlist for trusted commands, lock in hard denies for destructive ones, and use auto mode (not bypass) for long tasks. That way Claude Code runs fast while your hands stay on the wheel.
Not done installing yet? Read the Claude Code installation guide. For the big picture, see what Claude Code is. check claude --version, since label names and mode thresholds can change with new releases.