Claude Code controls tool use — editing files, running commands, accessing the web — through permission rules. You decide what runs automatically, what asks for confirmation each time, and what is blocked outright, using settings.json and permission modes. This guide covers the three rule types and their evaluation order, the configuration file levels, and the permission modes, based on the official documentation. (As of June 2026. Details may change, so check the official permissions docs for the latest.)
Three permission rules
Permissions live in the permissions object of settings.json, split into three lists.
- allow — uses the tool automatically, without confirmation. Cuts down on repeated approvals.
- ask — prompts for confirmation whenever the tool is about to be used.
- deny — blocks the tool. The strongest rule.
Run /permissions in the terminal to see every active rule and which settings.json each one comes from.
Evaluation order — deny, then ask, then allow
Rules are always evaluated in the order deny -> ask -> allow, and the first match decides the outcome. Rule specificity does not change this order. For example, if an ask rule matches a command, it prompts first even when a more specific allow rule also matches. And a deny rule blocks the tool even in bypass mode.
Rule format and wildcards
Rules take the form Tool (the whole tool) or Tool(specifier) (a scoped pattern). The * wildcard is supported.
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(git status)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.*)", "Bash(rm -rf *)"]
}
}
One important difference: a deny entry with just a tool name (e.g. Bash) removes the tool from Claude’s context entirely, so Claude never sees it. A scoped entry (e.g. Bash(rm *)) keeps the tool available and blocks only matching calls. MCP tools use a double-underscore format with no parentheses. New to MCP? See how to connect MCP.
Settings have levels
Settings can live at several levels, not just one. The main ones are the user level ~/.claude/settings.json (applies to every project), the project level .claude/settings.json (commit it to the repo to share with the team), and org-enforced managed (enterprise) settings. A managed deny cannot be undone by users, which makes it useful for enforcing a team-wide safety boundary. Exact precedence rules can vary by version, so check the official docs. A clean split is to use CLAUDE.md for what to build and settings.json for how to operate.
Permission modes
Use defaultMode to set the baseline behavior. The default mode prompts for anything not allowed, acceptEdits auto-approves plain file edits, and plan mode proposes a plan without making changes. bypassPermissions (the CLI --dangerously-skip-permissions, often called “YOLO mode”) skips all prompts. This bypass mode is safe only in isolated environments — containers, VMs, ephemeral CI runners — where the environment itself provides the safety boundary. Note that deny rules still block in bypass mode, and sensitive paths such as .git/ and .claude/ are protected with a prompt even there.
Safe defaults
- Protect secret files with deny — e.g.
Read(./.env),Read(./.env.*), SSH key paths. - Put hard-to-undo commands in deny — e.g.
Bash(rm -rf *), force push. - Move safe, repeatedly-approved commands (tests, lint) into allow so they do not break your flow.
- Use bypass mode only in isolated environments. For day-to-day work, prefer default mode or acceptEdits.
- Sandboxing is a complementary layer, separate from permissions. When building automation, you can insert checks before and after tool runs with hooks.
New to Claude Code? Start with what Claude Code is and the install guide for the full picture.
The options and behaviors here reflect the official documentation as of June 2026 and may change by version. For details such as mode names, file precedence, and sandbox setup, check the official permissions docs. This site is not an official Anthropic site.