Runtime
One AgentRun object becomes a fully isolated, fully attributed run. The agent in the loop is not
trusted, so every control on this page sits outside the sandbox. This page describes the design;
what runs today is on the status page.
Source: docs/architecture/ai-platform.drawio, page 3.
Components and software
| Component | Software | What it does | Why this software |
|---|---|---|---|
| Run API | Crossplane v2 composition, written in KCL | Turns one AgentRun claim into everything a run needs: ServiceAccount, task ConfigMap, network policy, Sandbox. Projects the run’s phase, PR and token usage back into its status | The platform’s standard for self-service APIs; one claim, one lifecycle, deleted as a whole |
| Sandbox lifecycle | agent-sandbox | A Sandbox resource: one pod with a stable identity and a clean start, and no restarts that hide failures | Kubernetes-native and built for agent workloads; the same building block as AWS’s agents-on-EKS blueprint |
| Isolation | gVisor (runsc) on a dedicated pool: GKE Sandbox agents-gvisor on gcp-0, Karpenter agents-gvisor on aws-0 | Runs the agent’s commands against gVisor’s user-space kernel, so an exploit has to break gVisor before it reaches the node’s kernel | Strong isolation without VMs, and it runs on ordinary nodes (Kata would need bare metal or nested virtualisation) |
| Harness | OpenHands agent-server and SDK, wrapped by a small agent-run entrypoint | The agent loop: shell, editor, git, MCP tools. agent-run clones the repository, starts the conversation, prints the step log and revokes the GitHub token at the end | Open source, headless (an HTTP API rather than an IDE), model-agnostic, with MCP support |
| Identity proxy | Envoy sidecar | Attaches the run’s own short-lived token to every model, tool and token-exchange call. The harness never sees that token | The agent cannot leak a gateway token it never sees. The one credential it holds is its GitHub token: in memory, one repository, one role, ≤ 1 h, revoked when the run ends |
| Network policy | Cilium CiliumNetworkPolicy | Default deny, per run: egress only to named hosts (GitHub, the router, optional package registries) | FQDN-aware policy, plus Hubble to see every dropped flow |
| GitHub access | octo-sts and a GitHub App, plus a repository ruleset | Exchanges the run’s identity for a GitHub token scoped to one repository and its role’s permissions, valid ≤ 1 h and revoked when the run ends. The rulesets let the App push only agent/** branches, and no tags | No long-lived GitHub token anywhere; the rules live in each repository’s trust policies |
| Secrets | OpenBao and External Secrets | Holds the few platform secrets (App keys, provider keys); none reaches a sandbox | The platform’s secret store, nothing agent-specific |
Security boundaries
| Boundary | Mechanism |
|---|---|
| Code execution | gVisor sandbox, restricted pod security, no service-account token in the harness |
| Network | Default-deny CNP per run; egress only to named FQDNs and the gateway |
| Identity | Two projected tokens per run, for the gateway and for token exchange, valid until the deadline; each audience names the run’s role and its data class or repository. A room run adds a third, audience room-broker, refreshed every 600 s and held only by the room-bridge sidecar |
| GitHub | Short-lived installation tokens from octo-sts, scoped to one repository and the role’s permissions; rulesets let the agents’ App push only agent/** branches, and no tags |
Spend, merge and stop are the factory’s controls: see Factory → Controls.