Skip to main content
In bridge mode your sandbox plane stays on your intranet, unreachable from outside. You run the ei-worker daemon on a host next to the plane; it makes outbound HTTPS calls only, long-polls Empiric Intelligence for sandbox work, executes each operation against your local plane, and posts results back.
Nothing inbound is ever opened, and Empiric Intelligence never holds your plane’s credentials: the worker reads them from its own environment.

Requirements

  • Python 3.11+.
  • Outbound HTTPS to the Empiric Intelligence cloud API.
  • Network access to the local sandbox plane.
  • Outbound HTTPS from the sandbox instances to the artifact store (see File transfer and egress).
  • Persistent disk for the worker’s result journal (see Recovery).

File transfer and egress

Small operation payloads travel inside the work queue. Bulk file bytes do not — a sandbox reads and writes them straight to the artifact store using short-lived presigned URLs that the cloud mints per operation. Large files never round-trip through the Empiric Intelligence API, which is what keeps a multi-hundred-megabyte workspace practical. That means one outbound rule, on the sandboxes rather than on the worker host: Your Empiric Intelligence contact confirms the exact artifact host for your deployment before you open anything. What this does not require:
  • No inbound rule, ever. Both rules are outbound. Your plane stays unreachable from outside.
  • No cloud credentials in your network. A presigned URL carries its own authorization, is scoped to one object, and expires within 60 minutes. Neither the worker nor a sandbox ever holds an access key for the artifact store.
  • No egress for the worker host to the artifact store. The worker talks to the API; the sandboxes talk to the store.
If you restrict a sandbox’s own internet access with a network_policy, the artifact host must stay reachable — otherwise file staging fails at the start of a run and the run cannot proceed.
If your policy cannot allow egress to Amazon S3, contact us before you start. We can serve artifact traffic from an Empiric Intelligence-controlled host instead, so your allowlist names one domain we operate rather than a third party’s. It is not built yet; tell us it blocks you and we will prioritize it. If your constraint is that customer data must never leave your network at all — a different requirement from an allowlist — say so explicitly, because that needs a storage design rather than a delivery one.

Install

empiric-intelligence-worker is published on PyPI; your Empiric Intelligence contact provides your runtime id and worker key separately. For a system service, install the pinned wheel into a root-managed virtual environment:
Pin the version so upgrades stay a deliberate operator action: the worker is operator-pinned and never auto-updates. pipx or uv tool are fine for an interactive user, but their binaries normally live under that user’s home directory and are intentionally inaccessible to the hardened systemd unit below. Releases are published from Empiric Intelligence CI via PyPI Trusted Publishing and carry Sigstore PEP 740 attestations for provenance verification. The package is source-available under a restricted-use license (see LICENSE): you may run it to connect to Empiric Intelligence, but not redistribute or modify it.

Configuration

Empiric Intelligence settings, read by the worker: Sandbox-plane settings, read by the e2b SDK itself (the worker deliberately does not touch them, which is what keeps it portable across a real E2B cloud and a CubeSandbox plane):

About the worker key

The lkw01_... key is minted by Empiric Intelligence for exactly one runtime and shown once; you receive it from your Empiric Intelligence contact. It authenticates only this runtime’s work queue (a key for one runtime can never poll another’s). Store it in a root-owned file with mode 600. Rotation is a re-mint: you receive a new key and swap it into the environment file.

Run under systemd

Save this unit as /etc/systemd/system/ei-worker.service:
Then create the environment file and start the daemon:
The unit uses a persistent state directory for the journal and restarts the daemon automatically, except after a version rejection (see below). On SIGTERM the worker drains gracefully: it stops claiming, finishes in-flight operations, and reports its active claims before exiting.

Pre-flight checks: doctor

Run before enabling the daemon, and again after any plane upgrade:
Each check prints OK, WARN, or FAIL (non-zero exit on any FAIL):
  1. Cloud reachability, key validity, and key-to-runtime binding.
  2. Clock skew against the server (warn above 30s, fail above 300s).
  3. Local sandbox-plane reachability.
  4. Pause capability (a reminder unless --probe is used).
  5. Snapshot capability (CubeSandbox >= v0.5.1; a reminder unless --probe is used).
  6. Free disk space.
--probe additionally runs the live sandbox checks. The pause check runs here: it creates a real sandbox on your plane and verifies that a paused sandbox’s disk survives and resumes correctly. The snapshot check instead asks Empiric Intelligence to run its own round-trip against this runtime (snapshot a sandbox, boot a fork from the snapshot, verify the disk carried over) and prints the verdict, because “will Empiric Intelligence connect this runtime” is a question only Empiric Intelligence can answer — and the snapshot that round-trip creates is recorded there in the same step, so nothing is left on your provider that we are not tracking. The daemon must be running for it, since the round-trip is carried over this runtime’s own work queue; if it is not, the check says so and tells you to start it. Nothing either check creates is destroyed: the probe sandboxes are paused and the snapshot is left in place — a fork was booted from it, so your provider would refuse to delete it anyway. Both cost storage and no compute, and Empiric Intelligence garbage-collects the snapshot once your plane expires the paused boxes that pin it. Run it once at onboarding and after every plane upgrade. See Compatibility for why this matters on CubeSandbox.

Version pinning and HTTP 426

The cloud enforces a deployment-wide general worker floor (snapshot/auth compatibility, currently 0.5.0 or a higher configured runtime pin). A worker below that floor is turned away with HTTP 426 and exits with a non-zero status that systemd deliberately does not restart (no crash-restart loops on a permanent condition). Upgrade the pinned package (sudo /opt/ei-worker/bin/pip install --upgrade empiric-intelligence-worker==0.13.1) and restart the daemon (sudo systemctl restart ei-worker). Worker 0.7.0 adds the sandbox network_policy capability (including allowlists and deny-network forks). Public-tolerant work can continue on a compatible older worker during rollout, but a restricted-egress run probes its claimed worker and refuses to boot unless that capability is present. Worker 0.8.0 is a WIRE PROTOCOL change: bulk file bytes no longer travel inside an operation result, so a 0.7.0 or older worker is turned away at authentication until it is upgraded. Nothing else about your setup changes — the bytes already moved sandbox-to-store, and they still do. Worker 0.10.0 is a WIRE PROTOCOL change too, a subtractive one: the exec-server stdio tunnel operation and its two relay endpoints were removed because nothing dispatched them any more. A 0.9.0 or older worker is turned away at authentication until it is upgraded, and nothing about your sandbox plane, your key, or your unit file changes. Worker 0.11.0 is a WIRE PROTOCOL change of the same subtractive kind: the sandbox.kill operation is gone from the vocabulary. Empiric Intelligence no longer destroys a sandbox anywhere — a box that is finished with is PAUSED, which costs no compute and keeps its disk indefinitely — so the cloud has no caller for the operation, and a worker that still answered it would be a standing ability to destroy a box on your plane. A 0.10.0 or older worker is turned away at authentication until it is upgraded. Worker 0.12.0 is a WIRE PROTOCOL change of the additive kind: a long-running operation now reports PROGRESS to the cloud while it runs, and a command’s bound stopped being a total. exec.run carries a SILENCE bound instead of a timeout — a command that keeps printing is never stopped, however long it runs, and one that goes quiet for the whole window has its PROCESS stopped inside the box (the box itself is untouched and keeps running). A template build reports its build log the same way, so a slow image build is no longer abandoned at thirty minutes. A 0.11.0 or older worker is turned away at authentication until it is upgraded; nothing about your sandbox plane, your key, or your unit file changes. Worker 0.13.1 is a WIRE PROTOCOL change of the subtractive kind: the sandbox.delete_template operation is gone from the vocabulary. Nothing in Empiric Intelligence deletes a stored sandbox artifact — a template or snapshot is kept, and the provider reclaims nothing and charges nothing for it — so the cloud has no caller for the operation, and a worker that still answered it would be a standing ability to destroy a stored artifact on your plane. A 0.12.0 or older worker is turned away at authentication until it is upgraded; nothing about your sandbox plane, your key, or your unit file changes. Upgrade order: the cloud first, then the wheel. The protocol is matched EXACTLY in both directions, so pre-staging the new wheel against the old cloud is turned away for the same reason an old wheel against the new cloud is. Wait for the Empiric Intelligence deployment that carries the new protocol, then upgrade the worker.

The result journal and recovery

Every operation’s outcome is committed to a local SQLite journal before being reported. This makes results crash-safe:
  • If the daemon or host restarts, a re-delivered operation replays the journaled result instead of executing twice.
  • If an operation is re-delivered to a different host (for example after failover to a second worker machine) and that host has no journaled outcome, the worker reports the execution as indeterminate rather than repeating a command or provisioning a duplicate sandbox.
Keep the journal on persistent storage (the EI_WORKER_STATE_DB path). If you run the worker in a container, mount the journal directory as a volume; a journal lost with its container turns clean same-host recovery into indeterminate results.

Tuning

  • EI_WORKER_CONCURRENCY: raise it if your plane has headroom and tasks queue up; each slot handles one sandbox’s operations at a time.
  • EI_WORKER_IDLE_TIMEOUT_S: how long an idle claim is held before its slot is released. The default (330s) is chosen to sit above the cloud’s per-operation budget; lower it only if slot starvation is an issue.