Open Source · Cloud Agnostic
A starter kit for running isolated, per-conversation AI agent sandboxes on Kubernetes.
This kit is a thin, opinionated layer on top of Kubernetes that gives you a two-endpoint API for agent sandbox lifecycle: create one, destroy one. Everything else — file persistence, authentication, network isolation, observability — is handled by the kit.
It's built on kubernetes-sigs/agent-sandbox for CRD-based sandbox management, a cloud-agnostic storage layer (GCS / Azure Blob + NFS + Postgres), and a zero-trust networking model where sandboxes can only reach a single authenticated gateway.
This kit makes strong choices. If your requirements differ, fork and change them — the codebase is ~2,000 lines of Go, not a framework.
One sandbox per conversation. Each agent conversation gets a dedicated Kubernetes pod. The pod is created when the conversation starts and destroyed when it ends. No sharing, no reuse across users.
CRDs over raw Kubernetes primitives. You could build this with StatefulSets, PVCs, and a custom controller. The agent-sandbox CRD gives you warm pools, hibernation, and template-based provisioning for free, maintained by the Kubernetes SIG community instead of your team.
NFS + object storage over PVC-per-user. PVCs are opaque — you can't read files from them without mounting them to a running pod. NFS gives your backend direct file access. Object storage gives you durability, cross-region replication, and presigned uploads. NFS is the cache, object storage is the source of truth.
gVisor by default, Kata for gov cloud. For teams running trusted code (your own scripts, not arbitrary LLM-generated code), gVisor provides sufficient kernel-level isolation with one line of GKE config. Kata Containers (hardware-level isolation) is a configuration flag away for FedRAMP / NIST 800-53 compliance.
Gateway pattern over direct sandbox-to-backend. The sandbox is untrusted. Even with trusted scripts, an LLM agent can modify them or craft its own HTTP requests. A gateway between sandbox and backend validates token scope, overrides identity claims, enforces request schema, and rate-limits per session.
Short-lived, conversation-scoped tokens. No long-lived API keys. JWTs are minted per-sandbox with user ID, conversation ID, and allowed operations baked in. Revoked on teardown, expire within an hour.
Deny-all egress. Sandbox pods cannot reach the internet, cannot resolve external DNS, cannot talk to other sandboxes. The only allowed destination is the auth gateway's ClusterIP.
Cloud-agnostic from day one. Every component abstracts GCP vs Azure behind a config flag. Same Helm chart, different values file.
- Kubernetes cluster (GKE or AKS) with
kubectlaccess - Helm v3
- Docker
git clone https://github.com/xors-software/ai-starter.git
cd ai-starter
chmod +x scripts/quickstart.sh
./scripts/quickstart.sh gcp # or: ./scripts/quickstart.sh azure# 1. Install the agent-sandbox controller CRDs
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/main/config/crd/bases/
# 2. Build container images
make docker-build REGISTRY=ghcr.io/xors-software
# 3. Push images
make docker-push REGISTRY=ghcr.io/xors-software
# 4. Deploy with Helm
helm upgrade --install agent-sandbox-kit charts/agent-sandbox-kit/ \
-f charts/agent-sandbox-kit/values-gcp.yaml \
--set orchestrator.env.TOKEN_SIGNING_KEY=$(openssl rand -hex 32)
# 5. Run database migrations (using golang-migrate)
migrate -path migrations/ -database $DATABASE_URL up
# 6. Validate security
./tests/security/validate_isolation.sh# Create a sandbox
curl -X POST http://localhost:8080/sandbox \
-H "Content-Type: application/json" \
-d '{"user_id": "alice", "conversation_id": "conv-001"}'
# Response:
# {
# "sandbox_id": "sandbox-a1b2c3",
# "conversation_id": "conv-001",
# "status": "creating",
# "token": "eyJhbGciOiJIUzI1NiIs..."
# }
# Check status
curl http://localhost:8080/sandbox/sandbox-a1b2c3
# Destroy when done
curl -X DELETE http://localhost:8080/sandbox/sandbox-a1b2c3┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Your App │────▶│ Orchestrator │────▶│ K8s API Server │
│ │ │ (REST API) │ │ (SandboxClaim) │
└─────────────┘ └──────┬───────┘ └────────┬─────────┘
│ │
mint │ allocate │ from warm pool
token │ │
▼ ▼
┌──────────────┐ ┌─────────────────┐
│ Token Service│ │ Sandbox Pod │
│ (JWT) │ │ ┌────────────┐ │
└──────────────┘ │ │ Agent │ │
│ │ Runtime │ │
┌─────────────────┐ │ └─────┬──────┘ │
│ Auth Gateway │◀──────│────────┘ │
│ (validates, │ │ /data/user (NFS)│
│ rate-limits, │ │ /data/scratch │
│ proxies) │ └─────────────────┘
└────────┬────────┘ ▲
│ │
▼ │ hydrate / sync-back
┌─────────────────┐ ┌────────┴────────┐
│ Your Backend │ │ Storage Sync │
│ │ │ (init + sidecar)│
└─────────────────┘ └────────┬────────┘
│
┌────────┴────────┐
│ Object Storage │
│ (GCS / Azure) │
└─────────────────┘
| Layer | What It Does | Components |
|---|---|---|
| Runtime | Manages sandbox pod lifecycle | SandboxTemplate, SandboxWarmPool, SandboxClaim |
| Storage | Persists user files across conversations | Object storage + NFS + Postgres metadata |
| Auth & Network | Zero-trust sandbox networking | JWT tokens, auth gateway, NetworkPolicy |
| Orchestration | Ties everything together | REST API orchestrator |
ai-starter/
├── charts/ # Helm chart
│ └── agent-sandbox-kit/
│ ├── templates/ # K8s resource templates
│ ├── values.yaml # Default values
│ ├── values-gcp.yaml # GCP-specific
│ └── values-azure.yaml # Azure / Azure Gov
├── manifests/ # Raw K8s manifests (non-Helm)
│ ├── sandbox-template.yaml # SandboxTemplate CRD
│ ├── warm-pool.yaml # SandboxWarmPool CRD
│ ├── network-policy.yaml # Zero-trust egress rules
│ ├── rbac.yaml # ServiceAccounts and roles
│ ├── data-retention-cronjob.yaml # Stale data archival
│ └── grafana-dashboard.json # Monitoring dashboard
├── services/
│ ├── orchestrator/ # Sandbox lifecycle API
│ ├── auth-gateway/ # Token validation proxy
│ └── storage-sync/ # File hydration & sync-back
├── lib/
│ ├── storage/ # Cloud-agnostic storage interface
│ │ ├── storage.go # Interface + factory
│ │ ├── gcs.go # Google Cloud Storage
│ │ └── azure.go # Azure Blob Storage
│ └── token/ # JWT session tokens
│ └── token.go # Mint, validate, revoke
├── migrations/ # Postgres schema (golang-migrate)
│ ├── 000001_create_file_metadata.up.sql
│ ├── 000001_create_file_metadata.down.sql
│ ├── 000002_create_file_audit_log.up.sql
│ ├── 000002_create_file_audit_log.down.sql
│ ├── 000003_create_sandbox_audit_log.up.sql
│ └── 000003_create_sandbox_audit_log.down.sql
├── tests/
│ ├── security/ # Isolation validation script
│ └── integration/ # End-to-end lifecycle tests
├── scripts/
│ └── quickstart.sh # Zero-to-running setup
└── docs/
├── architecture.md # System design & decisions
├── migration-guide.md # Concept mapping from other platforms
├── threat-model.md # Security analysis
└── runbook.md # Operations guide
If you've used other sandbox platforms, here's how concepts translate.
| Concept | Daytona | Runloop / E2B | This Kit |
|---|---|---|---|
| Create sandbox | daytona create |
devbox.create() |
POST /sandbox |
| Destroy sandbox | daytona delete |
devbox.shutdown() |
DELETE /sandbox/{id} |
| File read/write | Volume mount | devbox.read_file() |
NFS at /data/user or Storage API |
| Execute command | daytona exec |
devbox.execute() |
kubectl exec or API |
| Snapshot/restore | N/A | devbox.snapshot() |
VolumeSnapshot CRD |
| Warm pool | N/A | Blueprint prebuilds | SandboxWarmPool CRD |
| Isolation | Container | MicroVM | gVisor or Kata (configurable) |
See docs/migration-guide.md for detailed mapping and code examples.
| Variable | Service | Default | Description |
|---|---|---|---|
TOKEN_SIGNING_KEY |
Orchestrator, Gateway | change-me-in-production |
HMAC-SHA256 signing key |
TOKEN_TTL |
Orchestrator, Gateway | 1h |
Session token lifetime |
STORAGE_BACKEND |
Storage Sync | gcs |
gcs or azure |
STORAGE_BUCKET |
Storage Sync | — | Object storage bucket/container |
BACKEND_URL |
Auth Gateway | — | Your backend service URL |
DATABASE_URL |
Storage Sync | — | Postgres connection string |
NFS_SERVER |
Orchestrator | — | NFS server IP/hostname |
SANDBOX_NAMESPACE |
Orchestrator | sandbox-system |
K8s namespace for sandboxes |
GCP (GKE):
helm upgrade --install agent-sandbox-kit charts/agent-sandbox-kit/ \
-f charts/agent-sandbox-kit/values-gcp.yamlAzure (AKS):
helm upgrade --install agent-sandbox-kit charts/agent-sandbox-kit/ \
-f charts/agent-sandbox-kit/values-azure.yamlSee the values files for cloud-specific configuration (NFS server, storage accounts, runtime classes).
Defense-in-depth, secure by default:
- Kernel isolation — gVisor (GKE) or Kata Containers (AKS/Gov) via runtimeClassName
- Minimal capabilities — All Linux capabilities dropped, non-root user, read-only rootfs
- No K8s API access — Service account token not mounted
- Zero-trust networking — All egress denied except auth gateway
- Scoped authentication — Short-lived JWTs with user/conversation/sandbox scope
- Request validation — Gateway strips user_id from requests, injects from token claims
- Rate limiting — Per-session rate limiting at the gateway
- Audit logging — File access and sandbox lifecycle events logged to Postgres
Run the security validation suite after deployment:
./tests/security/validate_isolation.sh sandbox-systemSee docs/threat-model.md for the full security analysis.
Import the Grafana dashboard from manifests/grafana-dashboard.json. Key metrics:
- Sandbox startup latency — p95 should be <5s with warm pools
- Active sandbox count — Track against your concurrency budget
- Warm pool available — Alert if this drops to 0
- Gateway error rate — Alert if >1% 4xx/5xx
- Token mint/revoke rate — Should be balanced (leaks = problem)
- File sync duration — p95 should be <30s for typical workloads
# Build all services
make build
# Run tests
make test
# Run linter
make lint
# Build Docker images
make docker-build REGISTRY=ghcr.io/xors-software
# Render Helm templates (dry-run)
make helm-template| Document | Description |
|---|---|
docs/architecture.md |
System design, data flows, and design decisions |
docs/migration-guide.md |
Concept mapping from Daytona / Runloop / E2B |
docs/threat-model.md |
Security analysis and risk matrix |
docs/runbook.md |
Operations guide and troubleshooting |
Apache 2.0 — see LICENSE for details.