Get started
Cloud Workers
Cloud workers let a session run its agent loop on a throwaway cloud machine while everything about the session stays where it always was: visible in the sidebar, streaming live, with the transcript owned by the Gateway. The Gateway leases a box, installs a pinned copy of OpenClaw on it, syncs the session's workspace over, and hands the turn loop to a restricted openclaw worker process. Model calls are proxied back through the Gateway, so provider credentials never leave your machine, and prompt caching keeps working because the provider sees one continuous stream.
When the work is done (or the box dies), the machine is discarded. The durable state — transcript, workspace commits, placement records — lives with the Gateway.
What runs where
| Concern | Location |
|---|---|
Agent loop + tools (exec, read, write, edit, …) |
Cloud worker box |
| Model inference and provider credentials | Gateway (proxied by {provider, model} reference) |
| Transcript (durable, session store) | Gateway |
| Live streaming into the sidebar | Gateway fanout, fed by the worker's replayable event stream |
| Workspace git history | Authored on the box credential-free; the Gateway adopts commits and owns push/PR |
The box needs no inbound ports except sshd and no egress beyond what your setup command uses: the Gateway connects out via SSH and a reverse tunnel carries the worker's WebSocket back. No Tailscale or VPN required.
Requirements
- A worker provider plugin. The bundled
crabboxplugin drives the Crabbox CLI, which brokers leases across cloud backends (AWS, Hetzner, and others). Thecrabboxbinary must be onPATH(or setsettings.binary) with provider credentials already configured. - Node.js on the leased machine. Bare cloud images usually lack it — install it in the profile's
setupcommand. - A session with a session-owned managed worktree (create one with
worktree: true). Dispatch moves that worktree's contents; plain directories sync as a manifest mirror.
Configuration
Add a profile under cloudWorkers.profiles in openclaw.json:
{ "cloudWorkers": { "profiles": { "aws": { "provider": "crabbox", "install": "bundle", "settings": { "provider": "aws", "class": "standard", "ttl": "8h", "idleTimeout": "45m", "setup": "test -x /usr/bin/node || (curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs)" } } } }}Profile fields:
| Key | Meaning |
|---|---|
provider |
Worker provider id registered by a plugin (crabbox for the bundled plugin). |
install |
bundle (default) ships the running Gateway's build; npm installs the exact released Gateway version with pinned integrity. npm requires the Gateway to run from a packaged release. |
settings |
Provider-owned JSON. For crabbox: provider (backend), class (machine class), ttl, idleTimeout (Go durations), optional setup and absolute binary path. |
lifetime |
Optional stored policy (idleTimeoutMinutes, maxLifetimeMinutes). |
The setup command
settings.setup runs on the leased box after it is SSH-ready and before OpenClaw is installed. It runs on every provision attempt (including replays after an interrupted dispatch), so it must be idempotent — guard installs with a command -v/test -x check as in the example. If setup fails, the provider stops the lease and the dispatch fails closed; no half-configured box is left running.
Install channels
bundlepacks the running Gateway'sdist, a prunedpackage.json, and any workspace packages the build references, all covered by a content hash. The box verifies the pristine bundle against that hash, then installs production npm dependencies (scripts disabled). This is how you run a dev build on a worker.npmproves the release exists on the public registry, pins its SHA-512 integrity, and installsopenclaw@<version>matching the Gateway exactly.
Dispatching a session
Create a session with a managed worktree, then dispatch it (the RPC requires operator.admin and only exists when profiles are configured):
openclaw gateway call sessions.create \ --params '{"key":"agent:main:big-refactor","worktree":true,"cwd":"/path/to/repo","worktreeName":"big-refactor"}' openclaw gateway call sessions.dispatch \ --timeout 1500000 \ --params '{"key":"agent:main:big-refactor","profileId":"aws"}'sessions.dispatch closes local turn admission, drains active work, provisions the lease, runs setup, bootstraps OpenClaw, syncs the workspace, and returns once the placement reaches active worker ownership. Budget several minutes for the first dispatch; leases and installs are cached where the provider supports it. After that, talk to the session as usual — turns route to the worker automatically.
Placement moves through a durable state machine (local → requested → provisioning → syncing → starting → active), so a Gateway restart mid-dispatch reconciles instead of leaking machines. Dispatch is one-way in v1: there is no pull-back RPC yet, and a failed worker turn fail-stops the placement with the worker's stderr tail preserved in the placement error for diagnosis.
Security model
- Closed worker ingress. Workers speak a dedicated protocol on the tunneled socket with a closed method allowlist — a worker cannot call operator RPCs.
- Minted credentials, hashed at rest. Each dispatch mints a worker credential; the Gateway stores only its hash. Credential rotation and owner-epoch fencing guarantee at most one live owner per session — a stale worker that reconnects is fenced, never merged.
- Host-key pinning. The provider must surface the box's SSH host key at provision time; bootstrap connects with strict pinning and fails closed without it.
- No secrets on the box. Model auth stays on the Gateway (inference travels by
{provider, model}reference), and workspace git commits are authored on the box without credentials. - Durable, exactly-once transcripts. The worker commits transcript batches through a compare-and-swap protocol against the session's leaf; a stale base fail-stops the run instead of duplicating or rebasing paid output.
Troubleshooting
sessions.dispatchis an unknown method — nocloudWorkers.profilesare configured, or the caller lacksoperator.admin.- "Worker bootstrap requires Node.js on the leased host" — add a Node install to
settings.setup(see above). - Dispatch fails with a provider error — the placement record and
environments.listkeep the last error, including the setup/bootstrap stderr tail. Boxes are destroyed on failure, so that tail is the primary forensic. - Client timeout while dispatching —
openclaw gateway calldefaults to a 10s timeout; pass--timeoutgenerously (dispatch keeps running server-side either way, and a retry while provisioning is rejected withsession cannot dispatch from placement provisioning). - Lease housekeeping —
crabbox list --provider <backend>shows live leases;crabbox stop --provider <backend> --id <lease>releases one manually. Idle leases expire on the profile'sidleTimeout.
Related
- Sandboxing — reducing blast radius for local tool execution
- Sessions CLI — inspecting stored sessions
- Configuration reference