SD-018 — settings.json Broad Allow with Protective Deny
SD-018 flags a settings.json deny entry that a wildcard allow entry already covers, which shows the allowlist is wider than the deny beside it suggests it was meant to be.
What it matches
In supported Claude settings, a Bash or PowerShell deny subcommand covered by a broader wildcard allow. Current Claude Code deny precedence still blocks it; the pair reveals an overbroad allow.
Why it matters
Current Claude Code applies deny over allow, so the deny still blocks the matched command; the pair is not a demonstrated bypass. It shows that the allow entry grants a wider command family and relies on version-sensitive deny handling to carve one member back out.
Example
json
{"permissions": {
"allow": ["Bash(git *)"],
"deny": ["Bash(git push *)"]
}}The allow grants every git subcommand; the deny names back only one of them.
How to fix it
Express the restriction in the allowlist: list the subcommands the agent may run instead of granting the whole command and denying one. Keep a deny only as defence in depth for something the allowlist already excludes — a deny that carves a hole out of a wildcard is hiding how wide that wildcard is.
Known false positives
A deny kept deliberately as defense in depth.
Standards mapping
Prevalence
Pattern SD-018 was detected in 0 of 16996 public skills scanned as of 27 October 2026.
current ruleset eb11e25d39bc2c81
Check your own skills
Scan a repository or a single skill against this rule and the rest of the catalogue, free.