Skip to main content
Feature available with the Enterprise Plan The agent sandbox runs customer-written Python (custom Python evaluators, agent code tools) in isolated, short-lived pods inside your cluster. It is built on the CNCF kubernetes-sigs/agent-sandbox project. Sandboxing is optional. The Helm chart ships with it disabled, and the platform runs fully without it; only features that execute customer Python code are unavailable until a sandbox is installed. The sandbox infrastructure is installed by the cluster administrator, never by the chart, so isolation stays under operator control.

Components

Quick deploy

The chart package includes a step-by-step runbook (AGENT-SANDBOX-PREREQUISITE.md) and ready-to-adapt manifests in its agent-sandbox/ folder. In short:
  1. Create two namespaces: agent-sandbox-system (controller) and agent-sandbox (router and sandboxes).
  2. Install the upstream controller Helm chart with controller.extensions=true.
  3. Create the runtime image pull secret, then apply agent-sandbox/python-sandbox-template.yaml (adapt image tag, node placement, and egress to your cluster).
  4. Apply agent-sandbox/router.yaml, and agent-sandbox/network-policy.yaml if your CNI enforces NetworkPolicies. agent-sandbox/warm-pool.yaml optionally keeps pre-provisioned sandboxes ready.
  5. Enable the feature in your values and upgrade:

Bring your own sandbox template

The SandboxTemplate is yours to define. The shipped template is a hardened reference (no service account token, dropped capabilities, managed egress policy), but you can substitute your own isolation approach, for example gVisor or Kata runtime classes, or a dedicated tainted node pool. The platform only requires that the template runs compatible runtime image and matches the configured agentSandbox.templateName and agentSandbox.namespace.

Bring your own sandbox image

The runtime image defines which Python libraries sandboxed code can import. The shipped image bundles a curated set: requests, pandas, and pydantic. To make additional libraries available (for example beautifulsoup4 for HTML parsing), build a custom image and point the SandboxTemplate at it. The platform never references the image directly, only the template by name, so swapping the image is a template change: no Helm upgrade or platform restart is involved.

Extend the shipped image

The supported approach is to layer extra libraries on top of the published image. Python dependencies live in /app/deps, exposed through PYTHONPATH; install extras into a second directory and append it:
  • Pin the base tag to the deployed platform version, and rebuild the extension image on every platform upgrade.
  • The base image is distroless (no shell, no package manager), so libraries must be installed in the builder stage, never in the final stage.
  • Pure Python packages work as-is. Packages with compiled extensions must ship wheels for Python 3.13 on Debian 13; the image exposes libstdc++ and libgcc_s on LD_LIBRARY_PATH for wheels that link against them.

Deploy the custom image

  1. Push the image to a registry the cluster can pull from, and create a pull secret in the sandbox namespace if the registry requires one.
  2. Update spec.podTemplate.spec.containers[0].image in the SandboxTemplate and re-apply it.
  3. The controller replaces warm-pool sandboxes automatically when the template changes; new executions pick up the new image.

Reaching internal services

The reference template’s egress policy allows sandboxed code to reach the public internet but blocks all private and cluster CIDRs by design. DNS resolution succeeds; the connection itself times out. To let sandboxed code call a service inside the cluster or VPC (for example to fetch and parse an internal website), add a scoped egress rule to the SandboxTemplate’s network policy:
Egress-only template changes apply to running sandboxes immediately (the controller reconciles the NetworkPolicy in place); image changes replace sandbox pods.

Runtime contract

A fully custom image, not based on the shipped one, must implement the same runtime contract the platform depends on:
  • An HTTP server on port 8888 with a health endpoint (GET /) and POST /execute accepting {"command", "timeout_seconds", "env", "cwd"} and returning {"stdout", "stderr", "exit_code"}. Commands run without a shell.
  • File staging endpoints rooted at a writable /workspace volume: POST /upload, GET /download/{path}, GET /list/{path}, GET /exists/{path}, DELETE /files/{path}.
  • python3 on PATH: the platform submits code as python3 -c "..." and reads results from stdout.
  • A non-root user compatible with the hardened template: runAsNonRoot, all capabilities dropped, no privilege escalation.
  • Server-side enforcement of timeout_seconds, returning exit code 124 on timeout.
Extending the shipped image satisfies the entire contract; implementing it from scratch is only needed for a different language runtime or base OS. For deployment assistance, contact support@orq.ai or reach out to an Orq.ai account manager.