> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox Backends

> Execute commands safely with configurable shell control across different backends

Sandbox backends provide isolated command execution environments with explicit shell control to prevent injection attacks while enabling shell features when needed.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Sandbox Command Execution"
        A[📝 Command] --> B{🔍 shell=?}
        B -->|False| C[🛡️ Safe Parse]
        B -->|True| D[⚠️ Shell Features]
        C --> E[✅ Execute]
        D --> E
    end
    
    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
    classDef shell fill:#8B0000,stroke:#7C90A0,color:#fff
    
    class A input
    class B decision
    class C,E safe
    class D shell
```

## Quick Start

<Steps>
  <Step title="Safe Command Execution">
    Execute commands safely without shell features:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.sandbox import SubprocessSandbox

    # Create agent with safe command execution
    agent = Agent(
        name="System Agent",
        instructions="Execute system commands safely",
    )

    # Create sandbox for safe execution
    sandbox = SubprocessSandbox()

    # Execute without shell (default, safe)
    result = await sandbox.run_command("ls -la")
    print(result.stdout)
    ```
  </Step>

  <Step title="With Shell Features">
    Enable shell features when needed:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent
    from praisonai.sandbox import DockerSandbox

    agent = Agent(
        name="Data Agent", 
        instructions="Process data with shell pipelines"
    )

    sandbox = DockerSandbox()

    # Execute with shell features (explicit opt-in)
    result = await sandbox.run_command(
        "cat data.txt | grep 'error' | wc -l",
        shell=True
    )
    print(f"Error count: {result.stdout.strip()}")
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant Sandbox
    participant Shell
    participant Process
    
    Agent->>Sandbox: run_command(cmd, shell=False)
    alt shell=False (Safe)
        Sandbox->>Shell: shlex.split(cmd)
        Shell->>Process: exec(*argv)
    else shell=True (Features)
        Sandbox->>Shell: sh -c "cmd"
        Shell->>Process: shell execution
    end
    Process-->>Sandbox: Result
    Sandbox-->>Agent: SandboxResult
```

| Backend             | Use Case                   | Security Level              |
| ------------------- | -------------------------- | --------------------------- |
| `SubprocessSandbox` | Local development, scripts | Medium (OS-level isolation) |
| `DockerSandbox`     | Production, untrusted code | High (container isolation)  |
| `SSHSandbox`        | Remote execution           | High (network isolation)    |

***

## Configuration Options

### Shell Parameter Control

<Tabs>
  <Tab title="shell=False (Default)">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # String commands are parsed safely
    result = await sandbox.run_command("python script.py --arg value")

    # List commands are executed directly
    result = await sandbox.run_command(["python", "script.py", "--arg", "value"])
    ```

    **Security**: No shell injection possible. String commands are parsed with `shlex.split()`.
  </Tab>

  <Tab title="shell=True (Opt-in)">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Shell features available: pipes, redirects, globs
    result = await sandbox.run_command(
        "find . -name '*.py' | xargs grep 'TODO' > todos.txt",
        shell=True
    )

    # Environment variable expansion
    result = await sandbox.run_command(
        "echo $HOME && ls $PWD/*.log", 
        shell=True
    )
    ```

    **Security**: Shell evaluation enabled. Only use with trusted input.
  </Tab>
</Tabs>

<Warning>
  Set `shell=True` only when you need shell features (pipes, `&&`, globbing). With untrusted input always keep `shell=False`.
</Warning>

### Decision Guide

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    A[Need to run command?] --> B{Need pipes/globs?}
    B -->|No| C[Use shell=False]
    B -->|Yes| D{Input trusted?}
    D -->|Yes| E[Use shell=True]
    D -->|No| F[Sanitize OR use shell=False]
    
    classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
    classDef caution fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef danger fill:#8B0000,stroke:#7C90A0,color:#fff
    
    class C,F safe
    class D,E caution
```

| Use Case                                   | Recommended `shell` Value |
| ------------------------------------------ | ------------------------- |
| Running a single executable with arguments | `False`                   |
| Pipelines (`grep \| sort`)                 | `True`                    |
| Globs and env-var expansion                | `True`                    |
| Untrusted / model-generated commands       | `False`                   |

***

## Common Patterns

### Backend Selection

<Tabs>
  <Tab title="Development">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.sandbox import SubprocessSandbox

    # Local development with subprocess
    sandbox = SubprocessSandbox()
    result = await sandbox.run_command("python test.py")
    ```
  </Tab>

  <Tab title="Production">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.sandbox import DockerSandbox

    # Isolated container execution
    sandbox = DockerSandbox(
        image="python:3.11-slim",
        timeout=30
    )
    result = await sandbox.run_command("python app.py", shell=False)
    ```
  </Tab>

  <Tab title="Remote">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.sandbox import SSHSandbox

    # Remote server execution
    sandbox = SSHSandbox(
        host="remote.server.com",
        username="runner"
    )
    result = await sandbox.run_command(["python", "remote_task.py"])
    ```
  </Tab>
</Tabs>

### Safe Data Processing

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.sandbox import DockerSandbox

sandbox = DockerSandbox()

# Process user data safely
async def process_file(filename):
    # Safe: no shell injection possible
    result = await sandbox.run_command([
        "python", "process.py", "--input", filename
    ], shell=False)
    return result.stdout

# Process with shell features when controlled
async def count_errors(log_file):
    import shlex
    # Trusted input, need shell features  
    result = await sandbox.run_command(
        f"grep 'ERROR' {shlex.quote(log_file)} | wc -l",
        shell=True
    )
    return int(result.stdout.strip())
```

### Resource Limits

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.sandbox import ResourceLimits, SubprocessSandbox

limits = ResourceLimits(
    timeout_seconds=30,
    memory_mb=512
)

sandbox = SubprocessSandbox()
result = await sandbox.run_command(
    "python heavy_task.py",
    limits=limits,
    shell=False
)
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Always use shell=False for untrusted input">
    Model-generated commands or user input should never use `shell=True` to prevent injection attacks. The default `shell=False` provides automatic protection.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # ✅ Safe with any user input
    user_script = request.get("script")
    result = await sandbox.run_command(f"python {user_script}", shell=False)

    # ❌ Vulnerable to injection
    result = await sandbox.run_command(f"python {user_script}", shell=True)
    ```
  </Accordion>

  <Accordion title="Quote arguments when building shell commands">
    If you must use `shell=True`, quote all dynamic arguments with `shlex.quote()`:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    import shlex

    filename = user_input  # Could contain special characters
    command = f"process.py --file {shlex.quote(filename)}"
    result = await sandbox.run_command(command, shell=True)
    ```
  </Accordion>

  <Accordion title="Prefer list form for complex commands">
    Using argument lists avoids shell parsing entirely:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # ✅ Clear and injection-safe
    result = await sandbox.run_command([
        "python", "script.py", 
        "--input", input_file,
        "--output", output_file
    ], shell=False)

    # ❌ Requires careful quoting
    import shlex
    command = f"python script.py --input {shlex.quote(input_file)} --output {shlex.quote(output_file)}"
    result = await sandbox.run_command(command, shell=True)
    ```
  </Accordion>

  <Accordion title="Use appropriate backend for your security needs">
    Choose the sandbox backend based on your isolation requirements:

    * **Development**: `SubprocessSandbox` for speed and convenience
    * **Production**: `DockerSandbox` for container-level isolation
    * **Remote**: `SSHSandbox` for network-isolated execution
    * **High Security**: Always use Docker or SSH backends with `shell=False`
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Resource Limits" icon="gauge" href="/docs/cli/sandbox-execution">
    Configure timeouts and memory limits for sandbox execution
  </Card>

  <Card title="Thread Safety" icon="lock" href="/docs/features/thread-safety">
    Understanding thread-safe operations across PraisonAI components
  </Card>
</CardGroup>
