A secure, isolated runtime where AI agents execute tool calls inside Docker containers — with resource limits, permission controls, and full audit logging.
Prerequisites: Go 1.21+, Docker running
# Build
make build
# Run
make runThe server starts on http://localhost:8080. First sandbox creation takes ~20s (builds a base image with the agent), subsequent ones are ~1.5s.
curl -X POST localhost:8080/api/v1/sandboxes \
-H "Content-Type: application/json" \
-d '{
"tools": ["shell_exec", "file_read", "file_write", "file_list"],
"files": {
"hello.sh": "echo hello world",
"data/input.txt": "some data"
}
}'curl -X POST localhost:8080/api/v1/sandboxes \
-H "Content-Type: application/json" \
-d '{"profile": "python-eval"}'# Run a shell command
curl -X POST localhost:8080/api/v1/sandboxes/<id>/tools/execute \
-H "Content-Type: application/json" \
-d '{"tool": "shell_exec", "arguments": {"command": "sh hello.sh"}}'
# Read a file
curl -X POST localhost:8080/api/v1/sandboxes/<id>/tools/execute \
-H "Content-Type: application/json" \
-d '{"tool": "file_read", "arguments": {"path": "hello.sh"}}'
# Write a file
curl -X POST localhost:8080/api/v1/sandboxes/<id>/tools/execute \
-H "Content-Type: application/json" \
-d '{"tool": "file_write", "arguments": {"path": "out.txt", "content": "written!"}}'
# List files
curl -X POST localhost:8080/api/v1/sandboxes/<id>/tools/execute \
-H "Content-Type: application/json" \
-d '{"tool": "file_list", "arguments": {"recursive": true}}'
# HTTP request (requires network allowlist)
curl -X POST localhost:8080/api/v1/sandboxes/<id>/tools/execute \
-H "Content-Type: application/json" \
-d '{"tool": "http_request", "arguments": {"method": "GET", "url": "https://api.example.com/data"}}'# Download a file from the sandbox
curl localhost:8080/api/v1/sandboxes/<id>/files/output.txt
# Upload a file to the sandbox
curl -X PUT localhost:8080/api/v1/sandboxes/<id>/files/input.txt \
-d "file content here"# Sandbox with outbound access to specific domains
curl -X POST localhost:8080/api/v1/sandboxes \
-H "Content-Type: application/json" \
-d '{
"tools": ["shell_exec", "http_request"],
"network": {
"mode": "allowlist",
"domain_allowlist": ["api.example.com", "cdn.example.com"]
}
}'curl localhost:8080/healthz # Health check
curl localhost:8080/api/v1/sandboxes # List sandboxes
curl localhost:8080/api/v1/sandboxes/<id>/logs # Audit log
curl -X DELETE localhost:8080/api/v1/sandboxes/<id> # Destroy
curl localhost:8080/api/v1/tools # List toolspip install -e sdk/pythonfrom cagebox import CageboxClient, SandboxConfig
with CageboxClient("http://localhost:8080") as client:
config = SandboxConfig(
tools=["shell_exec", "file_read", "file_write"],
files={"main.py": "print('hello')"},
)
with client.sandbox(config) as sb:
result = sb.execute("shell_exec", command="python3 main.py")
print(result.stdout)See sdk/python/README.md for async usage, profiles, and error handling.
| Method | Path | Description |
|---|---|---|
GET |
/healthz |
Health check |
POST |
/api/v1/sandboxes |
Create a sandbox |
GET |
/api/v1/sandboxes |
List active sandboxes |
GET |
/api/v1/sandboxes/{id} |
Get sandbox details |
POST |
/api/v1/sandboxes/{id}/tools/execute |
Execute a tool |
GET |
/api/v1/sandboxes/{id}/logs |
Get audit log |
GET |
/api/v1/sandboxes/{id}/files/{path} |
Extract file from sandbox |
PUT |
/api/v1/sandboxes/{id}/files/{path} |
Upload file to sandbox |
DELETE |
/api/v1/sandboxes/{id} |
Destroy a sandbox |
GET |
/api/v1/tools |
List registered tools |
Full API documentation: api/openapi.yaml
| Tool | Description |
|---|---|
file_read |
Read a file from the workspace |
file_write |
Write a file to the workspace |
file_list |
List files and directories in the workspace |
shell_exec |
Run a shell command |
http_request |
Make an outbound HTTP request (requires allowlist) |
- Container isolation — each sandbox is a separate Docker container
- Read-only root filesystem — only
/workspace,/tmp,/runare writable (tmpfs) - Non-root execution — agent and all commands run as
nobody(UID 65534) - Zero capabilities — all Linux capabilities dropped, including NET_ADMIN after iptables setup
- Network isolation — iptables blocks all outbound traffic by default; allowlist mode permits specific domains
- seccomp profile — Docker's default profile blocks dangerous syscalls (mount, ptrace, etc.)
- Path traversal prevention — defense-in-depth: server-side and agent-side validation
- Tool allowlists — sandboxes only have access to explicitly enabled tools
- Command blocklist — regex patterns block dangerous shell commands (rm -rf /, fork bombs)
- Domain allowlist — http_request requires explicit domain approval
- Audit logging — every tool call logged (allowed and denied) to SQLite
# Unit tests (no Docker needed)
make test-unit
# Integration tests (requires Docker)
make test-integrationEdit configs/default.yaml or use environment variables:
sandbox:
default_image: "ubuntu:22.04"
max_concurrent: 10 # Max simultaneous sandboxes
resource_limits:
cpu: 0.5
memory_mb: 512
timeout_seconds: 600
command_blocklist: # Regex patterns to block
- 'rm\s+-rf\s+/'
- '\bshutdown\b'
profiles:
python-eval: # Named profile
base_image: "python:3.12-slim"
tools: [file_read, file_write, file_list, shell_exec]
resource_limits:
timeout_seconds: 300
web-scraper:
base_image: "python:3.12-slim"
tools: [file_read, file_write, shell_exec, http_request]
network:
mode: "allowlist"
domain_allowlist: ["api.example.com"]| Env Var | Default |
|---|---|
CAGEBOX_SERVER_PORT |
8080 |
CAGEBOX_SANDBOX_DEFAULT_IMAGE |
ubuntu:22.04 |
CAGEBOX_AUDIT_DATABASE_PATH |
./cagebox.db |
CAGEBOX_LOGGING_LEVEL |
info |
cmd/server/ API server entrypoint
cmd/agent/ In-container agent binary (runs as nobody)
internal/api/ HTTP handlers, router, middleware
internal/sandbox/ Sandbox lifecycle manager
internal/container/ Docker SDK wrapper, image building, network isolation
internal/agent/ Agent tool execution (runs inside containers)
internal/tools/ Tool registry and validation
internal/permissions/ Permission enforcement, domain/command validation
internal/audit/ Audit log storage (SQLite)
internal/config/ Configuration loading, profiles
sdk/python/ Python SDK (sync + async)
api/ OpenAPI 3.1 specification