Skip to content

Feature: Granular control for bash command auto-approval in tool_approval plugin #114

@wu-changxing

Description

@wu-changxing

Problem

Currently, the tool_approval plugin's auto-approve feature only supports tool-level control. When you add bash to the auto-approve list, it approves all bash commands, including potentially dangerous ones.

# Current limitation - all or nothing
agent = Agent(
    "assistant",
    tools=[bash],
    auto_approve_tools=["bash"]  # ❌ Approves EVERYTHING: ls, rm -rf, git push, etc.
)

This forces users to choose between:

  • Too permissive: Auto-approve all bash commands (dangerous)
  • Too restrictive: Manually approve every single command (annoying)

Desired Feature

Add granular command and parameter control to auto-approval:

# Proposed syntax - granular control
agent = Agent(
    "assistant",
    tools=[bash],
    auto_approve_tools={
        "bash": {
            "commands": ["git status", "git diff", "ls", "pwd"],  # Exact commands
            "patterns": [
                r"^git log",           # Regex patterns
                r"^pytest.*--tb=short", # Allow specific flags
                r"^npm run build"
            ],
            "safe_prefixes": ["git status", "git log", "git diff"],  # Prefix matching
            "blocked_patterns": [r"rm -rf", r"git push.*--force"]    # Explicitly block
        }
    }
)

Use Cases

1. Safe git operations only

auto_approve_tools={
    "bash": {
        "commands": ["git status", "git diff", "git log"],
        "blocked_patterns": [r"git push", r"git reset --hard", r"git clean -f"]
    }
}

2. Read-only file operations

auto_approve_tools={
    "bash": {
        "commands": ["ls", "pwd", "cat", "head", "tail"],
        "patterns": [r"^grep", r"^find.*-name"],
        "blocked_patterns": [r"rm", r"mv", r"cp"]
    }
}

3. Test commands only

auto_approve_tools={
    "bash": {
        "patterns": [
            r"^pytest.*",
            r"^npm test",
            r"^python -m unittest"
        ]
    }
}

4. Directory-restricted operations

auto_approve_tools={
    "bash": {
        "patterns": [r"^cd /safe/path/"],
        "validate": lambda cmd: "/safe/path/" in cmd  # Custom validation
    }
}

Implementation Suggestions

1. Update tool_approval.py auto-approve check

Current code (simplified):

# In tool_approval.py
if tool_name in auto_approve_list:
    return  # Auto-approve

Proposed:

def should_auto_approve(tool_name: str, tool_args: dict, auto_approve_config) -> bool:
    """Check if tool execution should be auto-approved based on granular rules."""
    
    if isinstance(auto_approve_config, list):
        # Backward compatible: simple list of tool names
        return tool_name in auto_approve_config
    
    if isinstance(auto_approve_config, dict):
        if tool_name not in auto_approve_config:
            return False
        
        rules = auto_approve_config[tool_name]
        
        # For bash tool, check command
        if tool_name == "bash":
            command = tool_args.get("command", "")
            
            # Check exact commands
            if "commands" in rules and command in rules["commands"]:
                return True
            
            # Check patterns
            if "patterns" in rules:
                for pattern in rules["patterns"]:
                    if re.match(pattern, command):
                        return True
            
            # Check safe prefixes
            if "safe_prefixes" in rules:
                for prefix in rules["safe_prefixes"]:
                    if command.startswith(prefix):
                        return True
            
            # Check blocked patterns (explicit deny)
            if "blocked_patterns" in rules:
                for pattern in rules["blocked_patterns"]:
                    if re.search(pattern, command):
                        return False
            
            # Custom validation function
            if "validate" in rules and callable(rules["validate"]):
                return rules["validate"](command)
        
        # For other tools, just check if they're in the dict (simple approval)
        return True
    
    return False

2. Backward Compatibility

# Old syntax still works
auto_approve_tools=["bash", "search", "write_file"]

# New syntax is opt-in
auto_approve_tools={
    "bash": {"commands": ["git status"]},
    "search": True,  # Simple approval
    "write_file": {"patterns": [r"^/tmp/.*"]}  # Path restrictions
}

3. Configuration Validation

Add validation to catch typos and invalid patterns:

def validate_auto_approve_config(config):
    """Validate auto_approve_tools configuration."""
    if isinstance(config, dict):
        for tool_name, rules in config.items():
            if isinstance(rules, dict):
                # Validate known keys
                valid_keys = {"commands", "patterns", "safe_prefixes", "blocked_patterns", "validate"}
                unknown_keys = set(rules.keys()) - valid_keys
                if unknown_keys:
                    raise ValueError(f"Unknown auto-approve keys for '{tool_name}': {unknown_keys}")
                
                # Validate regex patterns compile
                for pattern_key in ["patterns", "blocked_patterns"]:
                    if pattern_key in rules:
                        for pattern in rules[pattern_key]:
                            try:
                                re.compile(pattern)
                            except re.error as e:
                                raise ValueError(f"Invalid regex pattern '{pattern}': {e}")

Benefits

Safety: Only approve specific safe commands
Convenience: Auto-approve common read-only operations
Flexibility: Regex patterns for complex matching
Backward compatible: Existing code keeps working
Explicit blocklist: Prevent dangerous operations even with broad patterns
Custom validation: Lambda/function support for complex logic

Related

  • Existing tool_approval docs: docs/useful_plugins/tool_approval.md
  • Shell approval plugin: connectonion/useful_plugins/shell_approval.py (similar pattern could be used)

Priority

Medium-High - This would significantly improve UX for automated agents while maintaining security.


Additional Ideas:

  • Add dry-run mode to test what would be auto-approved
  • Logging of auto-approved commands for audit trail
  • Rate limiting on auto-approvals (max N auto-approvals per minute)
  • Time-based rules (auto-approve only during working hours)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions