Agent sandbox
A sandbox is a Pod that runs one agent for one task run; this page covers its lifecycle, its identity and what runs inside it.
Sandbox lifecycle
A sandbox is a Pod that runs one agent for one task run. With the warm pool on (Enable Agent-Sandbox Warm Pool (CRD), off by default), the deployment keeps a pool of pre-provisioned sandboxes (Agent-Sandbox Warm Pool Size, default 3) so that a task does not wait for a Pod to start. When the pool is empty, a task falls back to a sandbox created on demand.
stateDiagram-v2 [*] --> Pooled Pooled: Pooled (no task, no identity) Bound: Bound (task labels applied) OnDemand: Created on demand (no pooled sandbox) Live: Identity live (epoch active) Ready: Runtime ready (harness running) Running: Running (agent working) Idle: Idle (waiting for a prompt) Revoked: Identity revoked Deleted: Deleted Pooled --> Bound: claimed Bound --> OnDemand: bind check fails Bound --> Live: attested OnDemand --> Live: attested Live --> Ready: harness started Ready --> Running: prompt delivered Running --> Idle: turn complete Idle --> Running: next prompt Idle --> Revoked: run ends Revoked --> Deleted: deleted Deleted --> [*]| State | Meaning | Next state |
|---|---|---|
| Pooled | No task, no identity | Bound (claimed) |
| Bound | Task labels applied | Identity live (attested), or Created on demand (bind check fails) |
| Created on demand | No pooled sandbox | Identity live (attested) |
| Identity live | Epoch active | Runtime ready (harness started) |
| Runtime ready | Harness running | Running (prompt delivered) |
| Running | Agent working | Idle (turn complete) |
| Idle | Waiting for a prompt | Running (next prompt), or Identity revoked (run ends) |
| Identity revoked | Deleted |
- A pooled sandbox has no task and no identity; its agent runtime is already running. When a task needs one, it is claimed and labeled with the task, run and agent.
- A claim is accepted only if the sandbox can enforce the in-sandbox tool policy, was built from the current template and passes the identity bind (sidecar present; model hosts point at the live egress proxy). Otherwise the claim is discarded and a sandbox is created on demand.
- The task does not start until the sandbox’s identity is live (see Sandbox identity).
- At the end of the run, identity is revoked first; the claim and the sandbox are then deleted. A sandbox bound to a task is also deleted two days after it was bound, whatever its state. Pooled sandboxes that were never claimed are replaced when the sandbox template changes.
- The sandbox’s working files are on an ephemeral volume deleted with the Pod. Results persist only if the agent saves them to the drive.
The identity states and steps above apply with Sandbox Workload Identity on. With it off (the default), there is no identity to establish or revoke, and the sandbox runs with a Context API key scoped to its agent and run that expires after 24 hours.
Sandbox identity
Workload identity is controlled by the installer setting Sandbox Workload Identity, which is off by default. With it on, sandboxes hold no credentials for your data: each sandbox proves its identity to the application tier through a separate sidecar container, and afterwards its requests are recognized by its network address. With it off, there is no identity sidecar and no identity epoch; the sandbox authenticates with a scoped Context API key that expires after 24 hours and calls the model gateway with the gateway key (see Without Sandbox Workload Identity). The rest of this section describes a sandbox with it on.
sequenceDiagram autonumber participant W as Temporal worker participant K as Kubernetes API participant C as Sandbox controller participant S as Identity sidecar (uid 1001) participant R as Agent runtime (uid 1000) participant B as Identity broker participant D as Identity records (Amazon RDS) participant E as Enforcement points W->>D: create epoch and single-use bootstrap value W->>K: create labeled Sandbox, then bootstrap ConfigMap C->>K: create Pod; projected token (broker, 600 s) S->>B: bootstrap value + projected token, over TLS B->>D: bootstrap pending, unexpired, matching B->>K: read Pod: IP, ServiceAccount, owner, network B->>K: TokenReview; re-read Pod B->>D: epoch live; bind Pod name, UID and IP B->>S: capability token, 600 s lease S->>R: readiness signal releases the runtime W->>D: wait for the live epoch (up to 65 s) W->>R: start the harness, deliver the prompt R->>E: request identified by source Pod IP E->>D: live epoch for this IP? (cached 2 s) S->>B: renew about every 8 minutes W->>D: teardown: revoke epochs W->>K: delete claim and SandboxThe handshake for a sandbox created on demand:
| Step | From | To | What happens |
|---|---|---|---|
| 1 | Temporal worker | Identity records | Create epoch and single-use bootstrap value |
| 2 | Temporal worker | Kubernetes API | Create labeled Sandbox, then bootstrap ConfigMap |
| 3 | Sandbox controller | Kubernetes API | Create Pod; projected token (audience: the broker, 600 s) |
| 4 | Identity sidecar | Identity broker | Bootstrap value + projected token, over TLS |
| 5 | Identity broker | Identity records | Check the bootstrap is pending, unexpired and matching |
| 6 | Identity broker | Kubernetes API | Read Pod: IP, ServiceAccount, owner, network |
| 7 | Identity broker | Kubernetes API | TokenReview; re-read Pod |
| 8 | Identity broker | Identity records | Epoch live; bind Pod name, UID and IP |
| 9 | Identity broker | Identity sidecar | Capability token, 600 s lease |
| 10 | Identity sidecar | Agent runtime | Readiness signal releases the runtime |
| 11 | Temporal worker | Identity records | Wait for the live epoch (up to 65 s) |
| 12 | Temporal worker | Agent runtime | Start the harness, deliver the prompt |
| 13 | Agent runtime | Enforcement points | Request identified by source Pod IP |
| 14 | Enforcement points | Identity records | Live epoch for this IP? (cached 2 s) |
| 15 | Identity sidecar | Identity broker | Renew about every 8 minutes |
| 16 | Temporal worker | Identity records | Teardown: revoke epochs |
| 17 | Temporal worker | Kubernetes API | Delete claim and Sandbox |
For a pooled sandbox, the Pod (step 3) already exists and its agent runtime is running. Just before the claim, the worker creates the identity epoch (step 1), adds the task labels to the Pod, and the broker delivers the bootstrap value to the sidecar over TLS instead of a ConfigMap (step 2). Steps 4 to 9 follow; step 10 does not apply, and in step 12 the harness is already running.
- The identity sidecar runs as a separate operating-system user with its own volumes. It is the only container that holds the projected ServiceAccount token and the capability token; the agent runtime container has no Kubernetes token.
- The broker attests a sandbox by its source IP, ServiceAccount, owner reference and a Kubernetes TokenReview before marking its identity live. Only one live identity can exist for an IP address.
- Enforcement points recognize a sandbox by its source Pod IP bound to a live identity. The capability token is used only to renew the identity and is never presented to enforcement points.
- Identity is revoked before a sandbox is deleted. A revoked identity can still be honored for up to 2 seconds by default (10 seconds at most) because of a short-lived cache (S-08).
- Recognition by IP address relies on the cluster network preventing address spoofing. Network policy enforcement in your cluster is your responsibility (S-14).
Inside the sandbox
| Process | User | Notes |
|---|---|---|
| Harness | uid 1000 | Runs the agent loop; port 4096; applies the in-sandbox tool policy ◇ |
| Identity sidecar | uid 1001 | Holds the projected token and the capability token |
| Tools | uid 1000 | bash, read, write, edit, MCP tool, drive search |
| CLI tools | uid 1000 | context-cli, rclone, context-web-search |
| Agent-generated code | uid 1000 | Same user as the harness |
The harness’s tools are bash, read, write and edit, terminal sessions, the MCP connector tool, drive search and agent-browser; context-cli, rclone and context-web-search run through bash. Which harness runs is set by the installer (see Glossary). The drive search tool is provided by the OpenCode harness; on the default harness it is not yet available.
Pod settings:
- Non-root; no privilege escalation.
- Capabilities dropped; no host network.
- No hardened runtime class (S-09).
- No Kubernetes token or IAM role.
For every network path out of the sandbox, see Sandbox network paths.