Skip to content
Talk to our solutions team

Sandbox

Sandbox is the platform’s isolation-and-clone engine. It does two things: clone a base into a writable workspace, and run commands inside a confined environment, returning the exit code, streams, resource usage and a first-class reason for termination.

This is OS and VM isolation: namespaces, jails, microVMs, a WASI capability surface. It is a different thing from the in-process limiter behind Script, which has no OS boundary. Where Script confines what a script can call, Sandbox confines what a process can touch.

your caller
│ a resolved profile: tier, mounts, network, limits
▼
┌──────────────────────────────────┐
│ Sandbox engine │ stateless
│ clone a base ──▶ exec a command │ enforces a profile;
│ │ never computes one
└───────────────┬──────────────────┘
▼
process · wasm · host · container · microVM

The engine is deliberately stateless and policy-free. Which tier, which base, whose credentials, what to audit, all decided upstream and handed in resolved. The engine enforces a profile; it never derives one. That split is what keeps the security-critical part small enough to audit.

TierMechanismBoundary
processNone. The dev escape hatchNo isolation
wasmwazero WASI, cancellableCapability surface, no host syscalls
hostLandlock LSM + seccomp, or bubblewrap namespacesKernel-enforced filesystem and syscall limits
containercrun with a generated bundle, overlayfs CoWNamespaces, cgroups, seccomp
microvmFirecracker with a guest kernelHardware-assisted, separate kernel

Tiers ascend in isolation strength and in cost. Selection picks the most restrictive tier available on the host unless you pin one, the default leans safe rather than fast.

The backends compiled into your build, and what each can enforce:

Terminal window
kis sandbox backends
BACKEND TIERS CoW SHELL NATIVE NETWORK SECCOMP SNAPSHOT
bubblewrap host yes yes yes - - -
firecracker microvm yes - yes - yes yes
landlock host yes yes yes - - -
oci container yes yes yes - yes -
process process yes yes yes - - -
wasm wasm yes - - - - -

Read that matrix before designing around a capability. firecracker has snapshots and landlock does not; wasm supports neither shells nor native binaries. A backend that cannot enforce what you asked for refuses rather than running weaker: see Security.

Availability is platform-dependent: landlock, bubblewrap, oci and firecracker are Linux; seatbelt and applecontainer are macOS; process and wasm are everywhere.

A clone is copy-on-write where the platform supports it, APFS clonefile, reflinks, overlayfs , so materialising a workspace from a base is O(1) rather than a copy, and divergence is stored as a delta.

Bases are refcounted: a clone holds a reference, destroy releases it, and a base is freed only when its last clone is gone. Destroy is idempotent, so a retried teardown is safe.

Each workspace gets a randomly minted id, and a clone refuses a destination that already holds content. A workspace id becomes a directory name under the work directory, so those two properties together guarantee that one workspace never materialises on top of another, a clash fails the clone rather than merging.

If you supply your own WorkspaceID, it is validated before use. It reaches a container name, a runtime container id and a path join, so it is checked once at the boundary rather than trusted by each consumer separately.

run executes one command and exits. For work that needs continuity, a durable shell keeps working directory and environment across commands within a session:

Terminal window
kis sandbox backends # what this build can enforce
kis sandbox create # create a session, print its id
kis sandbox exec # run a command in a session
kis sandbox shell # a durable shell reading lines from stdin
kis sandbox session # manage sessions: create, list, destroy
kis sandbox run # clone a base, run one command

Not every backend supports shells, firecracker and wasm do not, per the matrix above.

On the container tier a session is a detached keep-alive container. Commands exec into it, so state left by one command, a working directory, an environment variable, a file in /tmp, is still there for the next.

A session can also be reattached: the runtime is asked for the container’s state and the handle is rebuilt from it, so a client that reconnects finds the same session rather than a fresh one. One-shot run is unchanged and still starts and exits.

An exec can request a real pseudo-terminal rather than plain pipes. That is what makes an interactive shell behave like one: line editing, job control, and programs that check whether they are attached to a terminal.

TierInteractive TTY
processyes
host (seatbelt)yes
containeryes
microVMyes. The terminal size is forwarded over the wire and resizes are tracked
wasmno

Terminal size is part of the request, and later resizes are propagated, so a window that changes mid-session reflows rather than staying at its opening dimensions.

  • Security: the profile model, deny-all defaults and escape hatches
  • Script: the in-process script sandbox, and when to use which