A small platform that gives each developer or AI agent its own persistent, isolated development sandbox on OpenShift, backed by Red Hat build of Agent Sandbox and OpenShift sandboxed containers.
Each sandbox can run generated Python/shell code, install packages, and keep files across
restarts — and runs inside a Kata VM (runtimeClassName: kata) for hardware-level
isolation of untrusted or LLM-generated code.
This is the "self-service AI Python workspace" use case. It exercises the documented Agent Sandbox capabilities, not just "can a pod start":
| Capability (from the docs) | How this demo shows it |
|---|---|
| Fast provisioning — warm pools | A SandboxWarmPool pre-warms Kata pods; "New sandbox" claims one in ~1s vs a cold pull |
| Persistent state — files survive restarts | volumeClaimTemplates mounts a PVC at /workspace; installed packages + files persist |
| Hibernation — idle cost savings | Idle sandboxes are paused/shut down and resumed with state intact |
| Stable identity — reconnectable sessions | Stable hostname + PVC per sandbox; the same environment comes back on reconnect |
| Hardware isolation — Kata VM | runtimeClassName: kata runs the workload in a lightweight VM with a dedicated kernel |
Full mapping to the success-criteria table is in docs/RUNBOOK.md.
Browser (xterm.js terminal + file tree)
│ HTTPS + WebSocket
▼
┌───────────────────────────────────────────────┐
│ Platform control-plane (FastAPI) │ deploy/base/platform.yaml
│ • POST /api/sandboxes → create SandboxClaim │
│ • WS /api/sandboxes/{id}/pty (terminal) │
│ • GET/PUT /api/sandboxes/{id}/files │
│ • POST /api/sandboxes/{id}/hibernate|resume │
│ • serves the web UI │
└───────────────┬───────────────────────────────┘
│ creates CRs (K8s API) │ proxies PTY/files
▼ ▼
SandboxClaim ─▶ SandboxWarmPool Sandbox Router (headers:
│ (pre-warmed Kata X-Sandbox-ID / X-Sandbox-Port)
│ pods, replicas: N) │ deploy/base/router.yaml
▼ ▼
Sandbox (agents.x-k8s.io/v1beta1) ┌────────────────────────────┐
runtimeClassName: kata ───────▶│ Workspace pod (Kata VM) │
volumeClaimTemplates → /workspace │ workspace-agent (FastAPI) │
│ • WS /pty (shell) │
│ • /files (list/read/wr) │
│ Python + pip + tools │
│ PVC mounted at /workspace │
└────────────────────────────┘
OpenShift sandboxed containers
runs this in a dedicated-kernel VM
Why a workspace-agent inside the pod (instead of kubectl exec)? Because Kata pods are
reached through the Sandbox Router over HTTP/WebSocket (X-Sandbox-ID/X-Sandbox-Port
headers), which is the connectivity path the upstream examples use for kata/gvisor
runtimes. The agent exposes a PTY + file API on a fixed port that the router forwards to.
Field names below were verified against the Red Hat build of Agent Sandbox operator
v0.9.0 on a live OCP 4.20 cluster (they differ from the GKE/upstream docs — notably the
extensions group is v1beta1, and a claim references a warm pool, not a template):
| Resource | apiVersion | Role here |
|---|---|---|
SandboxTemplate |
extensions.agents.x-k8s.io/v1beta1 |
Reusable blueprint: the Python workspace pod, runtimeClassName: kata |
SandboxWarmPool |
extensions.agents.x-k8s.io/v1beta1 |
Keeps replicas pre-warmed sandboxes for millisecond allocation |
SandboxClaim |
extensions.agents.x-k8s.io/v1beta1 |
The platform creates one per user; spec.warmPoolRef binds a warm pod, exposing status.sandbox.name + podIPs |
Sandbox |
agents.x-k8s.io/v1beta1 |
The pod itself: podTemplate, volumeClaimTemplates, operatingMode, shutdownPolicy |
Hibernation — confirmed. v0.9.0 provides real pause/resume via
Sandbox.spec.operatingMode: Running│Suspended.Suspendedreleases the pod (and its VM) while retaining the Sandbox and its PVC; flipping back toRunningresumes with state intact.shutdownPolicy: Retainkeeps the PVC if the Sandbox is deleted. The platform's/hibernateand/resumedriveoperatingModedirectly.
install.sh One-shot installer: operators → images → platform → route
deploy/
base/ kustomize base (Kata): SandboxTemplate, SandboxWarmPool, Sandbox Router, platform
persistent/ A standalone Sandbox with volumeClaimTemplates (persistence/hibernation demo)
overlays/kata-remote/ Cloud peer pods (runtimeClassName: kata-remote)
overlays/dev-runc/ Strip runtimeClassName for clusters without OpenShift sandboxed containers
workspace-image/ The sandbox image: Python + workspace-agent (Containerfile)
platform/ The control-plane service (FastAPI) + web UI (xterm.js + file tree)
docs/
INSTALL.md Install the operators, create the RuntimeClass, build/push images
RUNBOOK.md The demo script, mapped to the success-criteria table
scripts/ Convenience scripts (build/push, port-forward, smoke test)
- OpenShift Container Platform — verified on 4.20; any recent 4.x the Agent Sandbox operator supports should work.
- cluster-admin access, and
oclogged in (oc whoamiworks). Installing operators and creating aKataConfigneed it. - A default
StorageClasswithReadWriteOncesupport — persistent sandboxes bind a PVC at/workspace. Without one, the persistence/hibernation/reconnect demos won't run. (On AWS:oc patch storageclass gp3-csi -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'.) - Red Hat build of Agent Sandbox operator —
install.shinstalls it automatically (auto-detected from the catalog; verified as packageagent-sandbox-operator, channelpreview-0.9, fromredhat-operators). It provides the four CRDs and controllers. - Image build/host path —
install.shbuilds both images in-cluster via BuildConfigs into the internal registry (needs the OpenShift image registry enabled), or push your own and edit theimage:refs. - Spare worker capacity — the warm pool keeps 2 idle sandboxes hot (~0.5–1 Gi each), plus each active sandbox.
The isolation mode decides what runs the sandbox pod and therefore what extra
infrastructure you need. Pick with ./install.sh --isolation <mode>.
Mode (--isolation) |
Runtime | Extra prerequisites | Isolation you get |
|---|---|---|---|
none |
default CRI-O + runc |
None beyond the common list — runs on any cluster | Standard containers (namespaces, cgroups, SCC, seccomp). Shared host kernel. Trusted code only. |
kata |
Kata VM, nested on the node | Bare-metal x86_64/s390x nodes (or cloud *.metal instances) exposing virtualization/KVM. OpenShift sandboxed containers operator + a reconciled KataConfig, which creates the kata RuntimeClass. |
VM per sandbox with its own guest kernel. Safe for untrusted / LLM-generated code. |
kata-remote |
Kata VM as a separate cloud instance (peer pods) | Cloud cluster (AWS / Azure / GCP / IBM Z). OpenShift sandboxed containers operator + peer-pods configuration the manifests do not set up: a cloud-credentials Secret, peer-pods/instance-type config, and a KataConfig with enablePeerPods: true (creates the kata-remote RuntimeClass). Also cloud-account permission to launch instances. |
Same VM/guest-kernel isolation as kata, without needing bare-metal nodes. |
Notes:
- Bare metal is not required for VM isolation — standard cloud VMs can't nest a Kata VM,
so on AWS/Azure/GCP you use
kata-remote(peer pods), which launches the sandbox as its own cloud instance. Bare metal (or*.metalcloud shapes) is only required for plainkata. install.shinstalls the sandboxed-containers operator and (forkata) creates aKataConfigfor you; forkata-remoteit stops short of provisioning cloud credentials — that part is account-specific and must be done per the OSC docs first.- Operator install details, the
KataConfig/RuntimeClass steps, and SCC notes are indocs/INSTALL.md.
One-shot install onto a fresh cluster (operators → images → platform → route), logged in as cluster-admin:
./install.sh --isolation kata # bare-metal Kata VMs (default)
./install.sh --isolation kata-remote # cloud peer pods
./install.sh --isolation none # any cluster, no VM isolation (dev)Then follow docs/RUNBOOK.md. Prefer to do it by hand, or need to
understand each step? See docs/INSTALL.md.