OpenClaw Gateway 協議指南:WebSocket 連線實作
搞過分散式系統的人都知道,要讓一堆不同平台的客戶端(像是 CLI、網頁 UI、手機 App)跟後端節點乖乖聽話,通訊協定設計起來真的很頭大。如果你也曾經為了同步狀態或處理權限搞到心力交瘁,OpenClaw 的 Gateway WS 協定應該會讓你覺得親切許多。
這套協定是 OpenClaw 的核心,它把控制平面(Control Plane)跟節點傳輸合而為一。不管是你的 macOS App 還是跑在 Android 上的節點,通通都透過 WebSocket 連線,並在握手階段就直接表明自己的身份(Role)跟權限(Scope)。
- 使用 WebSocket,傳輸內容為 JSON 格式的 text frames。
- 第一個發出的 frame 必須是
connect請求。
握手 (connect)
Section titled “握手 (connect)”Gateway → Client (連線前的挑戰碼挑戰):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Client → Gateway:
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "client": { "id": "cli", "version": "1.2.3", "platform": "macos", "mode": "operator" }, "role": "operator", "scopes": ["operator.read", "operator.write"], "caps": [], "commands": [], "permissions": {}, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-cli/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } }}Gateway → Client:
{ "type": "res", "id": "…", "ok": true, "payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }}當裝置 token 核發後,hello-ok 也會包含:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}Node 範例
Section titled “Node 範例”{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "client": { "id": "ios-node", "version": "1.2.3", "platform": "ios", "mode": "node" }, "role": "node", "scopes": [], "caps": ["camera", "canvas", "screen", "location", "voice"], "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"], "permissions": { "camera.capture": true, "screen.record": false }, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-ios/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } }}- Request:
{type:"req", id, method, params} - Response:
{type:"res", id, ok, payload|error} - Event:
{type:"event", event, payload, seq?, stateVersion?}
具有副作用(Side-effecting)的方法需要提供 idempotency keys(請參考 schema)。
角色與權限範圍
Section titled “角色與權限範圍”operator= 控制平面客戶端(CLI/UI/自動化工具)。node= 能力提供者(負責 camera/screen/canvas/system.run 等硬體或系統操作)。
權限範圍 (operator)
Section titled “權限範圍 (operator)”常見的權限範圍:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairing
方法的權限範圍只是第一道門檻。某些透過 chat.send 執行的斜線指令(slash commands)會有更嚴格的指令級檢查。例如,涉及持久化修改的 /config set 和 /config unset 就需要 operator.admin 權限。
能力/指令/權限 (node)
Section titled “能力/指令/權限 (node)”節點在連線時會宣告它擁有的能力:
caps: 高階能力分類。commands: 允許呼叫的指令白名單。permissions: 細粒度的開關(例如screen.record,camera.capture)。
Gateway 會將這些視為宣告(claims),並在伺服器端強制執行白名單檢查。
system-presence會回傳以裝置身份為 key 的項目。- 在線項目包含
deviceId,roles, 和scopes,這樣 UI 就能為同一個裝置顯示單一橫列,即使該裝置同時以 operator 和 node 身份連線。
Node 輔助方法
Section titled “Node 輔助方法”- 節點可以呼叫
skills.bins來獲取目前的技能執行檔列表,用於自動允許檢查。
Operator 輔助方法
Section titled “Operator 輔助方法”- 操作者可以呼叫
tools.catalog(operator.read) 來獲取 Agent 的執行階段工具目錄。回應內容包含工具分組與來源元數據:source:core或pluginpluginId: 當source="plugin"時的插件擁有者optional: 插件工具是否為選用
- 操作者可以呼叫
tools.effective(operator.read) 來獲取當前 session 實際生效的工具清單。- 必須提供
sessionKey。 - Gateway 會從伺服器端的 session 衍生出受信任的執行環境,而不是直接接受呼叫者提供的認證或交付環境。
- 回應內容僅限於該 session 範圍,反映了當前對話可以使用的工具(包含核心、插件與頻道工具)。
- 必須提供
- 當執行請求需要審核時,Gateway 會廣播
exec.approval.requested。 - 操作者客戶端透過呼叫
exec.approval.resolve來處理(需要operator.approvals權限)。 - 對於
host=node的情況,exec.approval.request必須包含systemRunPlan(標準的argv/cwd/rawCommand/session 元數據)。缺少systemRunPlan的請求會被拒絕。
Agent 交付備援
Section titled “Agent 交付備援”agent請求可以包含deliver=true來要求對外交付。bestEffortDeliver=false會維持嚴格行為:無法解析或僅限內部的交付目標會回傳INVALID_REQUEST。bestEffortDeliver=true允許在無法解析外部交付路徑時(例如內部/網頁聊天 session 或模糊的多頻道設定),回退到僅限 session 的執行模式。
PROTOCOL_VERSION定義在src/gateway/protocol/schema.ts。- 客戶端會發送
minProtocol與maxProtocol;如果版本不匹配,伺服器會拒絕連線。 - Schema 與模型是從 TypeBox 定義產生的:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
- 如果設定了
OPENCLAW_GATEWAY_TOKEN(或--token),connect.params.auth.token必須匹配,否則 Socket 會被關閉。 - 配對成功後,Gateway 會核發一個針對該連線角色與權限的 device token。它會透過
hello-ok.auth.deviceToken回傳,客戶端應該儲存它以便下次連線使用。 - 裝置 token 可以透過
device.token.rotate和device.token.revoke進行輪換或撤銷(需要operator.pairing權限)。 - 認證失敗會包含
error.details.code以及修復建議:error.details.canRetryWithDeviceToken(布林值)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- 針對
AUTH_TOKEN_MISMATCH的客戶端行為:- 受信任的客戶端可以使用快取的裝置 token 嘗試一次重試。
- 如果重試失敗,客戶端應停止自動重連迴圈,並引導操作者進行處理。
裝置識別與配對
Section titled “裝置識別與配對”- 節點應該包含一個穩定的裝置識別碼 (
device.id),這通常衍生自金鑰對的指紋(fingerprint)。 - Gateway 會根據每個裝置與角色核發 token。
- 新的裝置 ID 需要配對審核,除非啟用了本地自動審核。
- 本地連線包含 loopback 以及 Gateway 主機自身的 tailnet 位址(因此同主機的 tailnet 綁定仍可自動審核)。
- 所有 WS 客戶端在
connect時都必須包含device身份(包括 operator 與 node)。控制 UI 只有在以下模式可以省略:gateway.controlUi.allowInsecureAuth=true:用於 localhost 的非安全 HTTP 相容性。gateway.controlUi.dangerouslyDisableDeviceAuth=true:這是緊急救援開關,會嚴重降低安全性。
- 所有連線都必須對伺服器提供的
connect.challengenonce 進行簽名。
裝置認證遷移診斷
Section titled “裝置認證遷移診斷”對於仍在使用舊版(挑戰碼前)簽名行為的客戶端,connect 現在會在 error.details.code 下回傳 DEVICE_AUTH_* 代碼,並附帶穩定的 error.details.reason。
常見的遷移失敗原因:
| Message | details.code | details.reason | Meaning |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | 客戶端漏傳 device.nonce(或傳送空值)。 |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | 客戶端使用了過期或錯誤的 nonce 進行簽名。 |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | 簽名內容與 v2 格式不符。 |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | 簽名時間戳記超出允許的誤差範圍。 |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id 與公鑰指紋不符。 |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | 公鑰格式或標準化處理失敗。 |
遷移目標:
- 務必等待
connect.challenge。 - 簽署包含伺服器 nonce 的 v2 payload。
- 在
connect.params.device.nonce中傳送相同的 nonce。 - 建議使用
v3簽名格式,它除了裝置/客戶端/角色/權限/token/nonce 之外,還綁定了platform和deviceFamily。 - 為了相容性,目前仍接受舊版
v2簽名,但已配對裝置的元數據固定(pinning)在重連時仍會控制指令策略。
TLS 與憑證固定
Section titled “TLS 與憑證固定”- WS 連線支援 TLS。
- 客戶端可以選擇性地固定 Gateway 的憑證指紋(請參考
gateway.tls設定,以及gateway.remote.tlsFingerprint或 CLI 的--tls-fingerprint參數)。
此協定公開了完整的 Gateway API(包含狀態、頻道、模型、聊天、Agent、session、節點、審核等)。具體的介面定義請參考 src/gateway/protocol/schema.ts 中的 TypeBox schemas。
想要實際動手試試看嗎?你可以參考 AI Setup Assistant 來快速完成設定。
- 深入了解 Node 權限設定
- 探索 Agent 交付機制
OpenClaw Expert
還是卡住了?
如果這篇文件沒有解決你的情境,直接問 OpenClaw Expert,拿到可執行步驟。