> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent sandbox for on-premise

> Run customer Python code such as evaluators and agent tools in isolated on-premise sandbox pods with Kubernetes sandbox templates and runtime images.

<Badge color="blue" size="lg" shape="pill" stroke="true">Feature available with the [Enterprise Plan](https://orq.ai/solutions/enterprise)</Badge>

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](https://github.com/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

| Component         | What it is                                                                                                                                                      |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Controller + CRDs | The upstream [agent-sandbox](https://github.com/kubernetes-sigs/agent-sandbox) controller (`v0.4.6`, extensions API enabled), installed with its own Helm chart |
| sandbox-router    | Routes execution requests from the platform to individual sandbox pods                                                                                          |
| SandboxTemplate   | Defines how sandbox pods run: image, resources, network egress, placement                                                                                       |
| Runtime image     | `ghcr.io/orq-ai/agent-sandbox-python-runtime`, listed in the chart's `IMAGES.md` for air-gapped mirroring                                                       |

## 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](https://github.com/kubernetes-sigs/agent-sandbox) 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:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
agentSandbox:
  enabled: true
  networkPolicies: true # if your CNI enforces NetworkPolicies
```

## 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 a 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:

```dockerfile theme={"theme":{"light":"github-light","dark":"github-dark"}}
FROM python:3.13-slim-trixie AS extras
RUN pip install --no-cache-dir --target=/extras beautifulsoup4

FROM ghcr.io/orq-ai/agent-sandbox-python-runtime:<platform-version>
COPY --from=extras --chown=65532:65532 /extras /app/extra-deps
ENV PYTHONPATH=/app/deps:/app/extra-deps
```

* Pin the base tag to the deployed platform version, and rebuild the extension image on every platform upgrade.
* The base image is `python:3.13-slim-trixie` with `/bin/sh` and the Debian coreutils, which the shell server tool relies on. Hardening comes from the non-root user (uid 65532), the read-only root filesystem, and the sandbox network policy, not from the absence of a shell.
* The base image already switches to uid 65532, so a `pip install` in the final stage cannot write system site-packages. Install libraries in a builder stage and copy them in, as above.
* Pure Python packages work as-is. Packages with compiled extensions must ship wheels for Python 3.13 on Debian 13. The base provides `libstdc++6` and `libgcc-s1`; a wheel that needs another native library (for example `libgomp1`) must have it installed with `apt-get` in the final stage, switching to `USER root` for the install and back to `USER 65532:65532` afterwards.

### 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:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
- to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: <target-namespace>
  ports:
    - port: 80
      protocol: TCP
```

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](mailto:support@orq.ai) or reach out to an **Orq.ai** account manager.
