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 SynapseOrch UI: open Apps › Tools and a Python tool. Until the image exists the editor says Python sandbox image not built; press Build Sandbox Image (about 2–3 minutes).
Via the CLI:
cd backend/tools
docker build -t sandbox-python:latest -f sandbox.Dockerfile .Tool: execute_python
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 execute_python — it receives the output, interprets it, and presents the result.
Direct call
{
"tool": "execute_python",
"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 root, with /tmp and /root as 512 MB tmpfs |
| Network | None by default — the agent can ask for it, see below |
| Timeout | 30 seconds (configurable up to 120s) |
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
From a script signed in as Calling the settings API from a script shows:
curl -b synapse.cookies http://localhost:3000/api/tools/docker/status{
"installed": true,
"running": true,
"image_exists": true
}Network access
The tool takes an allow_network argument, default false, which decides whether the container runs with --network none or on the internet.
Two things are worth knowing:
- The agent chooses.
allow_networkis a normal tool argument, so an agent can set it totrueon any call. It is a default, not a restriction you impose. To stop an agent reaching the network at all, don't give it this tool — or require approval for it with tool policy. - Asking for packages asks for network. Installing packages needs pip to reach an index, so passing
packagesturnsallow_networkon whether or not you set it.
allowed_domains narrows an internet-enabled run to a host list, but it is applied inside the sandbox — a guardrail, not a boundary. Code that sets out to defeat it can. Enforcing a host list from outside the sandbox needs an egress proxy, which is why there is no RESTRICTED network mode: naming a guarantee before the mechanism exists would be worse than not offering it.
Security model
- Read-only filesystem — cannot write to the host or other containers
- Resource limits — cannot exhaust host CPU, memory or processes
- Ephemeral — each execution runs in a fresh container, discarded afterwards
- Network off by default, with the caveats above
Built-in Tools
Tools are functions that agents can call during their ReAct loop.
SQL Agent
The SQL tool gives agents the ability to query any SQLAlchemy-compatible database — PostgreSQL, MySQL, SQLite, and SQL Server. Agents can explore schemas, run queries, and surface data without needing to know the database structure in advance.