Sandboxer
Running untrusted code
To run untrusted or AI-generated code safely on Sandboxer, start a fresh microVM with none of your secrets, run the code there with a timeout, read back the output, and delete the VM. The code gets a full Linux machine with its own kernel, but no route to your network, your other sandboxes or your keys.
Updated October 28, 2026
Why run model-written code in a microVM?
Code an LLM wrote or a user uploaded can do anything code can do, so it belongs behind a strong boundary. Each Sandboxer sandbox is a Cloud Hypervisor microVM with its own kernel, and sandboxes cannot reach each other, the host or private networks. The host's agent listens on vsock rather than on the sandbox's network.
Sandboxer's untrusted code use case frames the pattern simply: run it in a VM that cannot reach your network, then throw it away. The reasons a VM is safer than a container are covered in microVMs vs containers.
What does the basic pattern look like?
Create a small sandbox with a short auto-stop, run the code with a timeout, and delete it. This is the example from Sandboxer's use-case page:
id=$(sbx new --type small --ttl 600 --json | jq -r 'select(.event=="ready") | .id')
sbx exec "$id" --timeout 60 -- python3 -c "$GENERATED_CODE"
sbx delete "$id" --yes
The --ttl 600 backstop stops the sandbox after ten minutes even if your script crashes before the delete. For files, use sbx scp, or the SDK's file calls, which read and write single files of up to 5 MiB.
How do you keep secrets out?
Start the sandbox with --no-env so it holds none of your account's secrets, then pass only what the task needs. Sandboxer's guide on passing secrets safely adds two cautions:
- Never put a secret on a command line:
sbx historystores every exec command for 90 days, andpsshows process arguments - Prefer
-e, stdin, or a file you delete after use
For your own API calls, use a scoped key limited to one sandbox and a few actions, with an expiry. In a product that gives each user a sandbox, create each one with noEnv through the API.
Should every tool call get a fresh sandbox?
Use a fresh sandbox per call when the input is untrusted or calls must not see each other, and reuse one sandbox per session when calls build on each other. Sandboxer's guide on a fresh sandbox per tool call measured both on its production service:
| Approach | Measured time per call |
|---|---|
| Fresh sandbox from a pre-warmed named snapshot | 3.2 seconds |
| Fresh sandbox, installing dependencies each time | 12.9 seconds |
| Reusing one sandbox per session | 0.55 seconds |
The lesson is to bake dependencies into a named snapshot, so fresh sandboxes start ready.
How do you cap CPU and memory for one run?
Wrap the run in a systemd scope inside the sandbox. Sandboxer's resource limits guide suggests limits along these lines:
sudo systemd-run --scope -p MemoryMax=1G -p CPUQuota=100% -p TasksMax=256 -p RuntimeMaxSec=60 python3 untrusted.py
In its test, a memory hog died with exit code 137, a fork bomb stalled at 200 tasks, and the agent's own processes kept running.
What is still your responsibility?
A microVM narrows escape routes, but it cannot judge the code's intent. Outbound internet is open by default, so code can call out; restrict it with ufw inside the VM if needed. Anything you put inside can be read. And output, such as a patch, still needs review before you merge or run it elsewhere. See security and isolation.
Frequently asked questions
Is Docker enough for untrusted code?
Containers share the host kernel. For code you do not trust, Sandboxer's guides recommend a VM boundary such as a microVM.
Can untrusted code in a sandbox reach my other sandboxes?
No. Traffic between sandboxes, and to the host and internal networks, is blocked.
How long can a command run through exec?
A synchronous exec waits 1 to 600 seconds, 30 by default. Longer jobs can be started detached and checked later.
Can I check out an unknown GitHub repo safely?
Sandboxer has a guide for this: run it in a fresh no-env sandbox inside a capped systemd scope, copy the report out, and delete the VM.