Run sandboxes
Create standalone sandboxes with the Nimbus SDK — root images, owners, labels, listing, and what the API redacts.
A sandbox is a single isolated world: a root filesystem and a process to run, with deny-by-default network egress, created for one purpose and addressed by id for its whole life. This guide covers standalone sandboxes — the ones you create directly, without a service definition. New to the model? Start with the agent sandbox quickstart.
All examples assume a configured client:
import { Nimbus } from "@nimbus/nimbus";
const nimbus = new Nimbus({
endpoint: "http://localhost:8080",
tenantId: "demo",
token: process.env.NIMBUS_TOKEN,
});Endpoint and credential discovery (environment variables, the local credential file) is covered in the SDK resources reference.
Create a standalone sandbox
const sandbox = await nimbus.sandboxes.create({
profile: "worker", // or "desktop"
spec: {
owner: { kind: "standalone", displayName: "batch-job" },
backend: "container", // or "krun"
root: {
kind: "oci_image",
source: { kind: "reference", reference: "docker.io/library/python:3.12-slim" },
},
process: { argv: ["python", "job.py"] },
},
labels: { purpose: "batch" },
});
const running = await nimbus.sandboxes.get({ id: sandbox.metadata.id });
console.log(running.status.lifecycleState, running.status.endpoints);
await nimbus.sandboxes.stop({ id: sandbox.metadata.id });The spec answers two separate questions:
- What root material runs? An OCI image, named by reference (a registry image, as above). The public create call accepts an image reference only — prepared root filesystems and Dockerfile build contexts are operator-only inputs and are rejected by the create call, so build and push the image yourself, then reference the published tag.
- Who owns it?
owner.kind: "standalone"means you created it directly, with an optional display name. Sandboxes launched as a service's backend instead carry{ kind: "service", serviceName }owner metadata — see Manage services. Creating a standalone sandbox never implicitly registers a service name.
Choose an isolation backend
backend selects the isolation mechanism, not the resource semantics —
the same spec, id, lifecycle, and session rules apply either way:
"container"— OCI container isolation, driven throughcrun. This is the default backend for standalone sandboxes."krun"— libkrun-based microVM isolation with per-sandbox egress enforcement. It executes workloads on Linux hosts — its launch stands up a deny-by-default network namespace and an egress proxy first — and is the default backend for services run throughnimbus compose.
Both run on Linux hosts with deny-by-default outbound network access; on
macOS and WSL2, nimbus machine provides the hosting Linux VM. See
current capabilities.
List and filter
Labels are the filtering handle for throwaway resources:
const batch = await nimbus.sandboxes.list({
labelKey: "purpose",
labelValue: "batch",
});There is deliberately no resolve-sandbox-by-name API — a sandbox id is a receipt, not a dependency contract. If other code needs to find the workload by name, promote it to a service.
What comes back redacted
Sandbox responses redact launch inputs: process.argv and
process.environment come back as { redacted: true, valueCount: n }
rather than their values. Don't round-trip secrets through sandbox reads —
what you launched with is not readable back.
Related pages
- Open sessions — lease scoped, expiring sessions to a running sandbox.
- Services, sandboxes, and sessions — the design rationale.
- SDK resources reference — full type and method signatures.