Sandbox lifecycle & security
Lazy by design
Section titled “Lazy by design”Sandboxes are never created eagerly:
- Planning, knowledge search, specialist routing, and file listing run with zero sandbox overhead.
- The first
execute_command,write_file-then-run, or Steel browser call triggersgetOrCreateOpenSandboxfor that session. The sandbox is stateful: Python variables, dataframes, and/workspacefiles persist across turns. - Pure reads use
getExistingOpenSandbox— a file list or preview can never spawn (and pip-install into) a fresh container as a side effect.
Idle sandboxes are reaped after 30 minutes. Warm pools (Docker or Kubernetes) keep the first execution feeling instant.
Isolation & guardrails
Section titled “Isolation & guardrails”- Fail-closed credentials: the sandbox service requires
OPENSANDBOX_URL(or domain) plusOPENSANDBOX_API_KEYfrom the environment. Nothing runs on hardcoded keys or silent gateway fallbacks. - Per-user quotas: at most
MAX_SANDBOXES_PER_USER(default 5) live sessions per user; over-quota spawns return a 429-style quota error. - Path safety: all sandbox file writes are confined to
/workspacewith traversal and NUL-byte rejection — no shell interpolation of paths. - Network safety: outbound fetches pass SSRF checks; chat payloads are capped (200 recent messages, 8k-char system prompts) with model allowlisting and per-user sliding-window rate limits.
- Kubernetes option:
K8S_SANDBOX_ENABLED=trueruns a warm pool of sandbox pods (K8S_SANDBOX_WARM_POOL_SIZE, CPU/memory limits, idle TTL) with in-cluster ServiceAccount auth.