Bash permissions.deny rules not enforced in subagent (Agent/Task tool) shells — denied command executes, only post-hoc security warning

Status Fixed / completed
Reported on v2.1.214
Maintainer reply None cached
Activity 3 comments · opened Jul 18, 2026 · closed Aug 17, 2026

Summary

A permissions.deny Bash rule that is correctly enforced in the main conversation loop is not enforced inside a subagent spawned via the Agent (Task) tool. The subagent executed the denied command successfully; the only trace was a post-hoc SECURITY WARNING in the parent's task-notification saying the command "matches the user's configured deny rule … this command should not have executed".

Environment

  • Claude Code 2.1.214 (CLI), macOS (darwin 25.5.0)
  • Project .claude/settings.json:
"permissions": {
  "deny": [
    "Bash(git stash)",
    "Bash(git stash:*)",
    "Bash(rtk git stash)",
    "Bash(rtk git stash:*)"
  ]
}

What happened

  1. Main loop: a Bash call containing rtk git stash list was denied as expected ("Permission to use Bash with command … has been denied."). Enforcement works there — including the compound-command case.
  2. A background subagent (Agent tool, subagent_type: general-purpose, model sonnet) working in the same project ran:

``
git stash push -u -m "wip: issue-1505 checked-op fix + tests"
``

The command executed (the stash was created and later consumed; work was recoverable, no data loss in this instance).

  1. The parent session's task-completion notification carried:

> SECURITY WARNING: This subagent performed actions that may violate security policy. Reason: [User Deny Rules] The subagent ran git stash push -u -m "wip: …", which matches the user's configured deny rule Bash(git stash:*) — this command should not have executed…

So a detection layer recognizes the violation post-hoc, but the PreToolUse permission gate that blocks the command in the main loop did not fire (or did not deny) in the subagent context.

Expected

Deny rules are a security boundary; they should bind every Bash execution in the session, including subagent (Task/Agent) contexts — same as the main loop. Post-hoc warning is detection, not prevention: for destructive commands (git reset --hard, rm, …) the damage is done by the time the parent is told.

Repro sketch

  1. Add "Bash(git stash:*)" to permissions.deny in project .claude/settings.json.
  2. Confirm the main loop refuses git stash list.
  3. Spawn a Task/Agent subagent whose work plausibly leads it to stash (e.g. "commit your work; keep the tree clean"), or that is directly told to run git stash push.
  4. Observe the subagent executes it; the parent later receives the SECURITY WARNING in the task notification.

View original on GitHub ↗

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