Sandbox AI agents with Agent Sandbox and Edera
Agent Sandbox is a Kubernetes SIG project that provides a Sandbox API for stateful, singleton workloads—the shape AI agents need: a stable identity, persistent storage, and a long-running runtime you can pause and resume.
By default, a Sandbox pod shares the host kernel. An agent that runs untrusted code, executes shell commands, or fetches arbitrary content is one container escape away from the node. Edera changes the runtime underneath: add runtimeClassName: edera and each Sandbox boots inside its own zone—a lightweight virtual machine with a dedicated kernel. Same Agent Sandbox API, same workload, now contained to its own kernel with no shared kernel surface to attack.
This guide installs the Agent Sandbox controller, runs a sandbox on Edera, and verifies the isolation. For the concepts behind isolating AI agents, see AI Agent Sandboxing.
What you’ll learn
- How Agent Sandbox and Edera fit together
- How to install the Agent Sandbox controller
- How to run a sandbox on the Edera runtime
- How to verify each sandbox has its own kernel
- How to size zones for agent workloads
Prerequisites
Before you begin, make sure you have:
An Edera-enabled Kubernetes cluster. If you don’t have one, follow Installing Edera with AWS EKS or another install guide. Confirm the runtime is registered:
kubectl get runtimeclass ederaNAME HANDLER AGE edera edera 1hkubectlconfigured against that cluster.A default StorageClass that supports dynamic provisioning (only needed for the stateful example in Step 3). On EKS, install the AWS EBS CSI driver; the in-tree
kubernetes.io/aws-ebsprovisioner used by the legacygp2class has been removed from Kubernetes and will leave PersistentVolumeClaimsPending.
How it works
Agent Sandbox uses the standard Kubernetes runtimeClassName field—the same mechanism Edera uses for any workload. When the scheduler places a Sandbox pod with runtimeClassName: edera, the Edera runtime boots a new zone with its own guest kernel and runs the sandbox container inside it.
The result is the same isolation model Edera gives any pod (see Deploy your app to Edera), applied to the Agent Sandbox lifecycle: the agent never shares the host kernel, and a container escape only reaches the zone’s kernel, not the node.
Step 1: Install the Agent Sandbox controller
Install the controller and the Sandbox CRD. Pin a release that serves the v1beta1 API (v0.5.0rc1 or newer).
export AGENT_SANDBOX_VERSION="v0.5.0rc1"
kubectl apply -f "https://github.com/kubernetes-sigs/agent-sandbox/releases/download/${AGENT_SANDBOX_VERSION}/manifest.yaml"
kubectl -n agent-sandbox-system rollout status deploy/agent-sandbox-controllerExpected Result: The controller is Running and the CRD is installed.
kubectl get crd sandboxes.agents.x-k8s.io \
-o jsonpath='{range .spec.versions[*]}{.name}{" served="}{.served}{"\n"}{end}'v1beta1 served=truev1beta1 release. Agent Sandbox v0.4.x releases serve only the older v1alpha1 API, and the project ships no conversion webhook—so the API version you install is the one you must use. Mixing a v1alpha1 controller with v1beta1 manifests fails with no matches for kind "Sandbox" in version "agents.x-k8s.io/v1beta1".Step 2: Run a sandbox on Edera
The only Edera-specific line is runtimeClassName: edera.
apiVersion: agents.x-k8s.io/v1beta1
kind: Sandbox
metadata:
name: edera-minimal
spec:
podTemplate:
spec:
runtimeClassName: edera # Run this sandbox in its own Edera zone
containers:
- name: main
image: public.ecr.aws/docker/library/alpine:3.20
command: ["sleep", "infinity"]
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
memory: "256Mi"Apply it and wait for it to be ready:
kubectl apply -f https://raw.githubusercontent.com/edera-dev/edera-agent/main/manifests/minimal-sandbox.yaml
kubectl wait --for=condition=Ready sandbox/edera-minimal --timeout=120sVerify the sandbox has its own kernel
Because each Edera zone runs a dedicated kernel, the kernel reported inside the sandbox differs from the host node’s kernel.
# Host node kernel (the Edera-patched host)
kubectl get node -o jsonpath='{.items[0].status.nodeInfo.kernelVersion}{"\n"}'
# Guest kernel inside the sandbox
kubectl exec edera-minimal -- uname -rExpected Output: two different kernels. The host carries the -edera suffix; the sandbox runs its own kernel.
6.18.34-edera # host
6.18.34 # sandbox zoneProcess isolation follows from the same fact—the sandbox has its own PID 1 and cannot see host processes:
kubectl exec edera-minimal -- ps -efClean up before moving on:
kubectl delete sandbox edera-minimalStep 3: Run a stateful agent sandbox
A real agent needs persistent storage and a heavier runtime. This example deploys a VS Code (code-server) devcontainer with a persistent workspace on a PersistentVolume—a realistic stand-in for a coding agent.
kubectl apply -f https://raw.githubusercontent.com/edera-dev/edera-agent/main/manifests/vscode-sandbox.yaml
kubectl get pvc # the workspace PVC should be Bound
kubectl logs -f sandbox-exampleThe first start takes several minutes while the devcontainer builds. Once it’s up, verify isolation the same way as Step 2:
kubectl exec sandbox-example -c devcontainer-main -- uname -r
kubectl exec sandbox-example -c devcontainer-main -- df -h /workspacesAccessing the sandbox
With VM-based runtimes, direct pod port-forward is not compatible. Use the Sandbox Router, a reverse proxy that routes requests to the right sandbox by an X-Sandbox-ID header:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/v0.5.0rc1/clients/python/agentic-sandbox-client/sandbox-router/sandbox_router.yaml
kubectl port-forward svc/sandbox-router-svc 8080:8080
curl -H "X-Sandbox-ID: sandbox-example" -H "X-Sandbox-Port: 13337" http://localhost:8080Sizing zones for agent workloads
Each sandbox is a zone—a real VM—so size it like one. Two settings matter most for agent workloads, which tend to be memory- and CPU-hungry during builds and tool execution.
Set a memory limit. Edera maps a container’s memory limit to the zone’s maximum memory. Without a limit, the zone falls back to Edera’s default maximum (1024M) regardless of the pod’s memory request—which OOM-kills heavier agents mid-task. Always set resources.limits.memory to the peak the workload needs.
Set dev.edera/cpu for multi-core agents. Match it to your CPU request so the zone gets the right vCPU count:
metadata:
annotations:
dev.edera/cpu: "4"
spec:
runtimeClassName: edera
containers:
- name: main
resources:
requests:
cpu: "4"
limits:
memory: "8Gi" # becomes the zone's max memorydev.edera/initial-memory-request annotation—see Memory ballooning with Edera. For CPU tuning, see CPU performance benchmarking.Troubleshooting
Sandbox pod is OOMKilled during startup
Problem: The agent runs out of memory while building or pulling dependencies.
Solution: Set resources.limits.memory. Without it, the zone caps at the 1024M default. See Sizing zones for agent workloads.
PersistentVolumeClaim stays Pending
Problem: No CSI driver is provisioning the volume. Solution: Install a working CSI driver and default StorageClass. On EKS, install the AWS EBS CSI driver—the legacy in-tree provisioner has been removed from Kubernetes.
no matches for kind "Sandbox" in version "agents.x-k8s.io/v1beta1"
Problem: An older Agent Sandbox controller (v1alpha1) is installed.
Solution: Reinstall a v0.5.0rc1+ release (Step 1).
kubectl exec fails with execvpe failed
Problem: The workload’s image has no shell yet (for example, while a devcontainer is still building). Solution: Wait for the build to finish, or test isolation with the minimal sandbox from Step 2.
Next steps
- Deploy your app to Edera - The general pattern for running any workload on Edera
- Enforce the Edera RuntimeClass with Kyverno - Automatically apply
runtimeClassName: ederato agent namespaces - Falco security monitoring with Edera - Add runtime threat detection inside agent zones
Summary
Key Points:
- Agent Sandbox runs on Edera by setting one field:
runtimeClassName: edera. - Each sandbox boots into its own zone with a dedicated kernel—verified by comparing
uname -rinside the sandbox against the host node. - Size zones for agent workloads: always set a memory limit, and set
dev.edera/cpufor multi-core agents. - Ready-to-apply manifests live in edera-dev/edera-agent.