AI Sandboxes¶
A sandbox is a short-lived VM that an AI agent (or a person) creates, runs commands in, and throws away. Use it to let an agent test code on a real kernel with systemd, libvirt or a real network, without giving it access to your other VMs.
Each sandbox:
- goes on the network and hosts an admin chooses, never wherever the caller asks;
- is deleted automatically when its time runs out;
- runs commands through the QEMU guest agent, so there's no SSH, no guest password and no route needed from the console to the sandbox network;
- is reachable with a
sandboxAPI key, which can use sandboxes and nothing else.
Sandboxes are off until an admin turns them on.
Plain unit tests don't need a sandbox
A CI runner is cheaper for tests that run in a container. Use a sandbox when the test needs a whole VM: installing packages, services, kernel modules, nested virtualization, or a real network.
1. Build the sandbox template¶
The template needs the QEMU guest agent with command execution allowed. Rocky and RHEL turn that off by default. On any compute node, as root:
dnf install -y guestfs-tools # once, for virt-customize
./deployment/sandbox/build-sandbox-template.sh
This downloads the Rocky 9 cloud image and writes
/var/lib/libvirt/images/sandbox-rocky9_tmplt.qcow2. The image has the guest
agent, git, Python 3, Podman and build tools. No password or SSH key is
baked in. Then publish it to the sandbox hosts from Content Library.
2. Pick an isolated network¶
Code under test is untrusted, and so is code an agent wrote. Give sandboxes a port group whose only way out is what tests need: your Git server and package mirrors. It shouldn't reach the hosts' management addresses, the console, or the database. An OVN logical switch with no router, or a VLAN behind a firewall, both work.
3. Turn sandboxes on¶
Settings → AI Sandboxes (Super Admin):
| Setting | What it does |
|---|---|
| Allow sandboxes | Off by default. Can't be turned on until a network and placement are set. |
| Network | The isolated port group from step 2. |
| Placement | The cluster whose hosts run sandboxes. Use lab hosts, not production. |
| Default template | Used when a caller doesn't name one, e.g. sandbox-rocky9_tmplt.qcow2. |
| Default life | Minutes a new sandbox lives (default 60). |
| Max per extend | The most one create or extend can set (default 240). |
| Hard limit | Hours from creation after which a sandbox is deleted however often it was extended (default 24). |
| Per user, max vCPU / RAM / disk | Size caps. Per-user quotas and tenant limits apply on top. |
| Command limit | Longest time one command may run (default 3600 s). |
Turning sandboxes off stops new ones being created. Existing ones still expire on time.
4. Give an agent a key¶
Under Settings → My API Keys, generate a key with scope Sandbox and
an expiry. That key can call /api/sandboxes and nothing else. It can't
list your VMs, open a console, or change these settings.
Connect it to the MCP server the same way as any other key. The agent then
has sandbox_create, sandbox_exec, sandbox_exec_result, sandbox_list,
sandbox_extend and sandbox_destroy. The console's AI chat panel offers
the same tools while sandboxes are on.
Using the API directly¶
H="X-API-Key: $KEY"
# create (returns the name, e.g. sbx-alice-3f9a1c)
curl -sk -H "$H" -H 'Content-Type: application/json' \
-d '{"vcpus":2,"memory_mb":4096,"ttl_minutes":90}' https://console/api/sandboxes
# run a command; waits up to wait_s (max 60) for it to finish
curl -sk -H "$H" -H 'Content-Type: application/json' \
-d '{"command":"git clone https://git.lab/app.git /src && cd /src && make test","timeout_s":900}' \
https://console/api/sandboxes/sbx-alice-3f9a1c/exec
# still running? poll it
curl -sk -H "$H" "https://console/api/sandboxes/sbx-alice-3f9a1c/exec/42?wait_s=60"
# done
curl -sk -H "$H" -X DELETE https://console/api/sandboxes/sbx-alice-3f9a1c
A command runs as root under /bin/sh -c. The result has the exit code and
the last 64 KB of stdout and stderr. Exit code 124 means the command
hit timeout_s and was stopped. Put secrets such as a Git deploy token in
env: commands are recorded with their results, env values never are.
The first command after creating a sandbox may answer "the guest agent isn't answering yet". The VM is still booting; wait a minute and retry.
What's recorded¶
- Creating, extending and destroying a sandbox, and every settings change, go to the audit log.
- Every command, with who ran it, when, its exit code and output tail, is kept with the sandbox and for 30 days after it's deleted.
- Expired sandboxes are deleted by the console within a minute of expiring,
and the deletion is audited as
system.