Skip to content

Back to the catalog

Kubernetes Agent Sandbox on AWS EKS (Step-by-Step Guide)
devopscube.comwriteup

Kubernetes Agent Sandbox on AWS EKS (Step-by-Step Guide)

Tutorial on setting up Kubernetes Agent Sandbox (kubernetes-sigs/agent-sandbox) with gVisor on an AWS EKS cluster. It runs a troubleshooting AI agent backend inside a sandbox using SandboxTemplate, SandboxWarmpool and SandboxClaim, and runs untrusted Python through the k8s-agent-sandbox SDK and Sandbox Router. Probes show blocked /etc/shadow reads, setuid and service account token access, plus host process isolation. It also covers scheduled deletion and suspend/resume with persistent volumes.

TL;DR Walks through deploying Kubernetes Agent Sandbox with gVisor on EKS to isolate an AI agent and run untrusted LLM code, with isolation tests.
Also seen from another angle🧠 AI →
Document

What it is

A walkthrough of kubernetes-sigs/agent-sandbox on an EKS cluster with gVisor, using the repo github.com/techiescamp/kubernetes-ai-projects (folder agent-sandbox). It covers two uses: running a troubleshooting agent's backend in a sandbox, and running untrusted Python through the k8s-agent-sandbox SDK.

How it works

The SandboxTemplate podTemplate is a copy of a Deployment's template.spec with one extra field, runtimeClassName. Without it, the sandbox runs on the default runc runtime, not gVisor.

A SandboxWarmpool keeps pre-started pods. A SandboxClaim takes one, and the pool starts a replacement. In the agent demo the namespace shows three backend pods: two warm, one claimed.

The sandboxed pod is not reachable directly, so the SDK uses two paths:

flowchart LR
  SDK[sandbox.py] -->|kubeconfig: create claim| API[Kubernetes API]
  SDK -->|port-forward 8080 + ROUTER_AUTH_TOKEN| R[Sandbox Router]
  R -->|exec code| P[gVisor sandbox pod]

In the agent demo the frontend reaches the backend through a normal internal service, so the router is not involved there.

Preconditions / Affected

  • EKS cluster with a gvisor RuntimeClass (handler runsc), Pod Identity and the EBS CSI add-on, kubectl, AWS CLI with IAM and EKS permissions, Python 3.
  • The agent demo calls AWS Bedrock models through Pod Identity, set up by scripts/setup-pod-identity.sh create.
  • The controller version comes from the latest GitHub release at install time. The page pins none.

What to do

Check the runtime, then install the controller:

kubectl get runtimeclass gvisor
VERSION=$(curl -s https://api.github.com/repos/kubernetes-sigs/agent-sandbox/releases/latest | jq -r '.tag_name')
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/$VERSION/sandbox.yaml
kubectl apply -f https://github.com/kubernetes-sigs/agent-sandbox/releases/download/$VERSION/extensions.yaml

Create the router auth token, then apply sandbox-router.yaml:

kubectl create secret generic sandbox-router-auth \
  --namespace agent-sandbox-system \
  --from-literal=auth-token="$(openssl rand -hex 32)"

Run the SDK test from python-sdk:

kubectl -n agent-sandbox-system port-forward svc/sandbox-router-svc 8080:8080
pip install k8s-agent-sandbox
kubectl apply -f .
export ROUTER_AUTH_TOKEN=<your-token>
python3 sandbox.py

The probe tries four things. Reading /etc/shadow fails with a permission error. setuid(0) fails with "Operation not permitted". The service account token file is absent. A process started in the sandbox has PID 3 and the node's process list can't show it. The page credits Pod Security for the first three blocks and gVisor for the last. The script prints a ps | grep command to run on the node to confirm the probe is not visible.

Scheduled deletion uses shutdownPolicy: Delete and shutdownTime on a Sandbox. The demo sandbox terminated at about 5 minutes.

Suspend and resume patch spec.operatingMode:

kubectl patch sandbox suspend-resume-demo --type=merge -p '{"spec":{"operatingMode":"Suspended"}}'
kubectl patch sandbox suspend-resume-demo --type=merge -p '{"spec":{"operatingMode":"Running"}}'

Suspending terminates the pod and sets Ready to False (reason SandboxSuspended). Resuming creates a new pod. A file written under a volumeClaimTemplates mount at /workspace survived. Without a PV, data is lost on suspend.

Caveats

  • The sandbox manifests use agents.x-k8s.io/v1beta1.
  • The scheduled-deletion example is inconsistent: it computes the time with GNU date -d, but the manifest uses BSD-style date -u -v+5M, so the latter fails on Linux. The -v+1H and -v+1w variants are BSD syntax too.
  • The default StorageClass must be set (the page patches one) for the PVC and Postgres to bind.
  • Cleanup uses kubectl delete ns ... --force, and setup-pod-identity.sh cleanup removes the IAM role and association.
  • Isolation is shown only by four probes. The page has no threat model, network egress test or performance data. It adds a NetworkPolicy manifest but does not explain it.

Organisations named here

  • EKS Pod Identity
  • SandboxClaim
  • Sandbox Router
  • SandboxTemplate
  • SandboxWarmpool

Technologies named here

  • Kubernetes on AWS EKS
  • Kubernetes Agent Sandbox
  • Sandbox Router
  • Default container runtime runc
  • k8s-agent-sandbox Python SDK
  • EKS Pod Identity
  • Kubernetes RBAC and NetworkPolicy manifests
  • Kubernetes Pod Security
  • kubectl, AWS CLI, Kustomize
  • techiescamp/kubernetes-ai-projects GitHub repository
  • Kubernetes
  • gVisor
  • AWS
  • AWS Bedrock
  • Python
  • PostgreSQL

Techniques named here

  • Human approval step
  • Pre-warmed sandbox pools
  • Sandbox escape