[DOCS] In settings to deny rules override allow rules or the other way round?

Resolved 💬 7 comments Opened Nov 15, 2025 by xpluscal Closed Feb 28, 2026

Documentation Type

Unclear/confusing documentation

Documentation Location

https://code.claude.com/docs/en/settings#permission-settings

Section/Topic

Permission Settings

Current Documentation

allow | Array of permission rules to allow tool use. Note: Bash rules use prefix matching, not regex | [ "Bash(git diff:*)" ]
-- | -- | --
ask | Array of permission rules to ask for confirmation upon tool use. | [ "Bash(git push:*)" ]
deny | Array of permission rules to deny tool use. Use this to also exclude sensitive files from Claude Code access. Note: Bash patterns are prefix matches and can be bypassed (see Bash permission limitations) | [ "WebFetch", "Bash(curl:)", "Read(./.env)", "Read(./secrets/*)" ]

allow Array of permission rules to allow tool use. Note: Bash rules use prefix matching, not regex [ "Bash(git diff:*)" ]
ask Array of permission rules to ask for confirmation upon tool use. [ "Bash(git push:*)" ]
deny Array of permission rules to deny tool use. Use this to also exclude sensitive files from Claude Code access. Note: Bash patterns are prefix matches and can be bypassed (see Bash permission limitations) [ "WebFetch", "Bash(curl:)", "Read(./.env)", "Read(./secrets/*)" ]

What's Wrong or Missing?

From the docs it is unclear if allow rules precede deny rules or not.

Example:

{
  "permissions": {
    "allow": [
      "Bash(ls:*)",
      "Bash(pwd)"
    ],
    "deny": [
      "Bash(*)"
    ]
  }
}

Which one here takes precedence?
Thanks!

Suggested Improvement

Be clear as to how allow vs deny works.

Impact

High - Prevents users from using a feature

Additional Context

This has significant impact on security posture and using claude code / the agent sdk in production.

View original on GitHub ↗

This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗