Deploy OpenClaw
Start the OpenClaw gateway in an E2B sandbox and connect your browser.
Quick start
This launches your OpenClaw gateway site (web UI for chatting with agents).
import { Sandbox } from 'e2b'
const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
// 1. Create sandbox
const sandbox = await Sandbox.create('openclaw', {
envs: { OPENAI_API_KEY: process.env.OPENAI_API_KEY },
timeoutMs: 3600_000,
})
// 2. Set the default model
await sandbox.commands.run('openclaw config set agents.defaults.model.primary openai/gpt-5.2')
// 3. Set insecure control UI flags and start the gateway with token auth
await sandbox.commands.run(
`bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth true && ` +
`openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true && ` +
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}'`,
{ background: true }
)
// 4. Wait for the gateway to start listening
for (let i = 0; i < 45; i++) {
const probe = await sandbox.commands.run(
`bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'`
)
if (probe.stdout.trim() === 'ready') break
await new Promise((r) => setTimeout(r, 1000))
}
const url = `https://${sandbox.getHost(PORT)}/?token=${TOKEN}`
console.log(`Gateway: ${url}`)Visit the printed Gateway URL in your browser.
If you run in secure mode (set gateway.controlUi.dangerouslyDisableDeviceAuth false), run this after opening the URL to poll pending pairing requests and approve the first one.
// 5. Poll for the browser's pending device request and approve it
for (let i = 0; i < 30; i++) {
try {
const res = await sandbox.commands.run(
`openclaw devices list --json --url ws://127.0.0.1:${PORT} --token ${TOKEN}`
)
const data = JSON.parse(res.stdout)
if (data.pending?.length) {
const rid = data.pending[0].requestId
await sandbox.commands.run(
`openclaw devices approve ${rid} --token ${TOKEN} --url ws://127.0.0.1:${PORT}`
)
console.log(`Device approved: ${rid}`)
break
}
} catch {}
await new Promise((r) => setTimeout(r, 2000))
}Once approved, the browser connects and the gateway UI loads.
How it works
| Step | What happens |
|---|---|
--bind lan | Gateway listens on 0.0.0.0 so E2B can proxy it |
--auth token | Requires ?token= on the URL for HTTP and WebSocket auth |
| Browser opens URL | Gateway serves the UI, browser opens a WebSocket |
code=1008 pairing required | Gateway closes the WebSocket until the device is approved (secure mode only) |
devices approve | Approves the browser’s device fingerprint (secure mode only) |
| Browser reconnects | WebSocket connects successfully, UI is live |
Gateway flags reference
| Flag | Purpose |
|---|---|
--allow-unconfigured | Start without a full config file |
--bind lan | Bind to 0.0.0.0 (required for E2B port proxying) |
--auth token | Enable token-based authentication |
--token <value> | The auth token (passed as ?token= in the URL) |
--port <number> | Gateway listen port (default: 18789) |
How to restart the gateway
Use this when the gateway is already running and you want a clean restart (for example, after changing model or env settings).
We can’t use the openclaw gateway restart command here. Some SDK environments cannot target a specific Unix user in commands.run. The commands below use the default command user context.
const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
// 1) Kill existing gateway processes if present
await sandbox.commands.run(
`bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'`
)
await new Promise((r) => setTimeout(r, 1000))
// 2) Start gateway again
await sandbox.commands.run(
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`,
{ background: true }
)
// 3) Wait for listening socket
for (let i = 0; i < 45; i++) {
const probe = await sandbox.commands.run(
`bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'`
)
if (probe.stdout.trim() === 'ready') break
await new Promise((r) => setTimeout(r, 1000))
}Turn insecure flags off (recommended after testing)
Use this to restore secure device authentication after initial testing.
const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
const PORT = 18789
await sandbox.commands.run(
`bash -lc 'openclaw config set gateway.controlUi.allowInsecureAuth false && ` +
`openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth false'`
)
await sandbox.commands.run(
`bash -lc 'for p in "[o]penclaw gateway" "[o]penclaw-gateway"; do for pid in $(pgrep -f "$p" || true); do kill "$pid" >/dev/null 2>&1 || true; done; done'`
)
await sandbox.commands.run(
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`,
{ background: true }
)