Skip to content

Commit f41e732

Browse files
openclaw gateway instructions
1 parent 20b0cdf commit f41e732

2 files changed

Lines changed: 161 additions & 0 deletions

File tree

docs/agents/openclaw-gateway.mdx

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
title: "OpenClaw Gateway"
3+
description: "Start the OpenClaw gateway in an E2B sandbox, connect your browser, and auto-approve device pairing."
4+
icon: "/images/icons/openclaw.svg"
5+
---
6+
7+
The OpenClaw [gateway](https://docs.openclaw.ai/gateway) serves a web UI for chatting with agents. When exposed over a network it requires **token auth** and **device pairing** — your browser must be approved as a trusted device before it can connect.
8+
9+
This guide starts the gateway inside an E2B sandbox, prints the URL, and programmatically approves your browser.
10+
11+
## Quick start
12+
13+
<CodeGroup>
14+
```typescript JavaScript & TypeScript
15+
import { Sandbox } from 'e2b'
16+
17+
const TOKEN = process.env.OPENCLAW_APP_TOKEN || 'my-gateway-token'
18+
const PORT = 18789
19+
20+
// 1. Create sandbox
21+
const sandbox = await Sandbox.create('openclaw', {
22+
envs: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY },
23+
timeoutMs: 3600_000,
24+
})
25+
26+
// 2. Start the gateway with token auth
27+
sandbox.commands.run(
28+
`openclaw gateway --allow-unconfigured --bind lan --auth token --token ${TOKEN} --port ${PORT}`,
29+
{ background: true }
30+
)
31+
32+
// 3. Wait for the gateway to start listening
33+
for (let i = 0; i < 45; i++) {
34+
const probe = await sandbox.commands.run(
35+
`bash -lc 'ss -ltn | grep -q ":${PORT} " && echo ready || echo waiting'`
36+
)
37+
if (probe.stdout.trim() === 'ready') break
38+
await new Promise((r) => setTimeout(r, 1000))
39+
}
40+
41+
const url = `https://${sandbox.getHost(PORT)}/?token=${TOKEN}`
42+
console.log(`Gateway: ${url}`)
43+
```
44+
```python Python
45+
import os, time
46+
from e2b import Sandbox
47+
48+
TOKEN = os.environ.get("OPENCLAW_APP_TOKEN", "my-gateway-token")
49+
PORT = 18789
50+
51+
# 1. Create sandbox
52+
sandbox = Sandbox.create("openclaw", envs={
53+
"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"],
54+
}, timeout=3600)
55+
56+
# 2. Start the gateway with token auth
57+
sandbox.commands.run(
58+
f"openclaw gateway --allow-unconfigured --bind lan --auth token --token {TOKEN} --port {PORT}",
59+
background=True,
60+
)
61+
62+
# 3. Wait for the gateway to start listening
63+
for _ in range(45):
64+
probe = sandbox.commands.run(
65+
f'bash -lc \'ss -ltn | grep -q ":{PORT} " && echo ready || echo waiting\''
66+
)
67+
if probe.stdout.strip() == "ready":
68+
break
69+
time.sleep(1)
70+
71+
url = f"https://{sandbox.get_host(PORT)}/?token={TOKEN}"
72+
print(f"Gateway: {url}")
73+
```
74+
</CodeGroup>
75+
76+
Open the URL in your browser. It will show **"Pairing required"** — that's expected.
77+
78+
## Approve device pairing
79+
80+
The gateway requires each browser to be approved as a paired device. Run this after opening the URL — it polls for pending requests and approves the first one.
81+
82+
<CodeGroup>
83+
```typescript JavaScript & TypeScript
84+
// 4. Poll for the browser's pending device request and approve it
85+
for (let i = 0; i < 30; i++) {
86+
const res = await sandbox.commands.run(
87+
`openclaw devices list --json --url ws://127.0.0.1:${PORT} --token ${TOKEN}`
88+
)
89+
const data = JSON.parse(res.stdout)
90+
if (data.pending?.length) {
91+
const rid = data.pending[0].requestId
92+
await sandbox.commands.run(
93+
`openclaw devices approve ${rid} --token ${TOKEN} --url ws://127.0.0.1:${PORT}`
94+
)
95+
console.log(`Device approved: ${rid}`)
96+
break
97+
}
98+
await new Promise((r) => setTimeout(r, 2000))
99+
}
100+
```
101+
```python Python
102+
import json
103+
104+
# 4. Poll for the browser's pending device request and approve it
105+
for _ in range(30):
106+
try:
107+
res = sandbox.commands.run(
108+
f"openclaw devices list --json --url ws://127.0.0.1:{PORT} --token {TOKEN}"
109+
)
110+
data = json.loads(res.stdout)
111+
if data.get("pending"):
112+
rid = data["pending"][0]["requestId"]
113+
sandbox.commands.run(
114+
f"openclaw devices approve {rid} --token {TOKEN} --url ws://127.0.0.1:{PORT}"
115+
)
116+
print(f"Device approved: {rid}")
117+
break
118+
except Exception:
119+
pass
120+
time.sleep(2)
121+
```
122+
</CodeGroup>
123+
124+
Once approved, the browser connects and the gateway UI loads.
125+
126+
## How it works
127+
128+
| Step | What happens |
129+
|------|-------------|
130+
| `--bind lan` | Gateway listens on `0.0.0.0` so E2B can proxy it |
131+
| `--auth token` | Requires `?token=` on the URL for HTTP and WebSocket auth |
132+
| Browser opens URL | Gateway serves the UI, browser opens a WebSocket |
133+
| `code=1008 pairing required` | Gateway closes the WebSocket until the device is approved |
134+
| `devices approve` | Approves the browser's device fingerprint |
135+
| Browser reconnects | WebSocket connects successfully, UI is live |
136+
137+
## Gateway flags reference
138+
139+
| Flag | Purpose |
140+
|------|---------|
141+
| `--allow-unconfigured` | Start without a full config file |
142+
| `--bind lan` | Bind to `0.0.0.0` (required for E2B port proxying) |
143+
| `--auth token` | Enable token-based authentication |
144+
| `--token <value>` | The auth token (passed as `?token=` in the URL) |
145+
| `--port <number>` | Gateway listen port (default: `18789`) |
146+
147+
## Related
148+
149+
<CardGroup cols={3}>
150+
<Card title="OpenClaw agent" icon="terminal" href="/docs/agents/openclaw">
151+
Run OpenClaw headless in a sandbox
152+
</Card>
153+
<Card title="Sandbox persistence" icon="clock" href="/docs/sandbox/persistence">
154+
Auto-pause, resume, and manage sandbox lifecycle
155+
</Card>
156+
<Card title="SSH access" icon="terminal" href="/docs/sandbox/ssh-access">
157+
Connect to the sandbox via SSH
158+
</Card>
159+
</CardGroup>

docs/agents/openclaw.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ print(f"Sandbox ID: {sandbox.sandbox_id}")
426426
```
427427
</CodeGroup>
428428

429+
For a complete example with token auth, device pairing, and browser auto-approval, see [OpenClaw Gateway](/docs/agents/openclaw-gateway).
430+
429431
## Build a custom template
430432

431433
If you need to customize the environment (e.g. pre-install dependencies, add config files), build your own template on top of the pre-built `openclaw` template.

0 commit comments

Comments
 (0)