Documentation
¶
Overview ¶
Command executor runs the platform-managed sandbox worker: it claims tool_exec work from the shared Postgres queue, runs the built-in toolset inside per-session Docker containers, and appends the agent.tool_result events the brain resumes on. Disposable "hands" — run as many as needed; a container dying is one tool-call error, not a lost session. Configuration is environment-driven:
DATABASE_URL Postgres DSN (required; same database as the
controlplane and brain). A pool_max_conns below 3
is refused: a provision and the reaper can pin a
session-lock connection each while their nested
queries still need the pool
EXECUTOR_IMAGE sandbox base image (default "debian:stable-slim")
EXECUTOR_WORKDIR working directory inside the sandbox (default
"/workspace")
EXECUTOR_LEASE_TTL work-item lease, Go duration (default "15m") —
must comfortably exceed a single tool's timeout
EXECUTOR_POLL_INTERVAL idle queue poll, Go duration (default "500ms")
EXECUTOR_REAP_INTERVAL sandbox reap pass interval, Go duration (default
"1m"); each pass destroys the sandboxes of
deleted (tombstone-evidenced), archived, and
terminated cloud sessions — self_hosted sandboxes
belong to the BYOC worker and are never touched
EXECUTOR_SANDBOX_IDLE_TTL idle sandbox lifetime, Go duration (default
"24h"; "0" disables the idle tier). An idle cloud
session older than this is checkpointed and its
sandbox reaped — unless it still owes work or an
unanswered confirmation ask. Requires object
storage; a blob-less executor disables the tier
at startup with one log line
EXECUTOR_CHECKPOINT_MAX_BYTES workspace-checkpoint size budget in bytes
(default 2147483648, 2 GiB); over budget the TTL
tier reaps without a checkpoint
EXECUTOR_REPO_CLONE_MAX_BYTES github_repository clone spool budget in
bytes (default 1073741824, 1 GiB), metered as the
clone's bytes land; over budget the clone is
abandoned and surfaces as a session.error
EXECUTOR_REPO_CLONE_TIMEOUT per-repository clone deadline (default 5m);
past it the clone is abandoned the same way
CONTROLPLANE_URL where a session's egress gate fetches its config;
set with EXECUTOR_GATE_IMAGE to opt into the gate.
Unset: no gate runs; a gate-wanting session (limited
or vault-attached) falls back to the backend's own
fail-closed networking (Docker limited -> no egress),
while unrestricted sessions network directly as before
EXECUTOR_GATE_IMAGE the egress-gate container image (built with
`docker build --target gate`); opts into the gate
together with CONTROLPLANE_URL
SANDBOX_BACKEND "docker" (default) or "k8s"
DOCKER_HOST Docker daemon address for the docker backend
(falls back to the well-known socket)
SANDBOX_DOCKER_GATE_NETWORK Docker network a session's egress-gate
container joins (default "bridge")
SANDBOX_K8S_KUBECONFIG kubeconfig path for the k8s backend; empty, together
with an empty SANDBOX_K8S_CONTEXT, uses in-cluster
config, then the default loading rules
SANDBOX_K8S_CONTEXT kubeconfig context for the k8s backend
SANDBOX_K8S_NAMESPACE namespace for sandbox pods (default "default")
SANDBOX_K8S_NODE_SELECTOR node labels every sandbox pod requires, as
comma-separated key=value; empty places nothing.
Malformed fails startup
SANDBOX_K8S_TOLERATIONS taints every sandbox pod tolerates, as a JSON array
of Kubernetes Toleration objects; empty tolerates
nothing. Malformed fails startup
SANDBOX_K8S_IMAGE_PULL_SECRETS Secrets every sandbox pod pulls images
with, as comma-separated Secret names; empty adds
nothing. Malformed fails startup
SANDBOX_K8S_NETSETUP_IMAGE image carrying `ip` for the limited-networking
init container (default "busybox")
BLOB_BACKEND object storage: "s3" (default when empty) or
"gcs"; unset with no BLOB_ENDPOINT disables
skills materialization
BLOB_ENDPOINT S3-compatible object storage host:port, required
by the s3 backend
BLOB_ACCESS_KEY / BLOB_SECRET_KEY / BLOB_BUCKET / BLOB_REGION / BLOB_TLS /
BLOB_BUCKET_PRECREATED the rest of the storage config (as controlplane);
the gcs backend takes BLOB_BUCKET alone
SECRETS_BACKEND secrets cipher (docs/plan/12): "openbao", "local",
"gcpkms", or empty to run without one. The executor
decrypts one secret: a github_repository resource's
sealed token, per clone (docs/plan/25). Egress
substitution still decrypts controlplane-side, for
the per-session gate. Without a cipher, repository
mounts do not clone
BAO_ADDR / BAO_TOKEN / BAO_TRANSIT_KEY / SECRETS_MASTER_KEY / SECRETS_KEY_ID /
GCPKMS_KEY_NAME the rest of the cipher config (as controlplane)
TAVILY_API_KEY web_search backend key; unset leaves the tool
unconfigured (it answers is_error naming it)
JINA_API_KEY web_fetch backend key; web_fetch needs this OR
WEBFETCH_BASE_URL, else it answers is_error
WEBSEARCH_BASE_URL / WEBFETCH_BASE_URL Tavily-protocol / Jina-Reader-
protocol endpoints (default: the public ones)
WEBTOOL_ALLOWED_DOMAINS comma-separated operator allowlist for both web
tools (bare host, IPv4, or *.wildcard); empty =
unrestricted
OTEL_EXPORTER_OTLP_ENDPOINT optional OTLP/gRPC collector endpoint
OTEL_EXPORTER_OTLP_INSECURE "true" to export without TLS (default TLS)
Click to show internal directories.
Click to hide internal directories.