Skip to content

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

  • Sandbox spec


    Declare the whole sandbox in a file, including the embedded policy and credentials that have no flag form.

  • Exec and shell


    Run commands inside a sandbox, open an interactive shell, and use the project shell sandbox.

  • Exposed ports


    Publish an agent's web UI or API at a stable URL, with or without platform authentication.

  • Storage and health


    Persistent volumes, HTTP health probes, revisions, and rollback.

  • Sandbox isolation


    What the boundary is made of, and why an agent cannot talk its way past it.

  • Spending limits


    Cap what a sandbox can spend on inference, and see where the money went.