Sandboxing
Every agent turn in Diminuendo executes inside an isolated sandbox — a short-lived compute environment with its own filesystem, network namespace, and process tree. The gateway itself never creates, provisions, or enters a sandbox. It delegates entirely to Podium, which orchestrates the execution environment and reports lifecycle events back through the WebSocket event stream. The gateway’s role is narrower and more disciplined: it tracks state, enforces security policy at the protocol level, and broadcasts lifecycle events to subscribers. This architecture is a deliberate separation of concerns. The gateway is a control plane. Podium is the data plane. The sandbox is the execution boundary. Each layer has a single owner, and the responsibilities do not overlap.Architecture
The gateway never SSH-es into a sandbox, never mounts filesystems, and never spawns processes inside containers. Its sole responsibility is relaying sandbox lifecycle events to clients and enforcing security policy at the protocol level. All container orchestration belongs to Podium.
Sandbox Lifecycle
A sandbox follows a four-phase lifecycle, each phase tracked through gateway events. The progression is linear — there are no backward transitions, no retry loops at the sandbox level. A failed sandbox is torn down; a new one is provisioned from scratch.Init
When a session starts its first turn, Podium creates a compute instance and begins provisioning a sandbox. The gateway receives a
sandbox.init event and broadcasts it to subscribers.Gateway event: sandbox_init — includes the provider name (e.g., "e2b", "docker")Provisioning
The sandbox is being set up: installing dependencies, configuring the environment, mounting the Chronicle workspace. Podium emits progress events that the gateway relays.Gateway event:
sandbox_provisioning — includes phase (e.g., "creating", "configuring", "installing_deps") and an optional messageReady
The sandbox is fully provisioned and the agent can execute tools. The gateway broadcasts
sandbox_ready and updates session metadata so clients can display sandbox status.Gateway event: sandbox_readySandbox State in the Gateway
The gateway tracks sandbox state in two places, ensuring that both late-joining clients and tenant-wide dashboards have a consistent view.State Snapshot
When a client joins a session (join_session), the state_snapshot response includes a sandbox field:
sandbox is null.
Session Updates
Sandbox lifecycle changes are broadcast assession_updated events to the tenant topic, so all connected clients — not just those joined to the session — see the sandbox status in their session list:
Sandbox Providers
Podium supports multiple sandbox providers. The gateway is provider-agnostic — it relays events regardless of which provider created the sandbox.E2B microVMs
Cloud-hosted microVMs via the E2B platform. Each sandbox receives a dedicated VM with its own kernel, filesystem, and network stack. The isolation is hardware-enforced: the guest kernel is distinct from the host. Used for production workloads requiring strong isolation guarantees.
Docker Containers
Local or cloud Docker containers for development and testing. Lighter-weight than microVMs — containers share the host kernel — but sufficient for local development stacks and CI environments where the threat model does not include malicious tenants.
E2B_API_KEY and E2B_DOMAIN environment variables configure the E2B provider. For Docker, Podium uses the local Docker daemon.
File Access Through Sandboxes
Clients access files in the agent’s workspace through the gateway, which proxies requests to Podium’s file API. The gateway is a relay, not a cache — every file operation reaches Podium in real time.| Client Message | Gateway Action | Podium API |
|---|---|---|
list_files | Proxy to Podium | GET /api/v1/instances/{id}/files |
read_file | Proxy to Podium | GET /api/v1/instances/{id}/files/{path} |
file_history | Proxy to Podium | GET /api/v1/instances/{id}/files/{path}/history |
file_at_iteration | Proxy to Podium | GET /api/v1/instances/{id}/files/{path}/at/{n} |
inactive, the gateway rejects file access with an error.
Chronicle provides the versioned filesystem layer inside the sandbox. Every file modification creates a new iteration, enabling clients to browse version history and read files at any historical point. See Chronicle Integration for details.
Security Profiles for Automations
Interactive sessions run with the user watching — the human can intervene if the agent does something unexpected. Automation runs are unattended, which demands stricter sandboxing. Each automation carries a security profile that Podium enforces at the container level.Profile Definitions
| Profile | Network | Filesystem | Use Case |
|---|---|---|---|
restricted (default) | No outbound except LLM provider | Read-write within /workspace only | Code analysis, test running, file review |
networked | Outbound via egress proxy with domain allowlist | Read-write within /workspace only | GitHub API access, external service monitoring |
custom | Admin-configured policy | Admin-configured policy | Special integrations (requires automation:admin permission) |
Filesystem Isolation
The container filesystem is restricted to exactly what the agent needs. Nothing more is visible; nothing less would be functional:registry.db, session.db) are never mounted into any sandbox. They reside on the gateway’s local filesystem, physically separate from the container mount namespace. This is not a policy — it is a topological fact. The databases exist in a namespace the container cannot see.
Permission Requests in Sandboxes
When an agent inside a sandbox encounters a sensitive operation, it emitsquestion_requested or permission_requested events. The gateway:
- Broadcasts the event to all session subscribers
- For automation runs: transitions the run to
waitingstatus and creates an inbox item - Waits for the user to respond via
answer_question
restricted profile runs. If a run remains in waiting status beyond a configurable timeout, it is canceled. There is no “YOLO mode” for unattended execution.
Sandbox Lifecycle During Shutdown
When the gateway shuts down gracefully:- The
server_shutdownevent is broadcast to all session topics - Active Podium connections are closed
- Podium instances are stopped via
DELETE /api/v1/instances/{id} - Sandboxes are torn down by Podium as a consequence of instance deletion
inactive. The Podium instances associated with those sessions will have already been reclaimed by Podium’s own timeout mechanism. The system converges to a consistent state without manual intervention.
Configuration
| Variable | Default | Description |
|---|---|---|
E2B_API_KEY | "" | API key for E2B sandbox provider |
E2B_DOMAIN | e2b-dev.igent.dev | E2B domain for sandbox URLs |
PODIUM_URL | http://localhost:5082 | Podium coordinator URL (manages sandbox lifecycle) |
Responsibility Matrix
The division of labor between gateway and Podium is strict and unambiguous:| Responsibility | Gateway (Diminuendo) | Podium |
|---|---|---|
| Create sandbox | No | Yes |
| Provision dependencies | No | Yes |
| Mount Chronicle workspace | No | Yes |
| Enforce network policy | No (defines policy) | Yes (enforces at container level) |
| Track sandbox state | Yes (via events) | Yes (source of truth) |
| Broadcast lifecycle events | Yes | No (emits raw events) |
| File access proxy | Yes | Yes (serves file API) |
| Stop sandbox on session delete | Yes (calls Podium API) | Yes (executes container teardown) |
| Recover after crash | Yes (resets stale sessions) | Yes (reclaims timed-out instances) |