Skip to content

Is --allowedTools with --permission-mode bypassPermissions behavior expected? #12232

@zvi-cato-prd

Description

@zvi-cato-prd

Is --allowedTools with --permission-mode bypassPermissions behavior expected?

I'm reopening this issue as a question to clarify the expected behavior of --allowedTools, particularly when used with --permission-mode bypassPermissions.

CLI Testing Results

Testing with Claude Code CLI shows inconsistent behavior:

# Test 1: Using --allowedTools with bypassPermissions
❯ claude --verbose -p "get my public ip from curl ifconfig.me" \
  --allowedTools Read \
  --permission-mode bypassPermissions
1.2.3.4
# ❌ UNEXPECTED: Bash tool executed despite whitelist specifying only Read
# Test 2: Using --disallowedTools with bypassPermissions  
❯ claude --verbose -p "get my public ip from curl ifconfig.me" \
  --disallowedTools Bash \
  --permission-mode bypassPermissions
I dont have access to execute bash commands in the current environment. 
Youll need to run `curl ifconfig.me` in your terminal directly.
# ✅ EXPECTED: Bash tool was correctly blocked

Key Observations

  1. --allowedTools appears to be ignored when using --permission-mode bypassPermissions

    • Setting --allowedTools Read did not restrict the toolset to only Read
    • Bash tool was still available and executed successfully
  2. --disallowedTools works correctly with --permission-mode bypassPermissions

    • Setting --disallowedTools Bash properly blocked the Bash tool
    • This proves tool restriction is technically possible

Real-World Use Case: SDK Automation with Tool Restrictions

Scenario: Using Claude Code via SDK in an automated CI/CD pipeline for code analysis

from claude_agent_sdk import ClaudeAgentOptions

# Automated code review agent - should only READ code, never modify
options = ClaudeAgentOptions(
    cwd="/repo",
    allowed_tools=["Read", "Grep", "Glob", "Ls"],  # Whitelist: read-only tools
    permission_mode="bypassPermissions",  # Required: no human to approve prompts
    max_turns=50,
)

Why both are needed:

  • permission_mode="bypassPermissions" - Required because there's no human to click "approve" prompts in CI/CD
  • allowed_tools=[...] - Required to enforce security boundary (read-only, no Bash/Edit/Write)

Without working allowed_tools:

  • Claude could execute Bash(rm -rf *) in automated context
  • Claude could use Edit/Write to modify source code unintentionally
  • Violates Principle of Least Privilege for automated security scanning

Current workaround (doesn't work):

# Attempted workaround using disallowed_tools (blacklist approach)
disallowed_tools=["Bash", "Edit", "Write", "MultiEdit", "NotebookEdit", "TodoWrite", "WebFetch", ...]
# Problems:
# 1. Must enumerate ALL dangerous tools (error-prone)
# 2. New tools added in future versions = new security holes
# 3. Whitelist is security best practice, not blacklist

Questions for Clarification

  1. Is --allowedTools intended to work as a whitelist that restricts available tools to only those specified?

    • Or does it only affect permission prompting behavior?
  2. Should --allowedTools function when combined with --permission-mode bypassPermissions?

    • Current behavior suggests these flags may be conflicting or that allowedTools is ignored in bypass mode
  3. Is there a supported way to restrict the available toolset to a whitelist for security hardening?

    • This is critical for SDK usage in automated environments (CI/CD, agents, security scanning)

Security Context

From a security perspective, the ability to whitelist tools is critical for:

  • Principle of Least Privilege: Only provide the minimum tools needed for a task
  • Read-only environments: Prevent any modifications when only analysis is required
  • Automated/SDK contexts: No human supervision = must enforce tool restrictions programmatically
  • Defense in depth: Blacklists (disallowedTools) miss new tools; whitelists are safer

Currently, --disallowedTools (blacklist) works, but --allowedTools (whitelist) does not appear to function as a tool restriction mechanism when using bypassPermissions.

Documentation Review

According to the CLI reference docs:

  • Both flags are listed without clear explanation of their interaction with permission modes
  • The exact semantics of "allowedTools" vs permission bypassing is unclear

Could the team clarify:

  • The intended behavior of --allowedTools with --permission-mode bypassPermissions?
  • Whether tool whitelisting is supported, and if so, what's the correct approach?
  • If this is a bug, documentation gap, or expected behavior?

Note: This is a pure CLI issue (also affects SDK), not SDK-specific code.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions