How to Restrict Shell Commands in the aisuite Shell Toolkit
The aisuite Shell Toolkit provides configurable sandbox controls via allowed_commands, allow_all, and allow_shell parameters to whitelist specific binaries and block dangerous shell operators.
The aisuite library by Andrew Ng offers a secure shell execution environment through its ShellToolkit class. When building AI agents that require system command execution, restricting shell commands in the aisuite shell toolkit prevents unauthorized access and potential security vulnerabilities. This guide examines the validation mechanisms implemented in aisuite/toolkits/shell.py to help you configure strict command sandboxing.
Configuration Parameters for Command Restrictions
The ShellToolkit constructor accepts several security parameters that control command execution privileges. According to the source code in aisuite/toolkits/shell.py, you must provide either an allowed_commands whitelist or set allow_all=True, otherwise the constructor raises a ValueError at lines 64-68.
Whitelisting with allowed_commands
The allowed_commands parameter accepts a list of exact command strings or prefixes that define which binaries may execute. When run_shell processes a command, the _validate_command method compares the input against this whitelist, raising a PermissionError if no match is found.
from aisuite import toolkits as tk
# Only permit python3 and ls commands
tools = tk.shell(
cwd="/tmp",
allowed_commands=["python3", "ls"],
allow_all=False,
allow_shell=False,
)
run_shell = tools[0].func
# ✅ Allowed: matches whitelist
result = run_shell("python3 -c 'print(\"hello\")'")
print(result["stdout"]) # → hello
# ❌ Blocked: raises PermissionError
run_shell("git status")
Disabling Restrictions with allow_all
Setting allow_all=True bypasses the whitelist validation entirely. The _validate_command method short-circuits when this flag is enabled, permitting any system command to execute regardless of the allowed_commands content.
Blocking Shell Operators with allow_shell
The allow_shell parameter controls whether the toolkit accepts shell-specific syntax such as pipes (|), redirections (>), and logical operators (&&). When set to False, the _validate_no_shell_syntax method scans for prohibited tokens including newlines and metacharacters, raising a ValueError if detected.
tools = tk.shell(
cwd=".",
allowed_commands=["make"],
allow_shell=False, # Reject &&, |, > etc.
)
run_shell = tools[0].func
# Allowed: single command with arguments
run_shell("make build")
# Blocked: raises ValueError for shell syntax
run_shell("make build && echo done")
Internal Validation Flow
The restriction logic follows a multi-layer validation pipeline before executing any command via subprocess.run.
First, the constructor validates that either allowed_commands is populated or allow_all is enabled. Then, during command execution, run_shell invokes validation methods in sequence. If allow_shell=False, the code parses the command using shlex.split and checks for shell metacharacters. Finally, if allow_all=False, the command string is checked against the whitelist. Only commands passing both validation stages proceed to subprocess.run.
Practical Implementation Examples
Basic Agent Integration
When integrating the shell toolkit into an AI agent, configure strict permissions to limit the agent's system access:
import aisuite as ai
# Build a tool set restricted to pytest only
tool_set = ai.toolkits.shell(
cwd="tests",
allowed_commands=["pytest"],
allow_shell=False,
)
assistant = ai.Agent(
name="tester",
model="openai:gpt-4o",
tools=[tool_set[0]],
)
Strict Sandbox Configuration
For maximum security, combine all restriction parameters:
tools = tk.shell(
cwd="/sandbox",
allowed_commands=["python3", "pip"],
allow_all=False, # Enforce whitelist strictly
allow_shell=False, # Disable pipes and redirection
default_timeout_seconds=30,
max_output_chars=10000,
)
Summary
- The
allowed_commandsparameter creates a whitelist of permitted binaries, enforced by the_validate_commandmethod inaisuite/toolkits/shell.py. - Setting
allow_all=Truedisables whitelist enforcement, allowing unrestricted command execution. - When
allow_shell=False, the toolkit rejects pipes, redirections, and other shell operators via_validate_no_shell_syntax. - The constructor requires explicit configuration of either a whitelist or
allow_allmode to prevent accidental unrestricted access. - Commands are validated using
shlex.splitbefore execution to ensure proper tokenization when shell mode is disabled.
Frequently Asked Questions
What happens if I don't specify allowed_commands or allow_all?
The ShellToolkit constructor raises a ValueError if neither parameter is provided, ensuring that developers explicitly configure the security model rather than defaulting to unrestricted access.
Can I use wildcards or regex in the allowed_commands list?
The current implementation in aisuite/toolkits/shell.py performs prefix matching rather than regex evaluation. Commands must match exactly or start with one of the entries in the allowed_commands list.
How does aisuite prevent command injection when allow_shell is False?
The toolkit uses shlex.split to tokenize the command string and the _validate_no_shell_syntax method checks for prohibited characters including pipes, ampersands, and redirection operators. Any detected shell syntax triggers a ValueError before the command reaches subprocess.run.
Where is the shell restriction logic implemented in the source code?
All validation logic resides in aisuite/toolkits/shell.py, specifically within the _validate_command method (lines 13-22) for whitelist enforcement and _validate_no_shell_syntax (lines 23-30) for shell operator detection.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →