Claude Code permission rules that are accepted and then ignored
The awkward part of permission rules is that a wrong one is still valid JSON.
When a line in permissions.allow is not taking effect, the settings file
cannot tell you whether it is broken or working as designed.
Collected here are the cases the official documentation states outright — as ignored, as skipped, or as a startup warning. Nothing is inferred.
The list
| What you write | What happens |
|---|---|
"*" / "B*" / "mcp__*" in allow |
Skipped, auto-approves nothing. Warns |
A path rule on Write / NotebookEdit / Glob / MultiEdit |
Accepted but never consulted. Warns at startup |
A parameter rule on a tool's own content field, e.g. Bash(command:...) |
Ignored. Warns at startup |
An mcp__ rule with parentheses, e.g. mcp__memory(read) |
Skipped at load. Listed in the startup dialog and claude doctor |
An allow rule with a * before the rest of the command, e.g. Bash(git * main) |
Applies, but allows far more than it names. Warns at startup |
None of these is an error. The file loads and that one line is dead.
Each one
Unanchored allow globs
Deny and ask rules accept a glob in the tool-name position. Allow rules do not.
An allow rule may use a glob only after a literal mcp__<server>__ prefix.
// applies
"mcp__puppeteer__*"
"mcp__github__get_*"
// skipped, auto-approves nothing
"*"
"B*"
"mcp__*"
The server segment must be glob-free, so the rule names a server you configured.
Tools that never consult a path rule
File path rules apply to Read(...) and Edit(...).
Written for Write, NotebookEdit, Glob, or the legacy MultiEdit, the rule
is accepted and then never consulted.
Parameter rules on a tool's own content field
Tool(param:value) works in deny and ask rules for a top-level input parameter.
It does not work for the field that is the tool's content.
| Tool | Its content field |
|---|---|
Bash / PowerShell |
command |
Read / Edit / Write |
file_path |
Grep / Glob |
path |
NotebookEdit |
notebook_path |
WebFetch |
url |
Bash(command:rm *) would be bypassable with a compound command, so it is
ignored on purpose.
// ignored
"Bash(command:rm *)"
"Read(file_path:./.env)"
// write this instead
"Bash(rm *)"
"Read(./.env)"
"WebFetch(domain:example.com)"
mcp__ rules with parentheses
When a settings file is loaded, any mcp__ rule containing parentheses is
skipped.
To gate an MCP tool by parameter, use the CLI's --disallowedTools rather than
a settings file.
A skipped rule is listed in the invalid-settings dialog at the start of an
interactive session, and in claude doctor.
A wildcard before the rest of the command
A * stands in for whatever text is in its place, so the earlier it sits,
the wider the rule.
| What you write | What it actually allows |
|---|---|
Bash(git log *) |
commands beginning git log |
Bash(git * main) |
every git subcommand, git push origin main included |
Bash(* --version) |
every program |
Bash(git * main) covers -c, which makes git run a program you name.
Related: :* only works at the end
Bash(ls:*) is the same rule as Bash(ls *) — but only as a suffix.
In Bash(git:* push) the colon is a literal character, and the rule matches
no git command at all.
Whitespace changes the meaning
The space before a trailing * is part of the rule.
| What you write | Matches | Doesn't match |
|---|---|---|
Bash(ls *) |
ls -la, ls |
lsof |
Bash(ls*) |
ls -la, lsof |
Bash(ls *) matches bare ls only because the trailing * is the rule's
only wildcard.
Checking it
All five are mechanically detectable.
npx @quintetkit/ccheck
warn .claude/settings.json:14
`Bash(command:rm *)` is ignored. `command` is Bash's own content field and
cannot be matched as a parameter. Write `Bash(rm *)` instead.
why: https://code.claude.com/docs/en/permissions
Every finding cites its source. A rule that cannot be cited is not written.
Whether a deny or ask rule names a real tool is deliberately not checked.
The documentation says an unknown tool name warns at startup, and deciding that
needs the current list of tools. A checker can only hold a snapshot, so it would
warn on every tool released after it.
Source
https://code.claude.com/docs/en/permissions
Based on a snapshot taken 2026-09-04.
The workflow itself is available
Quartet, the four-persona version, is published free under MIT. Quintet adds a UI Designer persona, review criteria, a per-Issue parallel execution script, and a 10-chapter guide.
See the free version Product page