Gateway WS 協定是 OpenClaw 的單一控制平面 + 節點傳輸。所有用戶端(CLI、網頁 UI、macOS app、iOS/Android 節點、無頭節點)都透過 WebSocket 連線,並在握手時宣告其角色 + 範圍。Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
傳輸
- WebSocket,文字訊框搭配 JSON 承載。
- 第一個訊框必須是
connect請求。 - 連線前訊框上限為 64 KiB。握手成功後,用戶端應遵循
hello-ok.policy.maxPayload和hello-ok.policy.maxBufferedBytes限制。啟用診斷時,過大的入站訊框與緩慢的出站緩衝區會在 gateway 關閉或捨棄受影響訊框前發出payload.large事件。這些事件會保留大小、限制、介面與安全原因代碼。不會保留訊息本文、附件內容、原始訊框本文、權杖、Cookie 或祕密值。
握手(connect)
Gateway → 用戶端(連線前挑戰):connect 請求可能會傳回可重試的 UNAVAILABLE 錯誤,且 details.reason 設為 "startup-sidecars" 並包含 retryAfterMs。用戶端應在其整體連線預算內重試該回應,而不是將其呈現為終止性的握手失敗。
server、features、snapshot 和 policy 都是 schema(src/gateway/protocol/schema/frames.ts)要求的欄位。auth 也為必要欄位,並回報協商後的角色/範圍。canvasHostUrl 為選用欄位。
未簽發裝置權杖時,hello-ok.auth 會回報協商後的權限,且不含權杖欄位:
client.id: "gateway-client"、client.mode: "backend")在使用共用 Gateway 權杖/密碼驗證的直接 loopback 連線上,可以省略 device。此路徑保留給內部控制平面 RPC,並避免過期的 CLI/裝置配對基準阻擋本機後端工作,例如子代理工作階段更新。遠端用戶端、瀏覽器來源用戶端、節點用戶端,以及明確的裝置權杖/裝置身分用戶端,仍會使用一般配對與範圍升級檢查。
簽發裝置權杖時,hello-ok 也會包含:
hello-ok.auth 也可能在 deviceTokens 中包含其他受限角色項目:
scopes: [],任何交接的操作員權杖則會受限於啟動操作員允許清單(operator.approvals、operator.read、operator.talk.secrets、operator.write)。啟動範圍檢查仍以角色前綴為準:操作員項目只會滿足操作員請求,非操作員角色仍需要其自身角色前綴下的範圍。
Node 範例
訊框格式
- 請求:
{type:"req", id, method, params} - 回應:
{type:"res", id, ok, payload|error} - 事件:
{type:"event", event, payload, seq?, stateVersion?}
角色 + 範圍
角色
operator= 控制平面用戶端(CLI/UI/自動化)。node= 能力主機(camera/screen/canvas/system.run)。
範圍(操作員)
常見範圍:operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config 搭配 includeSecrets: true 時需要 operator.talk.secrets(或 operator.admin)。
由 Plugin 註冊的 Gateway RPC 方法可以要求自己的操作員範圍,但保留的核心管理前綴(config.*、exec.approvals.*、wizard.*、update.*)一律解析為 operator.admin。
方法範圍只是第一道關卡。透過 chat.send 觸達的部分斜線指令會在其上套用更嚴格的指令層級檢查。例如,持久性 /config set 和 /config unset 寫入需要 operator.admin。
node.pair.approve 在基本方法範圍之外,還有額外的核准時範圍檢查:
- 不含指令的請求:
operator.pairing - 帶有非 exec 節點指令的請求:
operator.pairing+operator.write - 包含
system.run、system.run.prepare或system.which的請求:operator.pairing+operator.admin
能力/指令/權限(節點)
節點會在連線時宣告能力主張:caps:高階能力類別。commands:供呼叫使用的指令允許清單。permissions:細粒度開關(例如screen.record、camera.capture)。
在線狀態
system-presence會傳回以裝置身分為鍵的項目。- 在線狀態項目包含
deviceId、roles和scopes,因此即使同一裝置同時以操作員和節點身分連線,介面也能為每個裝置顯示單一列。 node.list包含選用的lastSeenAtMs和lastSeenReason欄位。已連線節點會將目前連線時間回報為lastSeenAtMs,原因為connect;配對節點也可以在受信任的節點事件更新其配對中繼資料時,回報持久背景在線狀態。
Node 背景存活事件
Node 可以使用event: "node.presence.alive" 呼叫 node.event,以記錄配對節點在背景喚醒期間仍存活,而不將其標記為已連線。
trigger 是封閉列舉:background、silent_push、bg_app_refresh、significant_location、manual 或 connect。未知觸發字串會由 gateway 在持久化前正規化為 background。此事件只會針對已驗證的節點裝置工作階段持久保存;無裝置或未配對的工作階段會傳回 handled: false。
成功的 Gateway 會傳回結構化結果:
node.event 可能仍會傳回 { "ok": true };用戶端應將其視為已確認的 RPC,而非在線狀態已持久保存。
廣播事件範圍控管
伺服器推送的 WebSocket 廣播事件會受範圍控管,避免僅具配對範圍或僅節點的工作階段被動收到工作階段內容。- 聊天、代理與工具結果訊框(包括串流的
agent事件與工具呼叫結果)至少需要operator.read。沒有operator.read的工作階段會完全略過這些訊框。 - Plugin 定義的
plugin.*廣播會依照該 Plugin 的註冊方式,受operator.write或operator.admin控管。 - 狀態與傳輸事件(
heartbeat、presence、tick、連線/斷線生命週期等)維持不受限制,讓每個已驗證工作階段都能觀察傳輸健康狀態。 - 未知廣播事件族預設會受範圍控管(預設封閉),除非已註冊處理器明確放寬限制。
常見 RPC 方法族
公開 WS 介面比上述握手/驗證範例更廣。這不是自動產生的完整清單;hello-ok.features.methods 是從 src/gateway/server-methods-list.ts 加上已載入的 Plugin/頻道方法匯出所建立的保守探索清單。請將它視為功能探索,而不是 src/gateway/server-methods/*.ts 的完整列舉。
系統與身分
系統與身分
模型與用量
模型與用量
models.list會傳回執行階段允許的模型目錄。傳入{ "view": "configured" }可取得適合選擇器顯示的已設定模型(先列agents.defaults.models,再列models.providers.*.models),或傳入{ "view": "all" }取得完整目錄。usage.status會傳回提供者用量時段/剩餘配額摘要。usage.cost會傳回日期範圍內的彙總成本用量摘要。doctor.memory.status會傳回作用中預設代理工作區的向量記憶體/快取嵌入就緒狀態。只有在呼叫者明確想要即時偵測嵌入提供者時,才傳入{ "probe": true }或{ "deep": true }。doctor.memory.remHarness會為遠端控制平面用戶端傳回有界、唯讀的 REM 測試工具預覽。它可能包含工作區路徑、記憶體片段、已轉譯且具依據的 Markdown,以及深度提升候選項,因此呼叫者需要operator.read。sessions.usage會傳回每個工作階段的用量摘要。sessions.usage.timeseries會傳回單一工作階段的時間序列用量。sessions.usage.logs會傳回單一工作階段的用量記錄項目。
頻道與登入輔助工具
頻道與登入輔助工具
channels.status會傳回內建與隨附頻道/Plugin 狀態摘要。channels.logout會登出特定頻道/帳號,前提是該頻道支援登出。web.login.start會為目前具備 QR 能力的網頁頻道提供者啟動 QR/網頁登入流程。web.login.wait會等待該 QR/網頁登入流程完成,並在成功時啟動頻道。push.test會向已註冊的 iOS Node 傳送測試 APNs 推播。voicewake.get會傳回已儲存的喚醒詞觸發器。voicewake.set會更新喚醒詞觸發器並廣播變更。
訊息與記錄
訊息與記錄
send是直接對外投遞 RPC,用於在聊天執行器之外進行以頻道/帳號/對話串為目標的傳送。logs.tail會傳回已設定的 Gateway 檔案記錄尾端,並提供游標/限制與最大位元組控制。
Talk 與 TTS
Talk 與 TTS
talk.config會傳回有效的 Talk 設定承載;includeSecrets需要operator.talk.secrets(或operator.admin)。talk.mode會為 WebChat/Control UI 用戶端設定/廣播目前的 Talk 模式狀態。talk.speak會透過作用中的 Talk 語音提供者合成語音。tts.status會傳回 TTS 啟用狀態、作用中提供者、備援提供者,以及提供者設定狀態。tts.providers會傳回可見的 TTS 提供者清單。tts.enable與tts.disable會切換 TTS 偏好設定狀態。tts.setProvider會更新偏好的 TTS 提供者。tts.convert會執行一次性文字轉語音轉換。
秘密、設定、更新與精靈
秘密、設定、更新與精靈
secrets.reload會重新解析作用中的 SecretRefs,並且只有在完全成功時才替換執行階段秘密狀態。secrets.resolve會解析特定命令/目標集合的命令目標秘密指派。config.get會傳回目前的設定快照與雜湊。config.set會寫入已驗證的設定承載。config.patch會合併部分設定更新。config.apply會驗證並取代完整設定承載。config.schema會傳回 Control UI 與 CLI 工具使用的即時設定結構描述承載:結構描述、uiHints、版本與產生中繼資料,當執行階段可以載入時,還包括 Plugin 與頻道結構描述中繼資料。結構描述包含欄位title/description中繼資料,這些中繼資料衍生自 UI 使用的相同標籤與說明文字;當存在相符欄位文件時,也包含巢狀物件、萬用字元、陣列項目,以及anyOf/oneOf/allOf組合分支。config.schema.lookup會為單一設定路徑傳回限定路徑範圍的查詢承載:正規化路徑、淺層結構描述節點、相符提示與hintPath,以及供 UI/CLI 下鑽的直接子項摘要。查詢結構描述節點會保留面向使用者的文件與常見驗證欄位(title、description、type、enum、const、format、pattern、數值/字串/陣列/物件邊界,以及像additionalProperties、deprecated、readOnly、writeOnly這類旗標)。子項摘要會公開key、正規化path、type、required、hasChildren,以及相符的hint/hintPath。update.run會執行 Gateway 更新流程,且只有在更新本身成功時才排程重新啟動。update.status會傳回最新的快取更新重新啟動哨兵,包含可用時重新啟動後正在執行的版本。wizard.start、wizard.next、wizard.status與wizard.cancel會透過 WS RPC 公開入門精靈。
代理與工作區輔助工具
代理與工作區輔助工具
agents.list會傳回已設定的代理項目,包含有效模型與執行階段中繼資料。agents.create、agents.update與agents.delete會管理代理記錄與工作區接線。agents.files.list、agents.files.get與agents.files.set會管理為代理公開的啟動工作區檔案。agent.identity.get會傳回代理或工作階段的有效助理身分。agent.wait會等待執行完成,並在可用時傳回終端快照。
工作階段控制
工作階段控制
sessions.list會傳回目前的工作階段索引,當已設定代理執行階段後端時,包含每列的agentRuntime中繼資料。sessions.subscribe與sessions.unsubscribe會為目前的 WS 用戶端切換工作階段變更事件訂閱。sessions.messages.subscribe與sessions.messages.unsubscribe會為單一工作階段切換逐字稿/訊息事件訂閱。sessions.preview會為特定工作階段鍵傳回有界逐字稿預覽。sessions.resolve會解析或正規化工作階段目標。sessions.create會建立新的工作階段項目。sessions.send會向現有工作階段傳送訊息。sessions.steer是作用中工作階段的中斷並導向變體。sessions.abort會中止工作階段的作用中工作。呼叫者可以傳入key加上選用的runId,或針對 Gateway 可解析到工作階段的作用中執行,單獨傳入runId。sessions.patch會更新工作階段中繼資料/覆寫,並回報已解析的正規模型以及有效的agentRuntime。sessions.reset、sessions.delete與sessions.compact會執行工作階段維護。sessions.get會傳回完整儲存的工作階段列。- 聊天執行仍使用
chat.history、chat.send、chat.abort與chat.inject。chat.history會為 UI 用戶端進行顯示正規化:從可見文字移除行內指令標籤、移除純文字工具呼叫 XML 承載(包含<tool_call>...</tool_call>、<function_call>...</function_call>、<tool_calls>...</tool_calls>、<function_calls>...</function_calls>與被截斷的工具呼叫區塊)以及洩漏的 ASCII/全形模型控制權杖,省略精確為NO_REPLY/no_reply這類純靜默權杖的助理列,且過大的列可替換為預留位置。
裝置配對與裝置權杖
裝置配對與裝置權杖
device.pair.list會傳回待處理與已核准的配對裝置。device.pair.approve、device.pair.reject與device.pair.remove會管理裝置配對記錄。device.token.rotate會在已核准角色與呼叫者範圍界限內輪替配對裝置權杖。device.token.revoke會在已核准角色與呼叫者範圍界限內撤銷配對裝置權杖。
Node 配對、叫用與待處理工作
Node 配對、叫用與待處理工作
node.pair.request、node.pair.list、node.pair.approve、node.pair.reject、node.pair.remove與node.pair.verify涵蓋 Node 配對與啟動驗證。node.list與node.describe會傳回已知/已連線的 Node 狀態。node.rename會更新已配對的 Node 標籤。node.invoke會將命令轉送至已連線的 Node。node.invoke.result會傳回叫用請求的結果。node.event會將源自 Node 的事件帶回 Gateway。node.canvas.capability.refresh會重新整理限定範圍的畫布能力權杖。node.pending.pull與node.pending.ack是已連線 Node 佇列 API。node.pending.enqueue與node.pending.drain會管理離線/中斷連線 Node 的持久待處理工作。
核准系列
核准系列
exec.approval.request、exec.approval.get、exec.approval.list與exec.approval.resolve涵蓋一次性 exec 核准請求,以及待處理核准查詢/重播。exec.approval.waitDecision會等待一個待處理 exec 核准,並傳回最終決策(逾時時為null)。exec.approvals.get與exec.approvals.set會管理 Gateway exec 核准政策快照。exec.approvals.node.get與exec.approvals.node.set會透過 Node 中繼命令管理 Node 本機 exec 核准政策。plugin.approval.request、plugin.approval.list、plugin.approval.waitDecision與plugin.approval.resolve涵蓋 Plugin 定義的核准流程。
自動化、Skills 與工具
自動化、Skills 與工具
- 自動化:
wake會排程立即或下一次 Heartbeat 的喚醒文字注入;cron.list、cron.status、cron.add、cron.update、cron.remove、cron.run、cron.runs會管理排程工作。 - Skills 與工具:
commands.list、skills.*、tools.catalog、tools.effective。
常見事件系列
chat:UI 聊天更新,例如chat.inject與其他僅逐字稿的聊天 事件。session.message與session.tool:已訂閱工作階段的逐字稿/事件串流更新。sessions.changed:工作階段索引或中繼資料已變更。presence:系統存在狀態快照更新。tick:週期性 keepalive/存活事件。health:Gateway 健全狀態快照更新。heartbeat:Heartbeat 事件串流更新。cron:Cron 執行/工作變更事件。shutdown:Gateway 關閉通知。node.pair.requested/node.pair.resolved:Node 配對生命週期。node.invoke.request:Node 叫用請求廣播。device.pair.requested/device.pair.resolved:配對裝置生命週期。voicewake.changed:喚醒詞觸發器設定已變更。exec.approval.requested/exec.approval.resolved:exec 核准 生命週期。plugin.approval.requested/plugin.approval.resolved:Plugin 核准 生命週期。
Node 輔助方法
- Node 可呼叫
skills.bins來擷取目前的技能可執行檔清單,以進行自動允許檢查。
操作者輔助方法
- 操作者可以呼叫
commands.list(operator.read)來擷取代理程式的執行階段 命令清單。agentId為選填;省略即可讀取預設代理程式工作區。scope控制主要name目標所屬的介面:text會傳回不含開頭/的主要文字命令權杖native與預設的both路徑會在可用時傳回感知提供者的原生命令名稱
textAliases帶有精確的斜線別名,例如/model和/m。nativeName會在存在時帶有感知提供者的原生命令名稱。provider為選填,且只會影響原生命名以及原生 Plugin 命令可用性。includeArgs=false會從回應中省略序列化的引數中繼資料。
- 操作者可以呼叫
tools.catalog(operator.read)來擷取代理程式的執行階段工具目錄。回應包含分組工具與來源中繼資料:source:core或pluginpluginId:當source="plugin"時的 Plugin 擁有者optional:Plugin 工具是否為選用
- 操作者可以呼叫
tools.effective(operator.read)來擷取工作階段中執行階段實際生效的工具清單。sessionKey為必填。- Gateway 會從伺服器端的工作階段推導受信任的執行階段脈絡,而不是接受 呼叫端提供的驗證或傳遞脈絡。
- 回應以工作階段為範圍,並反映目前作用中的對話現在可以使用的內容, 包含核心、Plugin 與頻道工具。
- 操作者可以呼叫
skills.status(operator.read)來擷取代理程式可見的 Skills 清單。agentId為選填;省略即可讀取預設代理程式工作區。- 回應包含資格、缺少的需求、設定檢查,以及 已清理的安裝選項,且不會暴露原始秘密值。
- 操作者可以呼叫
skills.search和skills.detail(operator.read)取得 ClawHub 探索中繼資料。 - 操作者可以用兩種模式呼叫
skills.install(operator.admin):- ClawHub 模式:
{ source: "clawhub", slug, version?, force? }會將 Skills 資料夾安裝到預設代理程式工作區的skills/目錄。 - Gateway 安裝程式模式:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }會在 Gateway 主機上執行宣告的metadata.openclaw.install動作。
- ClawHub 模式:
- 操作者可以用兩種模式呼叫
skills.update(operator.admin):- ClawHub 模式會更新一個受追蹤的 slug,或更新預設代理程式工作區中所有受追蹤的 ClawHub 安裝項目。
- 設定模式會修補
skills.entries.<skillKey>值,例如enabled、apiKey和env。
models.list 檢視
models.list 接受選用的 view 參數:
- 省略或
"default":目前的執行階段行為。如果已設定agents.defaults.models,回應會是允許的目錄;否則回應會是完整的 Gateway 目錄。 "configured":適合選擇器大小的行為。如果已設定agents.defaults.models,它仍會優先。否則回應會使用明確的models.providers.*.models項目,只有在沒有已設定的模型列時才會退回完整目錄。"all":完整 Gateway 目錄,略過agents.defaults.models。將此用於診斷與探索 UI,而非一般模型選擇器。
Exec 核准
- 當 exec 請求需要核准時,Gateway 會廣播
exec.approval.requested。 - 操作者用戶端透過呼叫
exec.approval.resolve來解析(需要operator.approvals範圍)。 - 對於
host=node,exec.approval.request必須包含systemRunPlan(標準argv/cwd/rawCommand/工作階段中繼資料)。缺少systemRunPlan的請求會被拒絕。 - 核准後,轉送的
node.invoke system.run呼叫會重用該標準systemRunPlan作為具權威性的命令/cwd/工作階段脈絡。 - 如果呼叫端在準備和最終核准的
system.run轉送之間變更command、rawCommand、cwd、agentId或sessionKey,Gateway 會拒絕該執行,而不是信任已變更的承載。
代理程式傳遞後援
agent請求可以包含deliver=true以要求輸出傳遞。bestEffortDeliver=false會維持嚴格行為:無法解析或僅供內部使用的傳遞目標會傳回INVALID_REQUEST。bestEffortDeliver=true允許在無法解析任何外部可傳遞路由時,後援為僅限工作階段的執行(例如內部/webchat 工作階段或不明確的多頻道設定)。
版本控管
PROTOCOL_VERSION位於src/gateway/protocol/schema/protocol-schemas.ts。- 用戶端傳送
minProtocol+maxProtocol;伺服器會拒絕不相符的版本。 - 結構描述與模型會從 TypeBox 定義產生:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
用戶端常數
src/gateway/client.ts 中的參考用戶端使用這些預設值。這些值在協定 v3 中保持穩定,並且是第三方用戶端的預期基準。
| 常數 | 預設值 | 來源 |
|---|---|---|
PROTOCOL_VERSION | 3 | src/gateway/protocol/schema/protocol-schemas.ts |
| 請求逾時(每個 RPC) | 30_000 ms | src/gateway/client.ts(requestTimeoutMs) |
| 預驗證 / 連線挑戰逾時 | 15_000 ms | src/gateway/handshake-timeouts.ts(設定/env 可提高成對的伺服器/用戶端預算) |
| 初始重新連線退避 | 1_000 ms | src/gateway/client.ts(backoffMs) |
| 最大重新連線退避 | 30_000 ms | src/gateway/client.ts(scheduleReconnect) |
| 裝置權杖關閉後的快速重試上限 | 250 ms | src/gateway/client.ts |
terminate() 前的強制停止寬限 | 250 ms | FORCE_STOP_TERMINATE_GRACE_MS |
stopAndWait() 預設逾時 | 1_000 ms | STOP_AND_WAIT_TIMEOUT_MS |
預設 tick 間隔(hello-ok 前) | 30_000 ms | src/gateway/client.ts |
| tick 逾時關閉 | 當靜默超過 tickIntervalMs * 2 時使用代碼 4000 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024(25 MB) | src/gateway/server-constants.ts |
hello-ok 中公告實際生效的 policy.tickIntervalMs、policy.maxPayload 和 policy.maxBufferedBytes;用戶端應遵循這些值,而不是握手前的預設值。
驗證
- 共用秘密 Gateway 驗證會使用
connect.params.auth.token或connect.params.auth.password,取決於已設定的驗證模式。 - 帶有身分的模式,例如 Tailscale Serve
(
gateway.auth.allowTailscale: true)或非 local loopbackgateway.auth.mode: "trusted-proxy",會從請求標頭而非connect.params.auth.*滿足連線驗證檢查。 - 私有入口
gateway.auth.mode: "none"會完全略過共用秘密連線驗證; 請勿在公開/不受信任的入口暴露該模式。 - 配對後,Gateway 會發出一個範圍限定為連線角色 + 範圍的裝置權杖。
它會在
hello-ok.auth.deviceToken中傳回,且用戶端應將其持久保存以供未來連線使用。 - 用戶端應在任何成功連線後持久保存主要的
hello-ok.auth.deviceToken。 - 使用該已儲存裝置權杖重新連線時,也應重用該權杖已儲存的 已核准範圍集合。這會保留先前已授權的讀取/探測/狀態存取權, 並避免在不明顯的情況下將重新連線縮減為較窄的隱含僅管理員範圍。
- 用戶端連線驗證組裝(
src/gateway/client.ts中的selectConnectAuth):auth.password是正交的,設定時一律會被轉送。auth.token依優先順序填入:明確的共用權杖優先, 接著是明確的deviceToken,再來是已儲存的每裝置權杖(以deviceId+role為鍵)。- 只有在上述都未解析出
auth.token時,才會傳送auth.bootstrapToken。 共用權杖或任何已解析的裝置權杖都會抑制它。 - 在一次性的
AUTH_TOKEN_MISMATCH重試上,自動提升已儲存裝置權杖僅限於受信任端點: loopback,或具有釘選tlsFingerprint的wss://。沒有釘選的公開wss://不符合資格。
- 額外的
hello-ok.auth.deviceTokens項目是啟動程序交接權杖。 只有在連線於受信任傳輸(例如wss://或 loopback/local 配對)上使用啟動驗證時,才持久保存它們。 - 如果用戶端提供明確的
deviceToken或明確的scopes,該呼叫端要求的範圍集合仍具有權威性;只有在用戶端重用已儲存的每裝置權杖時,才會重用快取的範圍。 - 裝置權杖可透過
device.token.rotate和device.token.revoke輪替/撤銷(需要operator.pairing範圍)。 device.token.rotate會傳回輪替中繼資料。它只會對已使用該裝置權杖完成驗證的同一裝置呼叫回傳替換的持有者權杖,因此僅權杖用戶端可在重新連線前持久保存替換項。共用/管理員輪替不會回傳持有者權杖。- 權杖發行、輪替與撤銷仍會被限制在該裝置配對項目中記錄的已核准角色集合內;權杖變更不能擴大或瞄準配對核准從未授予的裝置角色。
- 對於已配對裝置權杖工作階段,除非呼叫端也擁有
operator.admin,否則裝置管理僅限自身範圍:非管理員呼叫端只能移除/撤銷/輪替自己的裝置項目。 device.token.rotate和device.token.revoke也會檢查目標操作者 權杖範圍集合是否符合呼叫端目前的工作階段範圍。非管理員呼叫端 不能輪替或撤銷比自己已持有範圍更廣的操作者權杖。- 驗證失敗包含
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的用戶端行為:- 受信任用戶端可以使用快取的每裝置權杖嘗試一次有界重試。
- 如果該重試失敗,用戶端應停止自動重新連線迴圈,並顯示操作者動作指引。
裝置身分 + 配對
- 節點應包含穩定的裝置身分識別 (
device.id),並由 金鑰組指紋衍生而來。 - Gateway 會依裝置 + 角色核發權杖。
- 新裝置 ID 必須獲得配對核准,除非已啟用本機自動核准。
- 配對自動核准以直接 local loopback 連線為核心。
- OpenClaw 也有狹窄的後端/容器本機自我連線路徑,用於 受信任的共享密鑰輔助流程。
- 同主機 tailnet 或 LAN 連線在配對時仍會被視為遠端,並且 需要核准。
- WS 用戶端通常會在
connect期間包含device身分識別(操作者 + 節點)。唯一不含裝置的操作者例外是明確的信任路徑:gateway.controlUi.allowInsecureAuth=true用於僅限 localhost 的不安全 HTTP 相容性。- 成功的
gateway.auth.mode: "trusted-proxy"操作者控制 UI 驗證。 gateway.controlUi.dangerouslyDisableDeviceAuth=true(緊急處置,嚴重降低安全性)。- 以共享
Gateway 權杖/密碼驗證的直接 loopback
gateway-client後端 RPC。
- 所有連線都必須簽署伺服器提供的
connect.challengenonce。
裝置驗證遷移診斷
對於仍使用挑戰前簽署行為的舊版用戶端,connect 現在會在
error.details.code 下傳回 DEVICE_AUTH_* 詳細代碼,並附帶穩定的 error.details.reason。
常見遷移失敗:
| 訊息 | details.code | details.reason | 含義 |
|---|---|---|---|
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 酬載。
- 在
connect.params.device.nonce中傳送相同的 nonce。 - 偏好的簽章酬載是
v3,除了裝置/用戶端/角色/範圍/權杖/nonce 欄位外, 也會綁定platform和deviceFamily。 - 舊版
v2簽章仍會因相容性而被接受,但已配對裝置的 中繼資料釘選仍會控制重新連線時的命令政策。
TLS + 釘選
- WS 連線支援 TLS。
- 用戶端可選擇釘選 Gateway 憑證指紋(請參閱
gateway.tls設定,加上gateway.remote.tlsFingerprint或 CLI--tls-fingerprint)。
範圍
此協定公開完整的 Gateway API(狀態、通道、模型、聊天、 代理程式、工作階段、節點、核准等)。確切介面由src/gateway/protocol/schema.ts 中的 TypeBox schema 定義。