Cloud sandboxes¶
A cloud sandbox is a remote node that lasts for one run. Instead of keeping a VM around, mini-ork asks a provider for a fresh sandbox, hands it the work, collects the results, and releases it.
This is the recommended way to run untrusted or parallel work: every run starts from a known image and leaves nothing behind.
Providers¶
| Provider | Kind | Notes |
|---|---|---|
static |
A VM you own | The default; a long-lived node in nodes.yaml |
daytona |
Daytona | Snapshot-based, per-run |
e2b |
E2B | Template-based |
modal |
Modal | Image- and resource-based |
MO_NODE_PROVIDER selects the provider when a profile does not set one.
Profiles¶
A profile lives at config/environments/<name>.yaml and describes everything
needed to create a node:
provider: daytona
provider_options:
snapshot: mini-ork-py311
timeout: 3600
auto_stop_minutes: 10
setup:
- pip install -e .[test]
env:
PYTHONHASHSEED: "0"
secrets:
- OPENAI_API_KEY
network: full
| Field | Meaning |
|---|---|
provider |
static, daytona, e2b or modal |
provider_options |
Provider-specific creation parameters |
setup |
Commands run inside the sandbox after creation |
env |
Non-secret environment for the run |
secrets |
Names resolved from the vault and injected at dispatch |
network |
full or allowlist |
--env <name> selects the profile. The same flag names a static node profile
from nodes.yaml, so --env means "which environment" regardless of provider.
Provider options¶
| Option | Used by | Meaning |
|---|---|---|
snapshot |
Daytona | Base snapshot to start from |
template |
E2B | Template id |
image |
Modal | Container image |
timeout |
all | Hard lifetime in seconds |
ttl_minutes |
all | Idle TTL before reaping |
auto_stop_minutes |
Daytona | Provider-side auto-stop |
bootstrap |
all | Commands run before setup |
ready_timeout_s |
all | How long to wait for the sandbox to become usable |
resources |
Modal | CPU/memory request |
A profile that omits a required option fails at launch with a clear message rather than starting a half-configured sandbox.
Lifecycle¶
sequenceDiagram
participant CLI as mini-ork (laptop)
participant P as Provider API
participant S as Sandbox
CLI->>P: create(profile)
P-->>CLI: sandbox handle
CLI->>S: bootstrap + setup
CLI->>S: dispatch nodes
S-->>CLI: outputs, artifacts, gate results
CLI->>P: release (or reap on TTL)
mini-ork acquires one sandbox per run (acquire_run_node) and holds it for
the run's lifetime. A run does not hop between sandboxes: the workspace, the git
state and the installed dependencies form one continuity that a hop would break.
Release happens when the run finishes, succeeds or fails. If the laptop dies before release, the provider-side TTL reaps the sandbox.
Secrets¶
Secrets are named, not inlined:
At dispatch the control plane resolves each name from the vault and passes the value with the request. The profile and the repository never contain the value.
If a named secret cannot be resolved, the launch fails before any provider API call. There is no silent empty-string fallback: a sandbox that starts without its key only wastes money failing every model call.
See Vault.
Network¶
| Value | Effect |
|---|---|
full |
The sandbox can reach the internet |
allowlist |
Only the listed hosts/ports are reachable |
allowlist is the right choice for runs that do not need open egress. It keeps
a compromised or confused repository from calling out, and it makes a run's
network dependencies explicit.
Cost¶
Sandboxes cost money per second, in addition to model spend. Keep timeouts honest:
- set
timeoutto a little more than the run's expected duration; - set
auto_stop_minutesfor providers that support it; - run
mini-ork sandbox-gc --backend daytonato reap leaked sandboxes.
--backend names the provider whose sandboxes to clean. The GC lists sandboxes
the provider still has for this project and releases those past their TTL. Run
it after an interrupted session.
Daily model spend remains governed separately by MO_DAILY_BUDGET_USD; see
Cost governance.
Choosing a placement¶
| You want… | Use |
|---|---|
| Fast iteration on your own machine | --placement local (default) |
| A stable, always-on worker | A static node in nodes.yaml |
| Clean state per run | A cloud sandbox profile |
| Untrusted repository code | A cloud sandbox with network: allowlist |
| Many parallel runs | One sandbox per run, in parallel |
Untrusted code is the strongest reason to choose a sandbox. Worktree isolation separates runs from each other; it does not separate a run from your machine.
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| Launch fails naming a secret | The secret is not in the vault | Add it, or remove it from secrets |
| Provider auth error | Provider key missing or expired | Set the provider's key in the environment/vault |
ready_timeout_s exceeded |
Image is slow to boot | Raise the value; check the provider's status |
| Sandbox still alive after a crash | No release happened | mini-ork sandbox-gc --backend <name> |
| Setup fails | setup assumes a tool the image lacks |
Add it to bootstrap or use a richer snapshot |
Related¶
- Remote nodes — the static-node sibling
- Architecture: cloud sandbox providers
- Vault
- Cost governance