# How to Restrict Shell Commands in the aisuite Shell Toolkit

> Learn to restrict shell commands in the aisuite Shell Toolkit using allowed_commands, allow_all, and allow_shell parameters. Secure your system by whitelisting binaries and blocking dangerous operators.

- Repository: [Andrew Ng/aisuite](https://github.com/andrewyng/aisuite)
- Tags: how-to-guide
- Published: 2026-06-16

---

**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`](https://github.com/andrewyng/aisuite/blob/main/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`](https://github.com/andrewyng/aisuite/blob/main/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.

```python
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.

```python
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:

```python
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:

```python
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_commands` parameter creates a whitelist of permitted binaries, enforced by the `_validate_command` method in [`aisuite/toolkits/shell.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/shell.py).
- Setting `allow_all=True` disables 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_all` mode to prevent accidental unrestricted access.
- Commands are validated using `shlex.split` before 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`](https://github.com/andrewyng/aisuite/blob/main/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`](https://github.com/andrewyng/aisuite/blob/main/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.