Overview
The sandbox system:- Runs commands in ephemeral Docker containers
- Routes network traffic through a validating proxy
- Injects credentials at the proxy boundary (never in containers)
- Enforces resource limits (memory, CPU, timeout)
- Scans for credential leakage in requests/responses
Architecture
Sandbox Policies
Three policies control filesystem and network access:| Policy | Filesystem | Network | Use Case |
|---|---|---|---|
ReadOnly | /workspace (ro) | Proxied (allowlist) | Explore code, fetch docs |
WorkspaceWrite | /workspace (rw) | Proxied (allowlist) | Build software, run tests |
FullAccess | Full host | Full network | Direct execution (no sandbox) |
Quick Start
Prerequisites
- Docker installed and running
- Docker image built:
docker build -t ironclaw-worker:latest -f Dockerfile.worker .
Check Docker Status
Enable Sandbox
Edit~/.ironclaw/.env or set environment:
Usage
Execute Commands
The agent automatically uses the sandbox for commands:Manual Execution (CLI)
For testing:Programmatic Usage
Configuration
Environment Variables
Network Allowlist
The proxy allows requests to specific domains. Default allowlist includes: Package registries:- crates.io, static.crates.io, index.crates.io
- registry.npmjs.org
- proxy.golang.org
- pypi.org, files.pythonhosted.org
- docs.rs, doc.rust-lang.org
- nodejs.org, docs.python.org
- go.dev
- github.com, raw.githubusercontent.com
- gitlab.com
- dl.google.com (Android SDK)
- download.qt.io
src/sandbox/config.rs and rebuild, or configure via environment:
Resource Limits
Default limits:Credential Injection
Credentials are never passed to containers as environment variables. Instead:- Container makes request with placeholder:
https://api.github.com/user?token={GITHUB_TOKEN} - Proxy intercepts and checks allowlist
- Proxy scans for leaked secrets in request
- Proxy replaces
{GITHUB_TOKEN}with actual token - Proxy executes request to external API
- Proxy scans response for leaked secrets
- Proxy returns response to container
Security Properties
Isolation
- Non-root execution: Containers run as UID 1000
- Read-only root: Container filesystem is immutable
- Dropped capabilities: All Linux capabilities removed
- No host network: Container uses internal network
- Ephemeral: Containers are removed after execution
Credential Protection
- No environment variables: Secrets not passed via ENV
- Proxy injection: Secrets replaced at proxy boundary
- Leak detection: Outgoing requests scanned for secrets
- Response scanning: Incoming data checked for leakage
Network Control
- Allowlist enforcement: Only approved domains accessible
- Path prefix matching: Restrict to specific API endpoints
- Rate limiting: Per-domain and global limits
- HTTPS enforcement: No plain HTTP to remote hosts
Resource Control
- Memory limits: Hard cap on container memory
- CPU limits: Relative CPU shares
- Timeout enforcement: Commands killed after timeout
- Output truncation: Large outputs are truncated
Building the Worker Image
Dockerfile.worker
Build
Verify
Troubleshooting
Docker Not Available
Error: “Docker is not available”- Ensure Docker is installed:
docker --version - Start Docker daemon:
sudo systemctl start docker(Linux) or start Docker Desktop (Mac/Windows) - Check permissions:
docker ps(should not require sudo) - Run doctor:
ironclaw doctor
Image Not Found
Error: “Image ‘ironclaw-worker:latest’ not found”Network Requests Blocked
Error: “Host not in allowlist”- Check the allowlist includes the host
- Add to allowlist in
src/sandbox/config.rs - For testing, use
full_accesspolicy (disables sandbox)
Timeout
Error: “Command timed out”- Increase timeout:
export SANDBOX_TIMEOUT=300 - Check if the command is hanging
- Test outside sandbox:
ironclaw exec --policy full_access
Permission Denied
Error: “Permission denied” writing to /workspace- Use
workspace_writepolicy:export SANDBOX_POLICY=workspace_write - Check ownership:
ls -la /workspace - Fix permissions:
chown -R 1000:1000 /workspace
Advanced Usage
Custom Proxy Configuration
Per-Command Policies
Custom Resource Limits
Performance Considerations
- Container startup: ~1-2 seconds per execution
- Network proxy: Minimal overhead (~10ms per request)
- Credential scanning: Fast regex matching
- Output collection: Streamed, not buffered
- Reuse containers when possible (future feature)
- Use polling instead of creating containers per message
- Batch commands where feasible
- Keep allowlist focused (fewer regex matches)
Best Practices
- Use sandbox by default: Only disable for trusted operations
- Minimal allowlist: Only add domains you need
- Set timeouts: Prevent runaway commands
- Monitor logs: Watch for policy violations
- Test policies: Verify commands work with least privilege
- Keep images updated: Rebuild worker image regularly
- Limit memory: Prevent OOM on host
Next Steps
- Learn about building WASM tools for custom capabilities
- Explore MCP servers for external integrations
- Set up Telegram channel for messaging
- Read building channels to create your own
