Claude Code settings.json permissions, explained.
Claude Code decides whether to run a tool call from a list of permission rules in its settings files. Understanding three things stops most surprises: how a rule is written, in which order rules are checked, and which settings file wins.
The three rule lists
- allow: the call runs without asking.
- ask: Claude Code stops and asks you each time.
- deny: the call is refused.
Rules live under permissions in a settings file. Each rule names a tool, and optionally a pattern in brackets.
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm run test *)",
"Bash(npm run lint)",
"Bash(git diff *)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Bash(git push --force *)",
"Read(./.env)",
"Read(./.env.*)",
"Edit(migrations/**)"
]
}
}
Order matters: deny, then ask, then allow
Rules are checked in that order and the first match decides. Specificity does not change it, so a narrow allow rule cannot carve an exception out of a broader deny. In the example above, git push origin main prompts you, while git push --force origin main is denied because the deny list is checked first. A deny in any settings file beats an allow in any other file.
Writing the patterns
- Bash:
Bash(npm run test *)matches the command text. A trailing*(space, then star) also matches the bare command, and the space matters:Bash(ls *)does not matchlsof. - Read and Edit: gitignore-style paths.
Read(./.env)blocks the file tools from reading that file;Edit(migrations/**)covers writes. Edit rules cover the write tools, so write oneEditrule rather than separate Write ones. - WebFetch:
WebFetch(domain:example.com). A star prefix covers subdomains. - MCP:
mcp__servername__toolname, or the server name alone for every tool on it.
Which file wins
Highest precedence first: managed settings from an organisation, command-line settings, .claude/settings.local.json, .claude/settings.json, then ~/.claude/settings.json. List settings such as permissions.allow merge across files rather than replace each other. Allow rules in a committed project file only apply after the person who cloned it accepts the workspace trust prompt; deny and ask rules apply straight away. Choosing "Yes, and don't ask again" on a prompt writes an allow rule to the local file, which is where surprise allows come from.
The permission mode
defaultMode sets how a session starts. The documented values include default (prompts on first use of each tool), acceptEdits, plan, auto, dontAsk and bypassPermissions. Be deliberate with the last one: it skips most prompts. Run /permissions in a session and /status to see what actually loaded.
Where Bash rules stop
- They match text, not intent. A rule for
git push *does not matchgit -C . pushor a command wrapped insh -c. Rules that try to constrain arguments, such as limitingcurlto one URL, are fragile. - Chains are split. An allow rule for one command does not approve
that-command && something-else; each part has to match. - Read rules cover the file tools. A shell command that reads a file is judged by your Bash rules, so protect secrets with Bash rules or a sandbox as well.
For the few operations that must never run, add a PreToolUse hook, which can check the command however you like. CommonRig's shell guard covers the same ground for both Claude Code and Codex and is described in stopping destructive git commands.
Check your own files
Paste your CLAUDE.md or AGENTS.md into the free footprint scorer, or get the free sample and run rig doctor --lite locally. The hosted doctor check is A$0.50 a run and scores the whole setup, hooks included. The kit (A$10 once) has the rule source, generator, hooks and protocols these guides describe.
More guides
- CLAUDE.md best practices and a template
- AGENTS.md example, and AGENTS.md vs CLAUDE.md
- Claude Code hooks examples: block dangerous git, enforce rules
- One rule set for Claude Code and Codex
- Briefing subagents: an orchestration template
- Agent ignores CLAUDE.md? Your file may be too long
- Codex AGENTS.md hierarchy, overrides and size cap
- Claude Code skills vs rules: when a skill wins
- Parallel agents with git worktrees, safely
- Stop AI agents running destructive git commands
- Measure and cut agent context cost (token footprint)