Python Sandbox
The sandbox tool executes Python code in an isolated Docker container with resource limits. It's the safest way to give agents the ability to run code without exposing your host system.
Requirements
- Docker must be installed and running
- The
sandbox-pythonDocker image must be built (one-time setup)
Building the sandbox image
Via the Synapse UI: go to Settings → Tools → Python Sandbox and click Build Image.
Via the CLI:
cd backend/tools
docker build -t sandbox-python:latest -f sandbox.Dockerfile .
Tool: sandbox_execute
Executes a Python script and returns stdout, stderr, and the exit code.
Agent usage
Can you write a Python script to calculate the compound interest on $10,000 at 7% for 20 years and plot it?
The agent will write the code and call sandbox_execute — it receives the output, interprets it, and presents the result.
Direct call
{
"tool": "sandbox_execute",
"code": "import pandas as pd\ndf = pd.DataFrame({'x': [1,2,3], 'y': [4,5,6]})\nprint(df.describe())"
}
Container constraints
| Resource | Limit |
|---|---|
| Memory | 512 MB |
| CPUs | 1.0 |
| PID limit | 64 processes |
| Filesystem | Read-only (tmpfs for /tmp and /root, 256 MB each) |
| Network | None — containers cannot make network calls |
| Timeout | 30 seconds (configurable up to 60s) |
The vault is mounted read-only at /data inside the container. Code can read vault files but cannot write to them from the sandbox — use the vault_write tool for that.
Pre-installed packages
The sandbox image ships with these Python packages:
| Package | Version |
|---|---|
pandas | latest |
pandas_ta | latest |
numpy | latest |
scipy | latest |
scikit-learn | latest |
matplotlib | latest |
seaborn | latest |
requests | latest |
httpx | latest |
beautifulsoup4 | latest |
lxml | latest |
openpyxl | latest |
xlsxwriter | latest |
pyyaml | latest |
tabulate | latest |
jinja2 | latest |
jsonschema | latest |
pillow | latest |
sympy | latest |
Argument injection
When the sandbox is called with arguments (e.g. from a custom Python tool), they are injected as _args:
# _args is automatically available
name = _args.get("name", "World")
print(f"Hello, {name}!")
Checking Docker status
curl http://localhost:8000/api/tools/docker/status
{
"installed": true,
"running": true,
"image_exists": true
}
Security model
- No network access — agents cannot exfiltrate data or make external calls from sandbox code
- Read-only filesystem — cannot write to host or other containers
- Resource limits — cannot exhaust host CPU, memory, or processes
- Ephemeral — each execution runs in a fresh container, discarded after completion