Sandboxes#
A sandbox is an isolated container that runs an agent under policy. It has its own filesystem, its own locked-down network, its own identity in the platform, and its own line in the audit trail.
This is where agents actually run.
Create a sandbox#
curl -fsS -X POST \
-H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
-H "Content-Type: application/json" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes \
-d '{
"image": "ghcr.io/acme/agent:1.2",
"command": "python agent.py",
"cpu": "500m",
"memory": "2Gi",
"policyIds": ["'"$POLICY_ID"'"]
}'
Create a sandbox in the production project from the image
ghcr.io/acme/agent:1.2. Run "python agent.py" with 500m CPU and
2Gi memory, and attach the agent-base policy.
Requires an AI tool connected to the MCP endpoint.
nexusctl sandbox create --project production \
--image ghcr.io/acme/agent:1.2 \
--command "python agent.py" \
--cpu 500m \
--memory 2Gi \
--policy agent-base
image, command, cpu, and memory are required. The command runs through sh -c inside the container.
cpu and memory are Kubernetes quantities and are capped by the install's ceilings (sandbox.k8s.cpu and sandbox.k8s.memory). A request above the ceiling is rejected rather than silently clipped.
The sandbox starts as soon as it is created. It gets a slug — an immutable, URL-safe label — which is what you use to refer to it everywhere else, and what its exposed ports are published under.
Anything with nested structure — the embedded policy, embedded credentials — has no flag form and comes from a spec file instead:
nexusctl sandbox create --project production -f sandbox.yaml
Attach policies#
A sandbox is its own principal. It does not inherit a person's permissions, and there is no binding to set up: attach policies directly.
Create that sandbox again in production, but attach both the
agent-base and github-readonly policies.
nexusctl sandbox create --project production \
--image ghcr.io/acme/agent:1.2 \
--command "python agent.py" \
--cpu 500m --memory 2Gi \
--policy agent-base \
--policy github-readonly
--policy is repeatable and takes a name or a UUID. Each policy must be an org policy or one that lives in this project; the server enforces that.
With no policy attached, the sandbox runs with the network denied by default and no credentials — it can execute code, and reach nothing.
See the effective policy the platform resolved for a running sandbox:
SB=https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes/$SANDBOX_ID
curl -fsS -H "Authorization: Bearer $LENS_AGENTS_TOKEN" $SB/effective-policy
Show me the effective policy for the nightly-refactor sandbox in
the production project. What domains can it actually reach?
List and inspect#
curl -fsS -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes
List the sandboxes in the production project. Which ones are not
running, and why?
nexusctl sandbox list --project production
nexusctl sandbox get nightly-refactor --project production
nexusctl sandbox describe nightly-refactor --project production
describe is the one to reach for when something is wrong: it joins the sandbox's configuration, state, health snapshot, exposed ports, attached policies, and revisions into a single view.
Lifecycle#
stateDiagram-v2
[*] --> creating
creating --> starting
starting --> started
started --> stopping: stop
stopping --> stopped
stopped --> starting: start
started --> destroying: delete
stopped --> destroying: delete
destroying --> [*]
creating --> error
starting --> error
error --> destroying: delete
The platform tracks two fields: state is what the sandbox is observed to be doing, and desiredState is what an API caller last asked for. They differ while a transition is in flight, and errorReason explains a sandbox that landed in error.
| State | Meaning |
|---|---|
creating |
Resources are being provisioned. |
starting |
The pod exists; the supervisor has not reported ready. |
started |
Running, and reachable by exec. |
stopping |
A stop was requested. |
stopped |
Not running. Volumes and configuration survive. |
destroying |
Deletion is in progress. |
error |
Provisioning or startup failed. errorReason carries the detail. |
Stop and start#
curl -fsS -X POST -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes/$SANDBOX_ID/stop
curl -fsS -X POST -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes/$SANDBOX_ID/start
Stop the nightly-refactor sandbox in the production project.
nexusctl sandbox stop nightly-refactor --project production
nexusctl sandbox start nightly-refactor --project production
Both are idempotent. Stopping releases compute but keeps the sandbox's identity, configuration, and persistent volume — starting it again resumes on the same disk.
Delete#
curl -fsS -X DELETE -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes/$SANDBOX_ID
Delete the nightly-refactor sandbox in the production project.
nexusctl sandbox delete nightly-refactor --project production
Deletion is asynchronous: the call returns immediately and cleanup follows. Persistent volumes are deleted with the sandbox.
Update#
nexusctl sandbox update changes image, command, resources, environment, health check, or exposed ports. Each change creates a new revision and restarts the sandbox on it.
curl -fsS -X PATCH \
-H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
-H "Content-Type: application/json" \
https://agents.example.com/v1/projects/$PROJECT_ID/sandboxes/$SANDBOX_ID \
-d '{"image": "ghcr.io/acme/agent:1.3"}'
Upgrade the nightly-refactor sandbox in production to image
ghcr.io/acme/agent:1.3.
nexusctl sandbox update nightly-refactor --project production \
--image ghcr.io/acme/agent:1.3
Related#
-
Declare the whole sandbox in a file, including the embedded policy and credentials that have no flag form.
-
Run commands inside a sandbox, open an interactive shell, and use the project shell sandbox.
-
Publish an agent's web UI or API at a stable URL, with or without platform authentication.
-
Persistent volumes, HTTP health probes, revisions, and rollback.
-
What the boundary is made of, and why an agent cannot talk its way past it.
-
Cap what a sandbox can spend on inference, and see where the money went.