Rules / CFG006
CFG006 permissions.deny is absent or empty
Severity: warn
OWASP: LLM03:2026 – Excessive Agency
What cfgaudit checks
cfgaudit flags any settings.json that defines a permissions block without a non-empty deny list. Without explicit denials, no rule blocks destructive operations such as rm -rf, git push --force, or arbitrary network calls — even when an allow entry is narrowly scoped, an unrelated default-allowed tool (or a future broadening of the allow list) can still reach them.
A denylist is the only mechanism that survives well-intentioned allow-list expansion, so it acts as a defense-in-depth guardrail rather than a primary control.
A deny list that is present in the file but not in force counts as absent. If the file carries a top-level value whose type the schema rejects, Claude Code discards the whole file (see CFG012), so its deny entries never load; CFG006 then fires and names the key responsible. The same applies to settings.local.json, which normally inherits the project deny list: when the project settings.json is discarded, there is nothing to inherit.
Trigger example
{
"permissions": {
"allow": ["Bash(make *)"]
}
}
Safe alternative
{
"permissions": {
"allow": ["Bash(make *)"],
"deny": [
"Bash(rm *)",
"Bash(git push --force*)",
"Bash(curl *)",
"Bash(wget *)"
]
}
}
References
Documentation for cfgaudit 1.18.1. Source of this page · Rule implementation