# Quickstart Paths (gVisor, Kata, Vanilla)

> Walkthrough of the quickstart manifests for vanilla, gVisor, and Kata runtimes, plus how the examples directory organizes runnable scenarios.

- Repository: kubernetes-sigs/agent-sandbox
- GitHub: https://github.com/kubernetes-sigs/agent-sandbox
- Human wiki: https://grok-wiki.com/public/wiki/kubernetes-sigs-agent-sandbox-c3f2597a654a
- Complete Markdown: https://grok-wiki.com/public/wiki/kubernetes-sigs-agent-sandbox-c3f2597a654a/llms-full.txt

## Source Files

- `examples/quickstart/README.md`
- `examples/quickstart/gvisor.md`
- `examples/quickstart/kata-containers.md`
- `examples/hello-world-sandbox`
- `examples/README.md`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [examples/quickstart/README.md](examples/quickstart/README.md)
- [examples/quickstart/gvisor.md](examples/quickstart/gvisor.md)
- [examples/quickstart/kata-containers.md](examples/quickstart/kata-containers.md)
- [examples/hello-world-sandbox/README.md](examples/hello-world-sandbox/README.md)
- [examples/hello-world-sandbox/hello-world.yaml](examples/hello-world-sandbox/hello-world.yaml)
- [examples/hello-world-sandbox/Dockerfile](examples/hello-world-sandbox/Dockerfile)
- [examples/README.md](examples/README.md)
- [examples/kata-gke-sandbox/README.md](examples/kata-gke-sandbox/README.md)
- [clients/python/agentic-sandbox-client/python-sandbox-template.yaml](clients/python/agentic-sandbox-client/python-sandbox-template.yaml)
- [extensions/examples/sandboxwarmpool.yaml](extensions/examples/sandboxwarmpool.yaml)
</details>

# Quickstart Paths (gVisor, Kata, Vanilla)

The Agent Sandbox repository ships a single "Secure Agent Sandbox Quickstart" that walks the operator through provisioning a working cluster, installing the controller and extensions, applying a `SandboxTemplate`/`SandboxWarmPool`, deploying the router, and exercising the Python SDK. The walkthrough is structured as a linear ten-step path that branches at a single decision point: whether to use a plain KIND cluster (the **vanilla** path), a KIND cluster augmented with the `runsc`/gVisor shim (the **gVisor** path), or a minikube cluster with Kata Containers installed via Helm (the **Kata** path). Steps 3–10 are shared across all three; only cluster creation, image loading, the optional `runtimeClassName`, and cleanup differ.

This page explains how those three quickstart variants relate, what each branch changes in the shared steps, and how the larger `examples/` directory organizes other runnable scenarios that build on the same `Sandbox`, `SandboxTemplate`, `SandboxClaim`, and `SandboxWarmPool` resources.

Sources: [examples/quickstart/README.md:1-54](examples/quickstart/README.md), [examples/README.md:1-20](examples/README.md)

## Topology of the Quickstart

The quickstart README is authoritative; the gVisor and Kata documents are "branch points" that handle only cluster-runtime setup, then redirect the reader back to Step 3 of the main README. All three branches converge on the same controller install, the same `SandboxTemplate` file (with one `runtimeClassName` line conditionally uncommented), and the same Python SDK test client.

```text
                Step 1: clone repo + export env vars
                                │
                                ▼
       ┌─────────── Step 2: create cluster ───────────┐
       │                       │                      │
       ▼                       ▼                      ▼
  vanilla KIND          KIND + gVisor          minikube + Kata
  (basic cluster)    (gvisor.md branch)    (kata-containers.md branch)
       │                       │                      │
       └──────► Step 3: install controller + extensions ◄──────┘
                                │
                                ▼
       Step 4: apply python-sandbox-template.yaml
         (optionally uncomment runtimeClassName: gvisor|kata-qemu)
                                │
                                ▼
       Step 5: SandboxWarmPool  →  5.1 SandboxClaim probe
                                │
                                ▼
       Step 6–7: build, load, deploy sandbox-router
         (kind load docker-image  OR  minikube image load)
                                │
                                ▼
       Step 8–9: install Python SDK + run test_client.py
                                │
                                ▼
       Step 10: kubectl delete ns + (kind|minikube) delete
```

Sources: [examples/quickstart/README.md:25-300](examples/quickstart/README.md), [examples/quickstart/gvisor.md:1-57](examples/quickstart/gvisor.md), [examples/quickstart/kata-containers.md:1-77](examples/quickstart/kata-containers.md)

## The Vanilla Path (KIND, no isolation)

The default path uses an unmodified KIND cluster — no custom `containerd` patches, no `RuntimeClass`, no virtualization prerequisites. The user runs `kind create cluster --name agent-sandbox-demo`, installs the controller from the project root `README.md`, and proceeds straight to applying the template. The `SandboxTemplate` is applied as-is — both `runtimeClassName` lines stay commented out, so pods run under whatever default runtime KIND provides on the host.

The cluster is later torn down with `kind delete cluster --name agent-sandbox-demo` in Step 10.

Sources: [examples/quickstart/README.md:43-49](examples/quickstart/README.md), [examples/quickstart/README.md:280-300](examples/quickstart/README.md), [clients/python/agentic-sandbox-client/python-sandbox-template.yaml:1-37](clients/python/agentic-sandbox-client/python-sandbox-template.yaml)

## The gVisor Path (KIND + runsc)

The gVisor branch is documented in `examples/quickstart/gvisor.md`. It still uses KIND, but adds:

1. A Linux host prerequisite (gVisor's `runsc` only runs on Linux).
2. A `kind-config.yaml` that patches `containerd` to register the `runsc` runtime and bind-mounts the `runsc` and `containerd-shim-runsc-v1` binaries from `/usr/local/bin/` on the host into the KIND node.
3. A `RuntimeClass` named `gvisor` with handler `runsc`, applied after the cluster is up.

```yaml
# examples/quickstart/gvisor.md (cluster config excerpt)
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
    runtime_type = "io.containerd.runsc.v1"
nodes:
- role: control-plane
  extraMounts:
  - hostPath: /usr/local/bin/runsc
    containerPath: /usr/local/bin/runsc
  - hostPath: /usr/local/bin/containerd-shim-runsc-v1
    containerPath: /usr/local/bin/containerd-shim-runsc-v1
```

The guide notes that `io.containerd.runsc.v1` is gVisor's shim implementation version, not the containerd shim-protocol version. After cluster creation and `RuntimeClass` apply, the user returns to README Step 3 and uncomments `runtimeClassName: gvisor` in `python-sandbox-template.yaml` before Step 4.

Because the cluster is still KIND, Step 7's image-load command remains `kind load docker-image`, and the Step 10 cleanup is the same `kind delete cluster` as the vanilla path.

The appendix supplies gVisor-specific validation: `kubectl get pod -o jsonpath='{.spec.runtimeClassName}'` should print `gvisor`, `dmesg | head` should show gVisor's boot messages, and `ls /dev | wc -l` should report roughly 16 devices, far fewer than a normal container.

Sources: [examples/quickstart/gvisor.md:1-99](examples/quickstart/gvisor.md), [examples/quickstart/README.md:51-55](examples/quickstart/README.md), [clients/python/agentic-sandbox-client/python-sandbox-template.yaml:10-12](clients/python/agentic-sandbox-client/python-sandbox-template.yaml)

## The Kata Path (minikube + kata-deploy)

The Kata Containers branch is documented in `examples/quickstart/kata-containers.md`. Unlike gVisor, it does not use KIND — Kata needs VM-level virtualization, so the guide spins up a minikube profile named `agent-sandbox-kata` with the `kvm2` driver and `containerd` runtime:

```bash
minikube start \
  --driver=kvm2 \
  --container-runtime=containerd \
  --cpus=4 \
  --memory=8192 \
  --profile=agent-sandbox-kata
```

Kata itself is installed via its upstream Helm chart in the `kube-system` namespace, then the minikube node is labeled `kata-containers=enabled`. A quick smoke test creates a `busybox` pod with `runtimeClassName: kata-qemu` and verifies it boots a different kernel from the host.

Switching to minikube affects three places in the main README:

- Step 4: uncomment `runtimeClassName: kata-qemu` in `python-sandbox-template.yaml`.
- Step 7: use `minikube image load ${ROUTER_IMAGE} -p agent-sandbox-kata` instead of `kind load`.
- Step 10: use `minikube delete -p agent-sandbox-kata` instead of `kind delete cluster`.

The appendix validates Kata isolation by checking `runtimeClassName: kata-qemu`, by running `uname -r` inside the pod (should differ from the host kernel), and by grepping `/proc/cpuinfo` for the `hypervisor` flag.

Sources: [examples/quickstart/kata-containers.md:1-114](examples/quickstart/kata-containers.md), [examples/quickstart/README.md:165-181](examples/quickstart/README.md), [examples/quickstart/README.md:295-300](examples/quickstart/README.md)

## What the Three Paths Change

The quickstart deliberately keeps the diff between the three paths small. The table below summarizes the only steps where the path actually matters; everything else (controller install, namespace, WarmPool, SDK install, test client) is identical.

| Concern                       | Vanilla (KIND)                 | gVisor (KIND + runsc)                              | Kata (minikube + kata-deploy)                              |
|-------------------------------|--------------------------------|----------------------------------------------------|------------------------------------------------------------|
| Host requirement              | Docker only                    | Linux host with `runsc` + `containerd-shim-runsc-v1` installed | KVM/QEMU, ≥4 CPU, ≥8 GB RAM, ≥20 GB disk                   |
| Cluster command (Step 2)      | `kind create cluster …`        | `kind create cluster … --config kind-config.yaml`  | `minikube start --driver=kvm2 --container-runtime=containerd --profile=agent-sandbox-kata` |
| Extra cluster-level resource  | None                           | `RuntimeClass/gvisor` (handler `runsc`)            | Kata Helm chart in `kube-system`, node label `kata-containers=enabled` |
| `python-sandbox-template.yaml`| Both `runtimeClassName` lines stay commented | Uncomment `runtimeClassName: gvisor`     | Uncomment `runtimeClassName: kata-qemu`                    |
| Router image load (Step 7.1)  | `kind load docker-image …`     | `kind load docker-image …`                         | `minikube image load … -p agent-sandbox-kata`              |
| Cleanup (Step 10)             | `kind delete cluster --name agent-sandbox-demo` | same as vanilla                       | `minikube delete -p agent-sandbox-kata`                    |
| Isolation validation          | None                           | `dmesg` shows gVisor boot, `/dev` ≈16 entries      | `uname -r` differs from host, `/proc/cpuinfo` has `hypervisor` |

Sources: [examples/quickstart/README.md:43-181](examples/quickstart/README.md), [examples/quickstart/gvisor.md:17-93](examples/quickstart/gvisor.md), [examples/quickstart/kata-containers.md:19-113](examples/quickstart/kata-containers.md)

## The Shared Backbone: Template, WarmPool, Router, SDK

All three quickstart paths converge on the same `SandboxTemplate` file at `clients/python/agentic-sandbox-client/python-sandbox-template.yaml`. The template is `extensions.agents.x-k8s.io/v1beta1`, parameterized by `${SANDBOX_NAMESPACE}` and `${SANDBOX_TEMPLATE_NAME}` (substituted in via `envsubst`), and embeds a `podTemplate.spec` whose two `runtimeClassName` candidates are intentionally left commented for the operator to choose:

```yaml
# clients/python/agentic-sandbox-client/python-sandbox-template.yaml
spec:
  podTemplate:
    spec:
      # Optional: uncomment one of the lines below to enable sandbox isolation.
      # runtimeClassName: gvisor      # gVisor (see examples/quickstart/gvisor.md)
      # runtimeClassName: kata-qemu   # Kata Containers (see examples/quickstart/kata-containers.md)
      containers:
      - name: python-runtime
        image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/python-runtime-sandbox:latest-main
        ports:
        - containerPort: 8888
```

Step 5 then layers a `SandboxWarmPool` (`extensions.agents.x-k8s.io/v1alpha1`) on top of that template with two replicas, and Step 5.1 proves the WarmPool works by creating a one-off `SandboxClaim` and inspecting the `agents.x-k8s.io/pod-name` annotation. The README explicitly documents that WarmPool produces *pods* (not Sandbox resources), labels them `agents.x-k8s.io/pool=<hash>`, and that on claim the controller swaps that label for `sandbox-name-hash=<hash>` and refills the pool to maintain replica count.

The router (`clients/python/agentic-sandbox-client/sandbox-router/`) is built locally as `${ROUTER_IMAGE}` (default `sandbox-router:local`), loaded into whichever cluster type was created, then applied with `imagePullPolicy: Never` uncommented so the cluster does not try to pull `sandbox-router:local` from a registry. Step 7.4 health-checks it via `kubectl port-forward svc/sandbox-router-svc 8080:8080` and a `curl /healthz` that expects `{"status":"ok"}`. Step 8 installs the Python SDK with `pip install -e clients/python/agentic-sandbox-client`, and Step 9 runs `test_client.py --template-name python-runtime-template --namespace agent-sandbox-demo` to exercise the full lifecycle.

Step 9.2 contains a small shell snippet that compares `SandboxClaim.metadata.creationTimestamp` with the underlying pod's `metadata.creationTimestamp` — if the pod predates the claim, the test reports "Pod was PRE-WARMED from WarmPool!" — which is the quickstart's only quantitative claim about WarmPool performance.

Sources: [clients/python/agentic-sandbox-client/python-sandbox-template.yaml:1-37](clients/python/agentic-sandbox-client/python-sandbox-template.yaml), [examples/quickstart/README.md:76-274](examples/quickstart/README.md), [extensions/examples/sandboxwarmpool.yaml:1-11](extensions/examples/sandboxwarmpool.yaml)

## Where `hello-world-sandbox` Fits

`examples/hello-world-sandbox/` is a deliberately minimal example that uses the core `Sandbox` CRD directly, without the extensions-layer template/claim/warmpool machinery and without isolation. Its `hello-world.yaml` is a single `agents.x-k8s.io/v1alpha1 Sandbox` with an inline `podTemplate.spec`:

```yaml
# examples/hello-world-sandbox/hello-world.yaml
apiVersion: agents.x-k8s.io/v1alpha1
kind: Sandbox
metadata:
  name: hello-world
spec:
  podTemplate:
    spec:
      containers:
      - name: my-container
        image: ${IMAGE}
      restartPolicy: Never
```

The accompanying README walks through building a tiny `alpine:latest` image whose entrypoint is `echo 'Hello, World from Kubernetes!' && sleep 3600`, pushing it to a Google Artifact Registry repository, and applying the manifest via `cat hello-world.yaml | envsubst | kubectl apply -f -`. Verification uses `kubectl get sandbox hello-world`, `kubectl describe pod hello-world`, and `kubectl logs hello-world -c my-container`. This example is what the quickstart README's `Sandbox` bullet refers to as "Core isolated environment for running untrusted code" — it shows that the controller can reconcile a bare `Sandbox` into a `Pod` without any of the extensions API surface.

Sources: [examples/hello-world-sandbox/README.md:1-87](examples/hello-world-sandbox/README.md), [examples/hello-world-sandbox/hello-world.yaml:1-11](examples/hello-world-sandbox/hello-world.yaml), [examples/hello-world-sandbox/Dockerfile:1-5](examples/hello-world-sandbox/Dockerfile)

## How `examples/` Is Organized

`examples/README.md` enumerates the runnable scenarios under `examples/`. They fall into a few rough groups, all of which depend on the same controller installed by the quickstart:

| Category                                   | Subdirectories                                                                                                                                |
|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
| Onboarding / quickstart                    | `quickstart/`, `hello-world-sandbox/`, `python-sdk-quickstart/`                                                                               |
| Runtime images for sandboxed workloads     | `python-runtime-sandbox/`, `jupyterlab/`, `vscode-sandbox/`, `chrome-sandbox/`, `aio-sandbox/`, `openclaw-sandbox/`                            |
| Agent framework integrations               | `code-interpreter-agent-on-adk/` (Google ADK), `langchain/` (LangGraph), `hermes-agent/`, `gemini-cu-sandbox/`, `kueue-agent-sandbox/`, `ray-integration/`, `analytics-tool/` |
| Operational / scaling / policy patterns    | `hpa-swp-scaling/`, `manual-pdb/`, `policy/`, `composing-sandbox-nw-policies/`, `sandbox-ksa/`                                                 |
| Alternative cluster runtimes               | `kata-gke-sandbox/`                                                                                                                            |

`kata-gke-sandbox/` is worth calling out alongside the quickstart's Kata path: it covers Kata Containers on managed **GKE** rather than local **minikube**. It documents the hardware constraints (Intel N2 machine type, Ubuntu node image, nested-virt-supporting zone), runs a `setup.sh` to provision the cluster, and then applies `sandbox-kata-gke.yaml` — a core `Sandbox` (not a `SandboxClaim`) that pins `runtimeClassName: kata-qemu` and uses a `nodeSelector` of `cloud.google.com/gke-os-distribution: ubuntu` to land on the Kata-capable node pool. Its isolation check is the same `uname -r` comparison the quickstart Kata appendix uses. It is the production-flavored counterpart to the local `quickstart/kata-containers.md` walkthrough.

Sources: [examples/README.md:1-20](examples/README.md), [examples/kata-gke-sandbox/README.md:1-128](examples/kata-gke-sandbox/README.md)

## Reading the Quickstart as a Decision Tree

When picking which path to follow, the prerequisites listed at the tops of the three documents are the real differentiator: the vanilla path needs only Docker and kubectl, the gVisor path additionally requires a Linux host with `runsc` installed, and the Kata path requires KVM-capable hardware plus minikube and Helm. The body of the quickstart is otherwise the same — the controller, extensions, template, warm pool, router, SDK, and test script do not change behavior between paths. The chosen path determines the *isolation boundary of the sandbox pod*, not the *shape of the Agent Sandbox API* the operator interacts with.

Once any path is finished, the broader `examples/` directory provides drop-in workloads (Python runtime, JupyterLab, VSCode, Chrome, OpenClaw) and integration patterns (LangGraph, ADK, Ray, HPA scaling, network policy) that all consume the same `Sandbox` / `SandboxTemplate` / `SandboxClaim` / `SandboxWarmPool` resources the quickstart left running.

Sources: [examples/quickstart/README.md:16-23](examples/quickstart/README.md), [examples/quickstart/gvisor.md:6-10](examples/quickstart/gvisor.md), [examples/quickstart/kata-containers.md:6-16](examples/quickstart/kata-containers.md), [examples/README.md:1-20](examples/README.md)
