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