Session-level permission caching bypasses allow list for Bash commands when sandbox mode is enabled

Resolved 💬 5 comments Opened Mar 28, 2026 by janeriklysander Closed May 2, 2026

Bug Description

When sandbox mode is enabled, approving a Bash command that is not in the permissions.allow list causes the approval to be cached for the remainder of the session. Subsequent invocations of matching commands execute without prompting, even though they were never pre-approved.

This worked correctly before enabling sandbox mode — every invocation prompted as expected.

Steps to Reproduce

  1. Enable sandbox mode in ~/.claude/settings.json ("sandbox": { "enabled": true, ... })
  2. Configure Bash(git commit *) to be absent from both permissions.allow and permissions.deny
  3. Start a new session
  4. Use a skill/command that triggers git commit — Claude Code correctly prompts for approval
  5. Approve the commit
  6. Later in the same session, Claude invokes git commit again (different context, different files)
  7. Expected: Claude Code prompts for approval again
  8. Actual: The commit executes without prompting

Environment

  • Claude Code version: 2.1.86
  • OS: Linux (WSL2) 5.15.167.4-microsoft-standard-WSL2
  • Shell: bash

Settings Context

{
  "sandbox": {
    "enabled": true,
    "filesystem": {
      "allowWrite": ["/tmp", "~/.local/share/pnpm", "~/.npm", "~/.yarn", "~/.bun/install"],
      "denyRead": ["~/.ssh", "~/.gnupg", "~/.aws/credentials"],
      "denyWrite": ["~/.ssh", "~/.gnupg", "~/.bashrc", "~/.zshrc", "~/.profile"]
    },
    "network": {
      "allowedDomains": ["github.com"],
      "allowUnixSockets": ["~/.ssh/agent.sock"]
    }
  },
  "permissions": {
    "allow": [
      "Bash(git status:*)",
      "Bash(git add:*)",
      "Bash(git push:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)"
    ],
    "deny": [
      "Bash(*&& git commit*)",
      "Bash(*; git commit*)",
      "Bash(*| git commit*)"
    ]
  }
}

Note: Bash(git commit *) is intentionally not in the allow list. The deny list only covered chained variants. Despite this, after a single approval during a /commit skill invocation, all subsequent standalone git commit calls in the session were auto-approved.

Session Transcript Evidence

Inspecting the session JSONL, all three git commit tool results show permissionBehavior: NONE — no permission prompt was triggered for any of them, including the second and third commits which were invoked outside the original /commit skill context.

Impact

This is a permission escalation within a session. Users configure allow/deny lists to maintain control over destructive or irreversible operations. A one-time approval for a specific commit should not blanket-approve all future commits in the session.

Suspected Cause

The sandbox execution path may cache command approvals differently than the standard Bash permission system. Before sandbox mode was enabled, the same configuration correctly prompted for every git commit invocation.

Workaround

Adding Bash(*git commit*) to permissions.deny hard-blocks all commit commands, but this silently denies rather than prompting — overly restrictive for users who want case-by-case approval.

Expected Behavior

Commands not in permissions.allow should prompt for approval every time, regardless of prior approvals in the same session. Sandbox mode should not alter this behavior.

View original on GitHub ↗

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