Sandbox drivers
Choose where agent sessions run (gVisor, Kata microVMs, confidential VMs, kosa8 or E2B) and configure trust tiers and sandbox drivers so every substrate keeps gateway-only egress.
A sandbox is the isolated environment one session runs in. MAQPNA keeps governance (identity, policy, audit, budgets, approvals, the kill switch) in the MAQPNA gateway, and keeps where the agent runs separate. Two settings decide where it runs:
- In a cluster, the trust tier (
TrustTier) names a Kubernetes RuntimeClass: gVisor, Kata with Firecracker, or a confidential VM. The operator creates an upstreamagent-sandboxSandboxon that RuntimeClass. - On a laptop or a sandbox cloud, a sandbox driver (
pkg/sandbox) creates the sandbox:kosa8(microVMs on your machine),e2b(E2B's sandbox cloud) oragent-sandbox(a cluster, from outside it).
Every driver must prove one thing before MAQPNA uses it: the sandbox can reach the gateway and nothing else.
flowchart LR
A["Agent / AgentSession<br/>spec.tier"] --> T["TrustTier<br/>runtimeClassName"]
T --> O["operator"]
O --> S["agent-sandbox Sandbox<br/>gVisor / Kata / CVM"]
D["maqpna dev run / fork<br/>--sandbox"] --> R["sandbox driver<br/>kosa8, e2b, agent-sandbox"]
R --> M["microVM or pod"]
S -->|"egress: gateway only"| G["MAQPNA gateway"]
M -->|"egress: gateway only"| G
When you need this page#
- You install MAQPNA in a cluster and must decide which trust tiers to enable for your nodes.
- You run agents on a laptop in kosa8 microVMs and want to fork, snapshot or attest them.
- You want the identity broker to check the sandbox itself before it issues a session token.
The trust tiers#
The Helm chart creates three RuntimeClasses and three sample TrustTier resources (runtimeClasses and trustTiers in values.yaml):
| Tier | RuntimeClass (handler) | isolation |
What it is | Node needs |
|---|---|---|---|---|
tier-0 |
gvisor (runsc) |
gvisor |
gVisor user-space kernel. Default for untrusted, model-generated code. | gVisor installed |
tier-1 |
kata-fc (kata-fc) |
microvm |
Kata Containers with a Firecracker microVM per sandbox. Pod overhead 250m CPU, 130Mi. | Kata, /dev/kvm |
tier-2 |
kata-qemu-snp (kata-qemu-snp) |
confidential |
Confidential VM (AMD SEV-SNP or Intel TDX) with attestationRequired: true. Pod overhead 1 CPU, 2048Mi. |
Kata CoCo, SEV-SNP or TDX hardware |
All three set egress: gateway-only. The dev profile (values-dev.yaml) enables only gvisor.
TrustTier fields#
TrustTier is cluster-scoped (maqpna.com/v1alpha1, short names tier, tt). Full schema: TrustTier reference.
| Field | Meaning |
|---|---|
runtimeClassName |
Required. The RuntimeClass for sandbox pods. |
isolation |
Required. gvisor, microvm or confidential. |
egress |
gateway-only (default): DNS and the gateway only. deny-all: no egress, DNS included. |
attestationRequired |
The identity broker issues tokens only after attestation. See attestation. |
jurisdiction |
Data-residency jurisdiction the tier guarantees, for example EU-DE. The chart fills it from sovereignty.jurisdiction when unset. |
allowedNodeLabels |
Required node affinity, for example topology.kubernetes.io/region: eu-central-1. |
sandboxTemplateName, warmPoolSize, warmPoolNamespaces |
Provision sessions from an agent-sandbox SandboxTemplate and warm pool (SandboxClaim) instead of a new Sandbox. |
defaultResources |
Resources for agent containers that set none. |
maxSessionTTL |
Caps the lifetime of any session in the tier. |
allowedProviderTools |
Provider-hosted tools (for example web_search) agents in this tier may enable. Empty: none. |
Pick a tier#
| If the agent… | Use |
|---|---|
| runs model-generated code you have not reviewed | tier-0 (gVisor) at least |
| handles customer data, or needs a kernel boundary | tier-1 (microVM) |
| handles data your host operator must not see, or needs hardware proof | tier-2 (confidential VM) |
Enable only the RuntimeClasses whose runtime is installed on your nodes. A tier whose RuntimeClass is missing or unschedulable cannot start sessions.
Step 1: Enable the runtimes in Helm#
-
Write a values file that enables the tiers your nodes support. This one enables gVisor and Kata, and pins Kata to labelled nodes:
runtimeClasses: gvisor: enabled: true kataFc: enabled: true nodeSelector: katacontainers.io/kata-runtime: "true" kataQemuSnp: enabled: false -
Check the cluster with the same values.
maqpna preflightchecks that each enabled RuntimeClass can be installed and scheduled, and that the agent-sandbox CRDs are installed:maqpna preflight -f tiers.yaml -
Install or upgrade:
maqpna install -f tiers.yaml --wait
Step 2: Add or change a tier#
The chart's tiers are samples. To change them, set trustTiers.items, or set trustTiers.create: false and apply your own:
apiVersion: maqpna.com/v1alpha1
kind: TrustTier
metadata:
name: tier-1-eu
spec:
runtimeClassName: kata-fc
isolation: microvm
egress: gateway-only
jurisdiction: EU-DE
allowedNodeLabels:
topology.kubernetes.io/region: eu-central-1
maxSessionTTL: 2h
maqpna apply -f tier-1-eu.yaml
Step 3: Run an agent on the tier#
Set spec.tier on the agent:
apiVersion: maqpna.com/v1alpha1
kind: Agent
metadata:
name: coder
namespace: team-a
spec:
tier: tier-1-eu
# image, tools, policy, budget ...
See the Agent reference for the other fields.
Step 4: Verify#
maqpna tier list
maqpna tier get tier-1-eu
maqpna doctor
maqpna doctor compares TrustTiers with the cluster's RuntimeClasses and reports a tier whose RuntimeClass does not exist. On a running session, check the pod's RuntimeClass with kubectl get pod -n team-a -o jsonpath='{.items[*].spec.runtimeClassName}'.
Sandbox drivers#
A driver implements the contract in pkg/sandbox: create, get, attach, exec, fork, snapshot, restore, kill, attest and egress check. Three drivers are registered:
| Driver | Substrate | Isolation | Fork and snapshot | Attestation | Egress enforced by |
|---|---|---|---|---|---|
kosa8 |
kosa8 microVMs on your host | microvm |
Yes | inventory (kernel, rootfs, image digests) |
kosa8, on the host and in the guest |
e2b |
E2B Firecracker microVMs, cloud or self-hosted | microvm |
Yes | none |
E2B's network config, outside the guest |
agent-sandbox |
An upstream agent-sandbox Sandbox on a RuntimeClass |
from the RuntimeClass | No | inventory (image digests, RuntimeClass, node) |
NetworkPolicy, if the CNI enforces it |
agent-sandbox is the package default (sandbox.Open("")). The maqpna dev commands default to kosa8. The Kubernetes operator does not use the driver contract yet: it drives agent-sandbox itself, from the trust tier.
Every driver keeps three rules, checked by a conformance suite (pkg/sandbox/sandboxtest):
- The token is a file. The session token is in the file named by
MAQPNA_TOKEN_FILE, never in argv or the environment.MAQPNA_TOKENis removed. - Egress is the gateway only. The driver reports the egress the substrate enforces now. A loopback gateway is refused, because no isolated sandbox can reach it.
- A copy gets its own token. Fork and restore re-key the copy before they return, or remove it.
Use kosa8 with maqpna dev#
maqpna dev up --kosa8
maqpna dev run --kosa8-image alpine:3.20 --kosa8-keep -- sh -c 'sleep 600'
maqpna dev attest
maqpna dev fork
maqpna dev snapshot
The step-by-step guide is Run agents in kosa8 sandboxes. dev run always uses kosa8. The driver finds kosa8d through KOSA8_HOST and KOSA8_TOKEN, or the user's socket.
Use E2B#
maqpna dev fork, snapshot, restore and attest take --sandbox e2b. Set:
| Variable | Default | Meaning |
|---|---|---|
E2B_API_KEY |
— | Required. |
E2B_DOMAIN, E2B_API_URL, E2B_SANDBOX_URL |
E2B's | For a self-hosted E2B (the E2B SDKs' names). |
MAQPNA_E2B_TIMEOUT |
1h |
Sandbox lifetime, capped by your E2B plan. |
MAQPNA_E2B_USER |
user |
User that owns the token file. |
MAQPNA_E2B_GATEWAY |
— | Gateway for restore when the source sandbox is gone. |
The sandbox image is an E2B template name. CPU and memory sizes are refused: E2B sizes a sandbox by its template.
Use agent-sandbox from outside the cluster#
--sandbox agent-sandbox uses $KUBECONFIG. maqpna dev asks for microvm isolation, so set a microVM RuntimeClass:
export MAQPNA_AGENT_SANDBOX_RUNTIME_CLASS=kata-fc
maqpna dev attest --sandbox agent-sandbox --session dev-1a2b3c4d
| Variable | Default |
|---|---|
MAQPNA_AGENT_SANDBOX_NAMESPACE |
the kubeconfig context's namespace |
MAQPNA_AGENT_SANDBOX_RUNTIME_CLASS |
gvisor |
MAQPNA_AGENT_SANDBOX_ISOLATION |
derived from the RuntimeClass |
MAQPNA_AGENT_SANDBOX_API_VERSION |
v1beta1 |
MAQPNA_AGENT_SANDBOX_GATEWAY_NAMESPACE, MAQPNA_AGENT_SANDBOX_GATEWAY_APP |
maqpna-system, maqpna-gateway |
MAQPNA_AGENT_SANDBOX_NETWORKPOLICY_ENFORCED |
detect: look for Calico, Cilium, Antrea and similar among kube-system DaemonSets. Or true / false. |
The isolation comes from the RuntimeClass handler: runsc or gvisor gives gvisor; kata*, Firecracker or Cloud Hypervisor gives microvm; SNP, TDX, CoCo or CCA gives cvm; runc, crun or none gives process.
Let the identity broker check the sandbox#
The identity broker can ask the substrate about a sandbox before it issues a session token. Add these flags to maqpna-identity (in Helm, identity.extraArgs):
| Flag | Default | Meaning |
|---|---|---|
-sandbox-check |
— | Driver: agent-sandbox, e2b or kosa8. |
-sandbox-check-gateway |
— | Required with -sandbox-check. The gateway URL the sandbox's egress must be pinned to. |
-sandbox-check-min-isolation |
microvm |
Weakest isolation accepted. Set gvisor for a gVisor tier. |
-sandbox-check-min-attestation |
inventory |
none, inventory or measured. E2B needs none. |
-sandbox-check-allowed |
— | JSON file of accepted measurement digests. |
-sandbox-api-version |
v1beta1 |
agent-sandbox API version. |
identity:
extraArgs:
- -sandbox-check=agent-sandbox
- -sandbox-check-gateway=http://maqpna-gateway.maqpna-system.svc:8080
- -sandbox-check-min-isolation=gvisor
Limits#
agent-sandbox: no fork or snapshot (agent-sandbox 1.0 has no clone or checkpoint API). Attestation never claimsmeasured, even on a confidential RuntimeClass. Enforcement is the CNI declaration, not a proof.e2b: the gateway must be an IPv4 address; E2B has no per-port rules and no IPv6 rules. Whoever holds the E2B API key can change a running sandbox's network.- Cloudflare Sandboxes and AWS AgentCore Runtime drivers: Planned.
- Drivers for
wasmanddevice-enclavesubstrates: Planned. The isolation classes exist in the contract.
Troubleshooting#
| Symptom | Cause | Fix |
|---|---|---|
Sessions do not start; pods are rejected or stay Pending |
The RuntimeClass is missing or no node runs its handler. | Run maqpna preflight and maqpna doctor. Disable tiers you cannot run. |
isolation gvisor is weaker than microvm |
maqpna dev or the broker needs a microVM. |
Use a Kata RuntimeClass, or set -sandbox-check-min-isolation gvisor on the broker. |
cannot enforce gateway-only egress |
No NetworkPolicy-enforcing CNI was detected. | Install one, or set MAQPNA_AGENT_SANDBOX_NETWORKPOLICY_ENFORCED=true only if your CNI enforces it. |
maqpna dev attest exits 3, egress NOT PINNED |
The sandbox can reach more than the gateway. | Read the listed destinations and remove the wider NetworkPolicy or network rule. |
cannot fork or cannot snapshot |
The driver has no fork or snapshot (agent-sandbox). | Use --sandbox kosa8 or --sandbox e2b. |
e2bsandbox: E2B_API_KEY is not set |
Missing key. | export E2B_API_KEY=<your-api-key>. |