Sandbox Execution
PraisonAI CLI provides sandboxed execution for running AI-generated commands safely. Inspired by Codex CLI’s sandbox modes, this feature isolates command execution with configurable security policies.
Sandbox execution is only activated when explicitly requested via the --sandbox CLI flag. By default, commands run without sandboxing.
Overview
The sandbox provides:
- Command validation - Block dangerous commands
- Resource limits - CPU, memory, and time limits
- Path restrictions - Control filesystem access
- Network isolation - Optional network blocking
- Execution isolation - Separate working directory
Quick Start
# Enable basic sandbox
praisonai "Run the tests" --sandbox basic
# Strict sandbox (more restrictions)
praisonai "Build the project" --sandbox strict
# Network isolated
praisonai "Process local files" --sandbox network-isolated
Sandbox Modes
Disabled (Default)
No sandboxing. Commands run normally.
praisonai "Run npm install"
# Runs without any restrictions
Basic
Light sandboxing with resource limits:
praisonai "Run tests" --sandbox basic
Restrictions:
- ✅ 512MB memory limit
- ✅ 60 second timeout
- ✅ Blocked dangerous commands (rm -rf, sudo, etc.)
- ✅ Network access allowed
Strict
Heavy sandboxing with filesystem isolation:
praisonai "Process data" --sandbox strict
Restrictions:
- ✅ 256MB memory limit
- ✅ 30 second timeout
- ✅ Blocked dangerous commands
- ✅ Blocked network tools (curl, wget, etc.)
- ✅ Isolated temporary directory
- ✅ Limited process count (5)
Network Isolated
No network access:
praisonai "Analyze local files" --sandbox network-isolated
Restrictions:
- ✅ 512MB memory limit
- ✅ 60 second timeout
- ✅ Blocked dangerous commands
- ❌ No network access
Python API
Basic Usage
from praisonai.cli.features import SandboxExecutorHandler
# Initialize with a mode
handler = SandboxExecutorHandler(verbose=True)
sandbox = handler.initialize(mode="basic")
# Execute a command
result = handler.execute("echo 'Hello, World!'")
print(f"Success: {result.success}")
print(f"Output: {result.stdout}")
print(f"Was sandboxed: {result.was_sandboxed}")
Execution Result
result = handler.execute("ls -la")
# Result properties
print(f"Success: {result.success}")
print(f"Exit code: {result.exit_code}")
print(f"Stdout: {result.stdout}")
print(f"Stderr: {result.stderr}")
print(f"Duration: {result.duration_ms}ms")
print(f"Sandboxed: {result.was_sandboxed}")
print(f"Violations: {result.policy_violations}")
Command Validation
# Validate before executing
violations = handler.validate_command("rm -rf /")
if violations:
print("Command blocked:")
for v in violations:
print(f" - {v}")
else:
result = handler.execute("rm -rf /")
Custom Policy
from praisonai.cli.features.sandbox_executor import (
SandboxPolicy,
SandboxMode,
SubprocessSandbox
)
# Create custom policy
policy = SandboxPolicy(
mode=SandboxMode.BASIC,
max_memory_mb=1024,
max_cpu_seconds=120,
max_file_size_mb=50,
max_processes=20,
allow_network=True,
blocked_commands={"rm", "sudo", "chmod"},
blocked_paths={"/etc", "/var", "/usr"}
)
# Use custom policy
sandbox = SubprocessSandbox(policy=policy)
result = sandbox.execute("my_command")
Blocked Commands
By default, these commands are blocked:
| Command | Reason |
|---|
rm | File deletion |
rmdir | Directory deletion |
mv | File moving (can overwrite) |
dd | Disk operations |
mkfs | Filesystem creation |
fdisk | Disk partitioning |
sudo | Privilege escalation |
su | User switching |
chmod | Permission changes |
chown | Ownership changes |
kill | Process termination |
pkill | Process termination |
Strict Mode Additional Blocks
| Command | Reason |
|---|
curl | Network access |
wget | Network access |
nc / netcat | Network access |
ssh | Remote access |
scp | Remote file transfer |
Dangerous Patterns
These patterns are always blocked:
# Recursive force delete
"rm -rf /" # Blocked
# Device file access
"> /dev/sda" # Blocked
# Shell piping
"cat file | sh" # Blocked
"cat file | bash" # Blocked
# Command substitution
"$(dangerous_command)" # Blocked
"`dangerous_command`" # Blocked
Path Restrictions
Blocked Paths (Strict Mode)
blocked_paths = {
"/etc", # System configuration
"/var", # Variable data
"/usr", # User programs
"/bin", # Essential binaries
"/sbin", # System binaries
"/root", # Root home
"/home", # User homes
"/sys", # Kernel interface
"/proc" # Process information
}
Allowed Paths
# Configure allowed paths
policy = SandboxPolicy(
mode=SandboxMode.STRICT,
allowed_paths={
"/tmp",
"/path/to/project",
"/path/to/data"
}
)
Resource Limits
Memory Limit
policy = SandboxPolicy(
max_memory_mb=256 # 256MB limit
)
CPU Time Limit
policy = SandboxPolicy(
max_cpu_seconds=30 # 30 second timeout
)
Process Limit
policy = SandboxPolicy(
max_processes=5 # Max 5 child processes
)
Integration with Autonomy Modes
Sandbox works with autonomy modes:
from praisonai.cli.features import (
SandboxExecutorHandler,
AutonomyModeHandler
)
# Set up autonomy
autonomy = AutonomyModeHandler()
autonomy.initialize(mode="auto_edit")
# Set up sandbox
sandbox = SandboxExecutorHandler()
sandbox.initialize(mode="basic")
# Commands go through both:
# 1. Autonomy check (approval if needed)
# 2. Sandbox validation
# 3. Sandboxed execution
Error Handling
Timeout
result = sandbox.execute("sleep 100", timeout=5)
if not result.success:
if "timed out" in result.stderr.lower():
print("Command timed out")
Policy Violation
result = sandbox.execute("rm -rf /")
if result.policy_violations:
print("Command blocked by policy:")
for violation in result.policy_violations:
print(f" - {violation}")
Execution Error
result = sandbox.execute("nonexistent_command")
if not result.success:
print(f"Error: {result.stderr}")
print(f"Exit code: {result.exit_code}")
Best Practices
When to Use Sandbox
| Scenario | Recommended Mode |
|---|
| Running user-provided code | strict |
| AI-generated shell commands | basic |
| Processing untrusted data | strict |
| Local file operations | basic |
| Network-sensitive tasks | network-isolated |
| Trusted automation | disabled |
Security Tips
- Start with strict - Relax restrictions as needed
- Review violations - Check what’s being blocked
- Use network isolation - When network isn’t needed
- Set timeouts - Prevent runaway processes
- Limit resources - Prevent resource exhaustion
Environment Variables
# Default sandbox mode
export PRAISONAI_SANDBOX_MODE=basic
# Disable sandbox entirely (not recommended)
export PRAISONAI_DISABLE_SANDBOX=false
# Custom timeout
export PRAISONAI_SANDBOX_TIMEOUT=60
CLI Flags
# Enable sandbox
praisonai "task" --sandbox basic
# Specific mode
praisonai "task" --sandbox strict
praisonai "task" --sandbox network-isolated
# Disable (explicit)
praisonai "task" --sandbox disabled
Troubleshooting
Command Unexpectedly Blocked
# Check what's being blocked
violations = handler.validate_command("my_command")
print(violations)
# Adjust policy if needed
policy = SandboxPolicy(
mode=SandboxMode.BASIC,
blocked_commands={"rm", "sudo"} # Reduced list
)
Timeout Too Short
# Increase timeout
result = handler.execute("long_running_command", timeout=300)
# Or in policy
policy = SandboxPolicy(max_cpu_seconds=300)
Path Access Denied
# Add to allowed paths
policy = SandboxPolicy(
allowed_paths={"/path/to/needed/directory"}
)