Gateway

Gateway プロトコル

Gateway WSプロトコルは、OpenClaw の単一のコントロールプレーン + ノードトランスポートです。すべてのクライアント(CLI、Web UI、macOSアプリ、iOS/Androidノード、ヘッドレスノード)は WebSocket 経由で接続し、ハンドシェイク時にロール + スコープを宣言します。

トランスポート

  • WebSocket、JSONペイロードを持つテキストフレーム。
  • 最初のフレームは必ず connect リクエストである必要があります。
  • 接続前フレームは 64 KiB に制限されます。ハンドシェイクが成功した後、クライアントは hello-ok.policy.maxPayloadhello-ok.policy.maxBufferedBytes の制限に従う必要があります。診断が有効な場合、過大な受信フレームと遅い送信バッファは、Gateway が影響を受けるフレームを閉じるか破棄する前に payload.large イベントを発行します。これらのイベントはサイズ、制限、サーフェス、安全な理由コードを保持します。メッセージ本文、添付ファイルの内容、生フレーム本文、トークン、Cookie、シークレット値は保持しません。

ハンドシェイク(connect)

Gateway → クライアント(接続前チャレンジ):

json
{  "type": "event",  "event": "connect.challenge",  "payload": { "nonce": "…", "ts": 1737264000000 }}

クライアント → Gateway:

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 3,    "maxProtocol": 4,    "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 → クライアント:

json
{  "type": "res",  "id": "…",  "ok": true,  "payload": {    "type": "hello-ok",    "protocol": 4,    "server": { "version": "…", "connId": "…" },    "features": { "methods": ["…"], "events": ["…"] },    "snapshot": { "…": "…" },    "auth": {      "role": "operator",      "scopes": ["operator.read", "operator.write"]    },    "policy": {      "maxPayload": 26214400,      "maxBufferedBytes": 52428800,      "tickIntervalMs": 15000    }  }}

Gateway がまだ起動時サイドカーの完了処理中の場合、connect リクエストは details.reason"startup-sidecars" に設定され、retryAfterMs を含む、再試行可能な UNAVAILABLE エラーを返すことがあります。クライアントは、その応答を最終的なハンドシェイク失敗として表面化するのではなく、全体の接続予算内で再試行する必要があります。

serverfeaturessnapshotpolicy はすべてスキーマ(packages/gateway-protocol/src/schema/frames.ts)で必須です。auth も必須で、ネゴシエートされたロール/スコープを報告します。pluginSurfaceUrls は任意で、canvas などのPluginサーフェス名を、スコープ付きホストURLにマップします。

スコープ付きPluginサーフェスURLは期限切れになる場合があります。ノードは node.pluginSurface.refresh{ "surface": "canvas" } とともに呼び出して、pluginSurfaceUrls の新しいエントリを受け取れます。実験的な Canvas Plugin リファクタリングは、非推奨の canvasHostUrlcanvasCapability、または node.canvas.capability.refresh 互換パスをサポートしません。現在のネイティブクライアントとGatewayはPluginサーフェスを使用する必要があります。

デバイストークンが発行されない場合、hello-ok.auth はトークンフィールドなしで、ネゴシエートされた権限を報告します。

json
{  "auth": {    "role": "operator",    "scopes": ["operator.read", "operator.write"]  }}

信頼された同一プロセスのバックエンドクライアント(client.id: "gateway-client"client.mode: "backend")は、共有Gatewayトークン/パスワードで認証する場合、直接ループバック接続で device を省略できます。このパスは内部コントロールプレーンRPC専用で、古いCLI/デバイスペアリングのベースラインが、サブエージェントセッション更新などのローカルバックエンド作業をブロックしないようにします。リモートクライアント、ブラウザーオリジンクライアント、ノードクライアント、明示的なデバイストークン/デバイスIDクライアントは、引き続き通常のペアリングとスコープアップグレードチェックを使用します。

デバイストークンが発行される場合、hello-ok には次も含まれます。

json
{  "auth": {    "deviceToken": "…",    "role": "operator",    "scopes": ["operator.read", "operator.write"]  }}

組み込みのQR/セットアップコードのブートストラップは、新しいモバイル引き継ぎパスです。ベースラインのセットアップコード接続が成功すると、プライマリノードトークンに加えて、範囲が限定されたオペレータートークンが1つ返されます。

json
{  "auth": {    "deviceToken": "…",    "role": "node",    "scopes": [],    "deviceTokens": [      {        "deviceToken": "…",        "role": "operator",        "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]      }    ]  }}

オペレーター引き継ぎは意図的に範囲が限定されており、QRオンボーディングでモバイルオペレーターループを開始し、ペアリング変更スコープや operator.admin を付与せずにネイティブセットアップを完了できます。ブートストラップ後にネイティブクライアントが必要な Talk 設定を読み取れるよう、operator.talk.secrets が含まれます。より広いペアリング権限と管理者アクセスには、別途承認済みのオペレーターペアリングまたはトークンフローが必要です。クライアントは、接続が wss:// やループバック/local pairing などの信頼されたトランスポート上でブートストラップ認証を使用した場合にのみ、hello-ok.auth.deviceTokens を永続化する必要があります。

ノードの例

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 3,    "maxProtocol": 4,    "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": "…"    }  }}

フレーミング

  • リクエスト: {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)

一般的なスコープ:

  • operator.read
  • operator.write
  • operator.admin
  • operator.approvals
  • operator.pairing
  • operator.talk.secrets

includeSecrets: true を指定した talk.config には operator.talk.secrets(または operator.admin)が必要です。 シークレットが含まれる場合、クライアントはアクティブな Talk プロバイダーの認証情報を talk.resolved.config.apiKey から読み取る必要があります。talk.providers.<id>.apiKey はソース形状のままで、SecretRef オブジェクトまたは秘匿化された文字列である場合があります。

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.runsystem.run.prepare、または system.which を含むリクエスト: operator.pairing + operator.admin

機能/コマンド/権限(node)

ノードは接続時に機能クレームを宣言します。

  • caps: cameracanvasscreenlocationvoicetalk などの高レベルな機能カテゴリ。
  • commands: invoke 用のコマンド許可リスト。
  • permissions: 粒度の細かいトグル(例: screen.recordcamera.capture)。

Gateway はこれらをクレームとして扱い、サーバー側の許可リストを強制します。

プレゼンス

  • system-presence はデバイスIDをキーにしたエントリを返します。
  • プレゼンスエントリには deviceIdrolesscopes が含まれるため、UIは、同じデバイスがオペレーターノードの両方として接続している場合でも、デバイスごとに1行で表示できます。
  • node.list には任意の lastSeenAtMslastSeenReason フィールドが含まれます。接続中のノードは、現在の接続時刻を lastSeenAtMs として、理由 connect とともに報告します。ペアリング済みノードは、信頼されたノードイベントがペアリングメタデータを更新したときに、永続的なバックグラウンドプレゼンスも報告できます。

ノードのバックグラウンド生存イベント

ノードは event: "node.presence.alive" を指定して node.event を呼び出し、ペアリング済みノードがバックグラウンドウェイク中に生存していたことを、接続済みとしてマークせずに記録できます。

json
{  "event": "node.presence.alive",  "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"}

trigger は閉じた列挙型です: backgroundsilent_pushbg_app_refreshsignificant_locationmanual、または connect。未知のトリガー文字列は、永続化前にGatewayによって background に正規化されます。このイベントは、認証済みのノードデバイスセッションについてのみ永続化されます。デバイスなしまたは未ペアリングのセッションは handled: false を返します。

成功したGatewayは構造化された結果を返します。

json
{  "ok": true,  "event": "node.presence.alive",  "handled": true,  "reason": "persisted"}

古いGatewayは node.event に対してまだ { "ok": true } を返す場合があります。クライアントはそれを、永続的なプレゼンスの永続化ではなく、確認済みRPCとして扱う必要があります。

ブロードキャストイベントのスコープ制御

サーバーからプッシュされる WebSocket ブロードキャストイベントはスコープでゲートされるため、ペアリングスコープのセッションやノード専用セッションがセッション内容を受動的に受信することはありません。

  • チャット、エージェント、ツール結果フレーム(ストリーミングされた agent イベントとツール呼び出し結果を含む)には、少なくとも operator.read が必要です。operator.read を持たないセッションは、これらのフレームを完全にスキップします。
  • Plugin定義の plugin.* ブロードキャストは、Plugin が登録した方法に応じて、operator.write または operator.admin にゲートされます。
  • ステータスとトランスポートイベントheartbeatpresencetick、接続/切断ライフサイクルなど)は制限されないままなので、トランスポートの健全性はすべての認証済みセッションから観測可能です。
  • 未知のブロードキャストイベントファミリーは、登録済みハンドラーが明示的に緩和しない限り、デフォルトでスコープゲートされます(fail-closed)。

各クライアント接続は独自のクライアントごとのシーケンス番号を保持するため、異なるクライアントがイベントストリームのスコープでフィルタリングされた異なるサブセットを見る場合でも、ブロードキャストはそのソケット上で単調な順序を維持します。

一般的なRPCメソッドファミリー

公開WSサーフェスは、上記のハンドシェイク/認証の例よりも広範です。これは生成されたダンプではありません。hello-ok.features.methods は、src/gateway/server-methods-list.ts と読み込まれたPlugin/チャンネルメソッドのエクスポートから構築された保守的なディスカバリーリストです。src/gateway/server-methods/*.ts の完全な列挙ではなく、機能ディスカバリーとして扱ってください。

システムとアイデンティティ
  • health は、キャッシュ済みまたは新しくプローブされた Gateway ヘルススナップショットを返します。
  • diagnostics.stability は、最近の有界診断安定性レコーダーを返します。イベント名、カウント、バイトサイズ、メモリ読み取り値、キュー/セッション状態、チャンネル/Plugin 名、セッション ID などの運用メタデータを保持します。チャットテキスト、Webhook 本文、ツール出力、生のリクエストまたはレスポンス本文、トークン、Cookie、秘密値は保持しません。オペレーターの読み取りスコープが必要です。
  • status は、/status 形式の Gateway サマリーを返します。機密フィールドは、管理者スコープのオペレータークライアントにのみ含まれます。
  • gateway.identity.get は、リレーとペアリングフローで使用される Gateway デバイスアイデンティティを返します。
  • system-presence は、接続済みオペレーター/Node デバイスの現在のプレゼンススナップショットを返します。
  • system-event は、システムイベントを追加し、プレゼンスコンテキストを更新/ブロードキャストできます。
  • last-heartbeat は、最新の永続化済み Heartbeat イベントを返します。
  • set-heartbeats は、Gateway 上の Heartbeat 処理を切り替えます。
モデルと使用状況
  • models.list は、ランタイムで許可されているモデルカタログを返します。ピッカー向けサイズの設定済みモデル(まず agents.defaults.models、次に models.providers.*.models)には { "view": "configured" } を、完全なカタログには { "view": "all" } を渡します。
  • usage.status は、プロバイダー使用状況ウィンドウ/残りクォータのサマリーを返します。
  • usage.cost は、日付範囲の集計済みコスト使用状況サマリーを返します。 1 つのエージェントには agentId を渡し、設定済みエージェントを集計するには agentScope: "all" を渡します。
  • doctor.memory.status は、アクティブなデフォルトエージェントワークスペースのベクトルメモリ/キャッシュ済み埋め込みの準備状態を返します。呼び出し元がライブの埋め込みプロバイダー ping を明示的に求める場合にのみ、{ "probe": true } または { "deep": true } を渡します。Dreaming 対応クライアントは、Dreaming ストア統計を選択したエージェントワークスペースにスコープするために { "agentId": "agent-id" } も渡せます。agentId を省略すると、デフォルトエージェントへのフォールバックを維持し、設定済み Dreaming ワークスペースを集計します。
  • doctor.memory.dreamDiarydoctor.memory.backfillDreamDiarydoctor.memory.resetDreamDiarydoctor.memory.resetGroundedShortTermdoctor.memory.repairDreamingArtifactsdoctor.memory.dedupeDreamDiary は、選択エージェントの Dreaming ビュー/アクション向けに任意の { "agentId": "agent-id" } パラメーターを受け付けます。agentId が省略されると、設定済みのデフォルトエージェントワークスペースで動作します。
  • doctor.memory.remHarness は、リモートコントロールプレーンクライアント向けに、有界で読み取り専用の REM ハーネスプレビューを返します。ワークスペースパス、メモリスニペット、レンダリング済みの grounded markdown、深い昇格候補を含めることができるため、呼び出し元には operator.read が必要です。
  • sessions.usage は、セッションごとの使用状況サマリーを返します。1 つの エージェントには agentId を渡し、設定済みエージェントをまとめて一覧表示するには agentScope: "all" を渡します。
  • sessions.usage.timeseries は、1 つのセッションの時系列使用状況を返します。
  • sessions.usage.logs は、1 つのセッションの使用状況ログエントリを返します。
チャンネルとログインヘルパー
  • channels.status は、組み込み + バンドル済みチャンネル/Plugin の状態サマリーを返します。
  • channels.logout は、チャンネルがログアウトをサポートしている特定のチャンネル/アカウントからログアウトします。
  • web.login.start は、現在の QR 対応 Web チャンネルプロバイダーの QR/Web ログインフローを開始します。
  • web.login.wait は、その QR/Web ログインフローが完了するまで待機し、成功時にチャンネルを開始します。
  • push.test は、登録済み iOS Node にテスト APNs プッシュを送信します。
  • voicewake.get は、保存済みのウェイクワードトリガーを返します。
  • voicewake.set は、ウェイクワードトリガーを更新し、変更をブロードキャストします。
メッセージングとログ
  • send は、チャットランナー外でのチャンネル/アカウント/スレッド対象送信向けの直接アウトバウンド配信 RPC です。
  • logs.tail は、設定済み Gateway ファイルログの末尾を、カーソル/制限および最大バイト制御付きで返します。
Talk と TTS
  • talk.catalog は、音声、ストリーミング文字起こし、リアルタイム音声向けの読み取り専用 Talk プロバイダーカタログを返します。正規プロバイダー ID、レジストリエイリアス、ラベル、設定状態、任意のグループレベル ready 結果、公開モデル/音声 ID、正規モード、トランスポート、ブレイン戦略、リアルタイム音声/ケイパビリティフラグを含み、プロバイダーシークレットを返したりグローバル設定を変更したりしません。現在の Gateway は、ランタイムプロバイダー選択を適用した後に ready を設定します。クライアントは、古い Gateway との互換性のため、それが存在しない場合は未検証として扱う必要があります。
  • talk.config は、有効な Talk 設定ペイロードを返します。includeSecrets には operator.talk.secrets(または operator.admin)が必要です。
  • talk.session.create は、realtime/gateway-relaytranscription/gateway-relay、または stt-tts/managed-room 向けに Gateway 所有の Talk セッションを作成します。stt-tts/managed-room では、sessionKey を渡す operator.write 呼び出し元は、スコープ付きセッションキー可視性のために spawnedBy も渡す必要があります。スコープなしの sessionKey 作成と brain: "direct-tools" には operator.admin が必要です。
  • talk.session.join は、管理ルームセッショントークンを検証し、必要に応じて session.ready または session.replaced イベントを発行し、平文トークンや保存済みトークンハッシュなしでルーム/セッションメタデータと最近の Talk イベントを返します。
  • talk.session.appendAudio は、base64 PCM 入力音声を Gateway 所有のリアルタイムリレーおよび文字起こしセッションに追加します。
  • talk.session.startTurntalk.session.endTurntalk.session.cancelTurn は、状態がクリアされる前に古いターンを拒否しつつ、管理ルームのターンライフサイクルを駆動します。
  • talk.session.cancelOutput は、主に Gateway リレーセッションでの VAD ゲート付き割り込みのために、アシスタント音声出力を停止します。
  • talk.session.submitToolResult は、Gateway 所有のリアルタイムリレーセッションによって発行されたプロバイダーツール呼び出しを完了します。最終結果が後続する中間ツール出力には options: { willContinue: true } を渡し、別のリアルタイムアシスタントレスポンスを開始せずにツール結果でプロバイダー呼び出しを満たす必要がある場合は options: { suppressResponse: true } を渡します。
  • talk.session.steer は、Gateway 所有のエージェント支援 Talk セッションにアクティブ実行の音声制御を送信します。{ sessionId, text, mode? } を受け付け、modestatussteercancel、または followup です。省略されたモードは、発話テキストから分類されます。
  • talk.session.close は、Gateway 所有のリレー、文字起こし、または管理ルームセッションを閉じ、終端 Talk イベントを発行します。
  • talk.mode は、WebChat/Control UI クライアント向けに現在の Talk モード状態を設定/ブロードキャストします。
  • talk.client.create は、Gateway が設定、認証情報、指示、ツールポリシーを所有したまま、webrtc または provider-websocket を使用してクライアント所有のリアルタイムプロバイダーセッションを作成します。
  • talk.client.toolCall は、クライアント所有のリアルタイムトランスポートがプロバイダーツール呼び出しを Gateway ポリシーへ転送できるようにします。最初にサポートされるツールは openclaw_agent_consult です。クライアントは実行 ID を受け取り、プロバイダー固有のツール結果を送信する前に通常のチャットライフサイクルイベントを待ちます。
  • talk.client.steer は、クライアント所有のリアルタイムトランスポート向けにアクティブ実行の音声制御を送信します。Gateway は sessionKey からアクティブな埋め込み実行を解決し、ステアリングを黙って破棄するのではなく、構造化された受理/拒否結果を返します。
  • talk.event は、リアルタイム、文字起こし、STT/TTS、管理ルーム、テレフォニー、会議アダプター向けの単一の Talk イベントチャンネルです。
  • talk.speak は、アクティブな Talk 音声プロバイダーを通じて音声を合成します。
  • tts.status は、TTS 有効状態、アクティブプロバイダー、フォールバックプロバイダー、プロバイダー設定状態を返します。
  • tts.providers は、表示可能な TTS プロバイダーインベントリを返します。
  • tts.enabletts.disable は、TTS 設定状態を切り替えます。
  • tts.setProvider は、優先 TTS プロバイダーを更新します。
  • tts.convert は、1 回限りのテキスト読み上げ変換を実行します。
シークレット、設定、更新、ウィザード
  • secrets.reload は、アクティブな SecretRefs を再解決し、完全に成功した場合にのみランタイムのシークレット状態を入れ替えます。
  • secrets.resolve は、特定のコマンド/ターゲットセット向けに、コマンド対象のシークレット割り当てを解決します。
  • config.get は、現在の設定スナップショットとハッシュを返します。
  • config.set は、検証済みの設定ペイロードを書き込みます。
  • config.patch は、部分的な設定更新をマージします。破壊的な配列 置換には、影響を受けるパスを replacePaths に含める必要があります。配列エントリ配下のネストされた配列には、agents.list[].skills のような [] パスを使用します。
  • config.apply は、完全な設定ペイロードを検証して置き換えます。
  • config.schema は、Control UI と CLI ツールで使用されるライブ設定スキーマペイロードを返します。スキーマ、uiHints、バージョン、生成メタデータを含み、ランタイムが読み込める場合は Plugin + チャンネルスキーマメタデータも含みます。このスキーマには、UI で使用される同じラベルとヘルプテキストから派生したフィールド title / description メタデータが含まれます。一致するフィールドドキュメントが存在する場合は、ネストされたオブジェクト、ワイルドカード、配列項目、anyOf / oneOf / allOf 合成ブランチも含まれます。
  • config.schema.lookup は、1 つの設定パスについて、パススコープのルックアップペイロードを返します。正規化パス、浅いスキーマノード、一致したヒント + hintPath、任意の reloadKind、UI/CLI ドリルダウン向けの直接の子サマリーを含みます。reloadKindrestarthotnone のいずれかで、要求されたパスに対する Gateway 設定リロードプランナーを反映します。ルックアップスキーマノードは、ユーザー向けドキュメントと共通の検証フィールド(titledescriptiontypeenumconstformatpattern、数値/文字列/配列/オブジェクトの境界、additionalPropertiesdeprecatedreadOnlywriteOnly などのフラグ)を保持します。子サマリーは、key、正規化済み pathtyperequiredhasChildren、任意の reloadKind、さらに一致した hint / hintPath を公開します。
  • update.run は Gateway 更新フローを実行し、更新自体が成功した場合にのみ再起動をスケジュールします。セッションを持つ呼び出し元は continuationMessage を含めることができるため、起動時に再起動継続キューを通じて 1 回の後続エージェントターンが再開されます。コントロールプレーンからのパッケージマネージャー更新と監視付き git チェックアウト更新では、稼働中の Gateway 内でパッケージツリーを置き換えたりチェックアウト/ビルド出力を変更したりする代わりに、分離された管理サービスへのハンドオフを使用します。開始されたハンドオフは、result.reason: "managed-service-handoff-started"handoff.status: "started" を伴う ok: true を返します。利用不可または失敗したハンドオフは、managed-service-handoff-unavailable または managed-service-handoff-failed を伴う ok: false を返し、手動シェル更新が必要な場合は handoff.command も返します。利用不可のハンドオフは、OpenClaw に安全なスーパーバイザー境界または永続的なサービスアイデンティティがないことを意味します。たとえば systemd の OPENCLAW_SYSTEMD_UNIT などです。開始されたハンドオフ中、再起動センチネルは一時的に stats.reason: "restart-health-pending" を報告する場合があります。継続は、CLI が再起動後の Gateway を検証し、最終的な ok センチネルを書き込むまで遅延されます。
  • update.status は、最新の更新再起動センチネルを更新して返します。利用可能な場合は、再起動後に稼働しているバージョンも含みます。
  • wizard.startwizard.nextwizard.statuswizard.cancel は、WS RPC 経由でオンボーディングウィザードを公開します。
Agent and workspace helpers
  • agents.list は、実効モデルとランタイムメタデータを含む、設定済みエージェントエントリを返します。
  • agents.createagents.updateagents.delete は、エージェントレコードとワークスペースの接続を管理します。
  • agents.files.listagents.files.getagents.files.set は、エージェントに公開されるブートストラップワークスペースファイルを管理します。
  • tasks.listtasks.gettasks.cancel は、Gateway タスク台帳を SDK とオペレータークライアントに公開します。
  • artifacts.listartifacts.getartifacts.download は、明示的な sessionKeyrunId、または taskId スコープに対して、トランスクリプト由来のアーティファクト要約とダウンロードを公開します。実行クエリとタスククエリは、所有するセッションをサーバー側で解決し、由来が一致するトランスクリプトメディアだけを返します。安全でない URL ソースやローカル URL ソースは、サーバー側で取得する代わりに、未対応のダウンロードを返します。
  • environments.listenvironments.status は、SDK クライアント向けに読み取り専用の Gateway ローカル環境とノード環境の検出を公開します。
  • agent.identity.get は、エージェントまたはセッションの実効アシスタント ID を返します。
  • agent.wait は実行の完了を待ち、利用可能な場合は終端スナップショットを返します。
Session control
  • sessions.list は、エージェントランタイムバックエンドが設定されている場合に行ごとの agentRuntime メタデータを含む、現在のセッションインデックスを返します。
  • sessions.subscribesessions.unsubscribe は、現在の WS クライアントのセッション変更イベント購読を切り替えます。
  • sessions.messages.subscribesessions.messages.unsubscribe は、1 つのセッションのトランスクリプト/メッセージイベント購読を切り替えます。
  • sessions.preview は、特定のセッションキーについて範囲制限されたトランスクリプトプレビューを返します。
  • sessions.describe は、正確なセッションキーに対応する 1 つの Gateway セッション行を返します。
  • sessions.resolve は、セッションターゲットを解決または正規化します。
  • sessions.create は、新しいセッションエントリを作成します。
  • sessions.send は、既存のセッションにメッセージを送信します。
  • sessions.steer は、アクティブなセッション向けの中断して誘導するバリアントです。
  • sessions.abort は、セッションのアクティブな作業を中止します。呼び出し元は key と任意の runId を渡すか、Gateway がセッションへ解決できるアクティブな実行については runId だけを渡せます。
  • sessions.patch は、セッションメタデータ/オーバーライドを更新し、解決済みの正規モデルと実効 agentRuntime を報告します。
  • sessions.resetsessions.deletesessions.compact は、セッションのメンテナンスを実行します。
  • sessions.get は、保存されている完全なセッション行を返します。
  • チャット実行は引き続き chat.historychat.sendchat.abortchat.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 のような純粋なサイレントトークンのアシスタント行は省略され、過大な行はプレースホルダーに置き換えられる場合があります。
  • chat.message.get は、単一の可視トランスクリプトエントリ向けに追加された、範囲制限付きの完全メッセージリーダーです。クライアントは sessionKey、セッション選択がエージェントスコープの場合は任意の agentId、さらに以前に chat.history を通じて公開されたトランスクリプト messageId を渡します。保存済みエントリがまだ利用可能で過大でない場合、Gateway は軽量履歴の切り詰め上限なしで、同じ表示正規化済みプロジェクションを返します。
  • chat.send は、1 ターンの fastMode: "auto" を受け入れ、自動カットオフ前に開始されたモデル呼び出しには fast mode を使い、その後のリトライ、フォールバック、ツール結果、または継続呼び出しは fast mode なしで開始します。カットオフのデフォルトは 60 秒で、agents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds によりモデルごとに設定できます。chat.send の呼び出し元は、そのリクエストのカットオフを上書きするために 1 ターンの fastAutoOnSeconds を渡せます。
Device pairing and device tokens
  • device.pair.list は、保留中および承認済みのペアリング済みデバイスを返します。
  • device.pair.setupCode は、モバイルセットアップコードと、デフォルトでは PNG QR データ URL を作成します。operator.admin が必要で、広告される検出からは意図的に省略されています。結果には setupCode、任意の qrDataUrlgatewayUrl、秘密ではない auth ラベル、urlSource が含まれます。
  • device.pair.approvedevice.pair.rejectdevice.pair.remove は、デバイスペアリングレコードを管理します。
  • device.token.rotate は、承認済みロールと呼び出し元スコープの範囲内で、ペアリング済みデバイストークンをローテーションします。
  • device.token.revoke は、承認済みロールと呼び出し元スコープの範囲内で、ペアリング済みデバイストークンを取り消します。

セットアップコードには、有効期間の短いブートストラップ認証情報が埋め込まれます。クライアントは、ペアリングフローを超えてそれをログに記録したり永続化したりしてはなりません。

Node pairing, invoke, and pending work
  • node.pair.requestnode.pair.listnode.pair.approvenode.pair.rejectnode.pair.removenode.pair.verify は、ノードペアリングとブートストラップ検証を扱います。
  • node.listnode.describe は、既知/接続済みノードの状態を返します。
  • node.rename は、ペアリング済みノードのラベルを更新します。
  • node.invoke は、接続済みノードにコマンドを転送します。
  • node.invoke.result は、invoke リクエストの結果を返します。
  • node.event は、ノード発のイベントを Gateway に戻します。
  • node.pending.pullnode.pending.ack は、接続済みノードキュー API です。
  • node.pending.enqueuenode.pending.drain は、オフライン/切断済みノード向けの永続的な保留作業を管理します。
Approval families
  • exec.approval.requestexec.approval.getexec.approval.listexec.approval.resolve は、単発の exec 承認リクエストと保留中の承認の検索/再生を扱います。
  • exec.approval.waitDecision は、1 つの保留中 exec 承認を待機し、最終判断(タイムアウト時は null)を返します。
  • exec.approvals.getexec.approvals.set は、Gateway exec 承認ポリシースナップショットを管理します。
  • exec.approvals.node.getexec.approvals.node.set は、ノードリレーコマンドを通じてノードローカルの exec 承認ポリシーを管理します。
  • plugin.approval.requestplugin.approval.listplugin.approval.waitDecisionplugin.approval.resolve は、Plugin 定義の承認フローを扱います。
Automation, skills, and tools
  • 自動化: wake は即時または次回 Heartbeat での wake テキスト挿入をスケジュールします。cron.getcron.listcron.statuscron.addcron.updatecron.removecron.runcron.runs は、スケジュール済み作業を管理します。
  • cron.run は、手動実行向けの enqueue 形式 RPC のままです。完了セマンティクスが必要なクライアントは、返された runId を読み取り、cron.runs をポーリングする必要があります。
  • cron.runs は、任意の空でない runId フィルターを受け入れるため、クライアントは同じジョブの他の履歴エントリと競合することなく、キューに入った 1 つの手動実行を追跡できます。
  • Skills とツール: commands.listskills.*tools.catalogtools.effectivetools.invoke

共通イベントファミリー

  • chat: chat.inject などの UI チャット更新、およびその他のトランスクリプト専用チャットイベント。プロトコル v4 では、デルタペイロードは deltaText を運びます。message は累積されたアシスタントスナップショットのままです。非プレフィックス置換は replace=true を設定し、deltaText を置換テキストとして使用します。
  • session.messagesession.operationsession.tool: 購読中セッション向けのトランスクリプト、実行中セッション操作、イベントストリーム更新。
  • sessions.changed: セッションインデックスまたはメタデータが変更されました。
  • presence: システムプレゼンススナップショット更新。
  • tick: 定期的な keepalive / liveness イベント。
  • health: Gateway ヘルススナップショット更新。
  • heartbeat: Heartbeat イベントストリーム更新。
  • cron: cron 実行/ジョブ変更イベント。
  • shutdown: Gateway シャットダウン通知。
  • node.pair.requested / node.pair.resolved: ノードペアリングのライフサイクル。
  • node.invoke.request: ノード invoke リクエストのブロードキャスト。
  • device.pair.requested / device.pair.resolved: ペアリング済みデバイスのライフサイクル。
  • voicewake.changed: ウェイクワードトリガー設定が変更されました。
  • exec.approval.requested / exec.approval.resolved: exec 承認ライフサイクル。
  • plugin.approval.requested / plugin.approval.resolved: Plugin 承認ライフサイクル。

ノードヘルパーメソッド

  • ノードは、自動許可チェック用に現在の skill 実行可能ファイル一覧を取得するため、skills.bins を呼び出せます。

タスク台帳 RPC

オペレータークライアントは、タスク台帳 RPC を通じて Gateway バックグラウンドタスクレコードを検査およびキャンセルできます。これらのメソッドは、生のランタイム状態ではなく、サニタイズ済みタスク要約を返します。

  • tasks.list には operator.read が必要です。
    • パラメーター: 任意の status"queued""running""completed""failed""cancelled"、または "timed_out")またはそれらのステータスの配列、任意の agentId、任意の sessionKey1 から 500 までの任意の limit、任意の文字列 cursor
    • 結果: { "tasks": TaskSummary[], "nextCursor"?: string }
  • tasks.get には operator.read が必要です。
    • パラメーター: { "taskId": string }
    • 結果: { "task": TaskSummary }
    • 見つからないタスク ID は、Gateway の not-found エラー形状を返します。
  • tasks.cancel には operator.write が必要です。
    • パラメーター: { "taskId": string, "reason"?: string }
    • 結果: { "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }
    • found は、台帳に一致するタスクがあったかどうかを報告します。cancelled は、ランタイムがキャンセルを受け入れたか、または記録したかどうかを報告します。

TaskSummary には、idstatus、および kindruntimetitleagentIdsessionKeychildSessionKeyownerKeyrunIdtaskIdflowIdparentTaskIdsourceId、タイムスタンプ、進捗、終端要約、サニタイズ済みエラーテキストなどの任意のメタデータが含まれます。agentId は、タスクを実行しているエージェントを識別します。sessionKeyownerKey は、リクエスターと制御コンテキストを保持します。

オペレーターヘルパーメソッド

  • オペレーターは commands.list (operator.read) を呼び出して、エージェントのランタイム コマンドインベントリを取得できます。
    • agentId は任意です。省略するとデフォルトのエージェントワークスペースを読み取ります。
    • scope は、プライマリ name が対象にするサーフェスを制御します:
      • text は、先頭の / を除いたプライマリテキストコマンドトークンを返します
      • native とデフォルトの both パスは、利用可能な場合にプロバイダーを考慮したネイティブ名を返します
    • textAliases/model/m などの正確なスラッシュエイリアスを保持します。
    • nativeName は、存在する場合にプロバイダーを考慮したネイティブコマンド名を保持します。
    • provider は任意で、ネイティブ名とネイティブプラグイン コマンドの可用性にのみ影響します。
    • includeArgs=false は、シリアライズされた引数メタデータをレスポンスから省略します。
  • オペレーターは tools.catalog (operator.read) を呼び出して、エージェントのランタイムツールカタログを取得できます。レスポンスには、グループ化されたツールと来歴メタデータが含まれます:
    • source: core または plugin
    • pluginId: source="plugin" の場合のプラグイン所有者
    • optional: プラグインツールが任意かどうか
  • オペレーターは tools.effective (operator.read) を呼び出して、セッションでランタイム上有効なツール インベントリを取得できます。
    • sessionKey は必須です。
    • Gateway は、呼び出し元が指定した認証または配信コンテキストを受け入れる代わりに、セッションからサーバー側で信頼済みランタイムコンテキストを導出します。
    • レスポンスは、アクティブなインベントリのセッションスコープのサーバー導出プロジェクションであり、 core、プラグイン、チャネル、すでに検出済みの MCP サーバーツールを含みます。
    • tools.effective は MCP に対して読み取り専用です。ウォーム状態のセッション MCP カタログを最終ツールポリシーに通して投影する場合がありますが、MCP ランタイムの作成、トランスポートの接続、または tools/list の発行は行いません。一致するウォームカタログが存在しない場合、レスポンスには mcp-not-yet-connectedmcp-not-yet-listed、または mcp-stale-catalog のような通知が含まれる場合があります。
    • 有効なツールエントリは source="core"source="plugin"source="channel"、または source="mcp" を使用します。
  • オペレーターは tools.invoke (operator.write) を呼び出して、 /tools/invoke と同じ Gateway ポリシーパスを通じて、利用可能なツールを 1 つ呼び出せます。
    • name は必須です。argssessionKeyagentIdconfirm、および idempotencyKey は任意です。
    • sessionKeyagentId の両方が存在する場合、解決されたセッションエージェントは agentId と一致する必要があります。
    • crongatewaynodes など所有者専用の core ラッパーは、 tools.invoke メソッド自体は operator.write ですが、 所有者/管理者 ID (operator.admin) が必要です。
    • レスポンスは、oktoolName、任意の output、および型付きの error フィールドを持つ SDK 向けエンベロープです。承認またはポリシーによる拒否は、Gateway ツールポリシーパイプラインを迂回するのではなく、ペイロード内で ok:false を返します。
  • オペレーターは skills.status (operator.read) を呼び出して、エージェントに表示される skill インベントリを取得できます。
    • agentId は任意です。省略するとデフォルトのエージェントワークスペースを読み取ります。
    • レスポンスには、適格性、不足している要件、設定チェック、および 生のシークレット値を公開しないサニタイズ済みインストールオプションが含まれます。
  • オペレーターは skills.searchskills.detail (operator.read) を呼び出して、 ClawHub 検出メタデータを取得できます。
  • オペレーターは skills.upload.beginskills.upload.chunk、および skills.upload.commit (operator.admin) を呼び出して、インストール前に非公開 skill アーカイブをステージングできます。これは信頼済みクライアント用の別個の管理者アップロードパスであり、 通常の ClawHub skill インストールフローではありません。また、 skills.install.allowUploadedArchives が有効でない限りデフォルトで無効です。
    • skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? }) は、その slug と force 値にバインドされたアップロードを作成します。
    • skills.upload.chunk({ uploadId, offset, dataBase64 }) は、正確なデコード済みオフセットにバイトを追加します。
    • skills.upload.commit({ uploadId, sha256? }) は、最終サイズと SHA-256 を検証します。コミットはアップロードを確定するだけで、skill はインストールしません。
    • アップロードされた skill アーカイブは、ルートに SKILL.md を含む zip アーカイブです。アーカイブ内部のディレクトリ名がインストール先を選択することはありません。
  • オペレーターは skills.install (operator.admin) を 3 つのモードで呼び出せます:
    • ClawHub モード: { source: "clawhub", slug, version?, force? } は、skill フォルダーをデフォルトのエージェントワークスペースの skills/ ディレクトリにインストールします。
    • アップロードモード: { source: "upload", uploadId, slug, force?, sha256?, timeoutMs? } は、コミット済みアップロードをデフォルトのエージェントワークスペースの skills/<slug> ディレクトリにインストールします。slug と force 値は、元の skills.upload.begin リクエストと一致する必要があります。このモードは skills.install.allowUploadedArchives が有効でない限り拒否されます。この設定は ClawHub インストールには影響しません。
    • Gateway インストーラーモード: { name, installId, timeoutMs? } は、Gateway ホスト上で宣言済みの metadata.openclaw.install アクションを実行します。 古いクライアントは引き続き dangerouslyForceUnsafeInstall を送信する場合があります。このフィールドは非推奨で、プロトコル互換性のためにのみ受け入れられ、無視されます。 オペレーター所有のインストール判断には security.installPolicy を使用してください。
  • オペレーターは skills.update (operator.admin) を 2 つのモードで呼び出せます:
    • ClawHub モードは、デフォルトのエージェントワークスペース内の、追跡対象の slug 1 つ、または追跡対象のすべての ClawHub インストールを更新します。
    • 設定モードは、enabledapiKeyenv などの skills.entries.<skillKey> 値にパッチを適用します。

models.list ビュー

models.list は任意の view パラメーターを受け付けます:

  • 省略または "default": 現在のランタイム動作。agents.defaults.models が設定されている場合、レスポンスは許可済みカタログになり、provider/* エントリに対して動的に検出されたモデルも含まれます。それ以外の場合、レスポンスは完全な Gateway カタログです。
  • "configured": ピッカー向けサイズの動作。agents.defaults.models が設定されている場合は、引き続きそれが優先され、provider/* エントリに対するプロバイダースコープの検出も含まれます。許可リストがない場合、レスポンスは明示的な 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 を権威ある command/cwd/セッションコンテキストとして再利用します。
  • 呼び出し元が prepare から最終承認済み system.run 転送までの間に commandrawCommandcwdagentId、または sessionKey を変更した場合、Gateway は変更されたペイロードを信頼せずに実行を拒否します。

エージェント配信フォールバック

  • agent リクエストには、アウトバウンド配信をリクエストするために deliver=true を含められます。
  • bestEffortDeliver=false は厳密な動作を維持します。未解決または内部専用の配信ターゲットは INVALID_REQUEST を返します。
  • bestEffortDeliver=true は、外部に配信可能なルートを解決できない場合に、セッションのみの実行へのフォールバックを許可します (たとえば、内部/webchat セッションや曖昧なマルチチャネル設定)。
  • 最終的な agent 結果には、配信がリクエストされた場合に result.deliveryStatus が含まれる場合があり、openclaw agent --json --deliver で文書化されているものと同じ sentsuppressedpartial_failed、および failed ステータスを使用します。

バージョニング

  • PROTOCOL_VERSIONpackages/gateway-protocol/src/version.ts にあります。
  • クライアントは minProtocol + maxProtocol を送信します。サーバーは、 現在のプロトコルを含まない範囲を拒否します。現在のクライアントとサーバーは プロトコル v4 を必要とします。
  • スキーマ + モデルは TypeBox 定義から生成されます:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

クライアント定数

src/gateway/client.ts のリファレンスクライアントは、これらのデフォルトを使用します。値は プロトコル v4 全体で安定しており、サードパーティクライアントの想定ベースラインです。

定数 デフォルト ソース
PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
MIN_CLIENT_PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
リクエストタイムアウト (RPC ごと) 30_000 ms src/gateway/client.ts (requestTimeoutMs)
事前認証 / 接続チャレンジのタイムアウト 15_000 ms src/gateway/handshake-timeouts.ts (config/env can raise the paired server/client budget)
初期再接続バックオフ 1_000 ms src/gateway/client.ts (backoffMs)
最大再接続バックオフ 30_000 ms src/gateway/client.ts (scheduleReconnect)
device-token クローズ後の高速リトライ制限 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 を超えた場合は code 4000 src/gateway/client.ts
MAX_PAYLOAD_BYTES 25 * 1024 * 1024 (25 MB) src/gateway/server-constants.ts

サーバーは、有効な policy.tickIntervalMspolicy.maxPayload、 および policy.maxBufferedByteshello-ok で通知します。クライアントは、ハンドシェイク前のデフォルトではなく、それらの値を尊重する必要があります。

認証

  • 共有シークレットの Gateway 認証は、設定された認証モードに応じて、connect.params.auth.token または connect.params.auth.password を使用します。
  • Tailscale Serve (gateway.auth.allowTailscale: true) や非ループバックの gateway.auth.mode: "trusted-proxy" など、ID を伴うモードは、 connect.params.auth.* の代わりにリクエストヘッダーから connect 認証チェックを満たします。
  • プライベートイングレスの gateway.auth.mode: "none" は、共有シークレットの connect 認証を 完全にスキップします。このモードをパブリックまたは信頼できないイングレスに公開しないでください。
  • ペアリング後、Gateway は接続ロール + スコープに限定された デバイストークン を発行します。 これは hello-ok.auth.deviceToken で返され、今後の接続のためにクライアントが永続化する必要があります。
  • クライアントは、成功した connect の後に必ず主要な hello-ok.auth.deviceToken を永続化する必要があります。
  • その 保存済み デバイストークンで再接続する場合、そのトークンに対して保存済みの承認済みスコープセットも再利用する必要があります。 これにより、すでに付与された読み取り/プローブ/ステータスアクセスが保持され、再接続が暗黙の管理者専用スコープへ 気づかないうちに狭められることを避けられます。
  • クライアント側の connect 認証組み立て (src/gateway/client.tsselectConnectAuth):
    • auth.password は独立しており、設定されている場合は常に転送されます。
    • auth.token は優先順で設定されます。明示的な共有トークンが最優先で、 次に明示的な deviceToken、その次に保存済みのデバイス単位トークン (deviceId + role でキー付け) です。
    • auth.bootstrapToken は、上記のどれも auth.token を解決しなかった場合にのみ送信されます。 共有トークンまたは解決済みのデバイストークンがある場合、これは抑制されます。
    • 1 回限りの AUTH_TOKEN_MISMATCH 再試行で保存済みデバイストークンを自動昇格する処理は、 信頼済みエンドポイントのみ に制限されます。つまり、ループバック、または tlsFingerprint がピン留めされた wss:// です。ピン留めのないパブリック wss:// は該当しません。
  • 組み込みセットアップコードのブートストラップは、主要な Node hello-ok.auth.deviceToken に加え、信頼済みモバイル引き渡し用の制限付きオペレータートークンを hello-ok.auth.deviceTokens で返します。オペレータートークンには、ネイティブ Talk 設定の読み取り用に operator.talk.secrets が含まれますが、ペアリング変更スコープと operator.admin は除外されます。
  • 非ベースラインのセットアップコードブートストラップが承認待ちの間、PAIRING_REQUIRED の詳細には recommendedNextStep: "wait_then_retry"retryable: truepauseReconnect: false が含まれます。クライアントは、リクエストが承認されるかトークンが無効になるまで、 同じブートストラップトークンで再接続を続ける必要があります。
  • hello-ok.auth.deviceTokens は、connect が wss:// やループバック/local ペアリングなどの信頼済みトランスポート上で ブートストラップ認証を使用した場合にのみ永続化してください。
  • クライアントが 明示的な deviceToken または明示的な scopes を提供した場合、その呼び出し元が要求した スコープセットが引き続き正となります。キャッシュ済みスコープは、クライアントが保存済みのデバイス単位トークンを 再利用している場合にのみ再利用されます。
  • デバイストークンは device.token.rotatedevice.token.revoke でローテーション/失効できます (operator.pairing スコープが必要)。Node または他の非オペレーターロールを ローテーションまたは失効する場合は、operator.admin も必要です。
  • device.token.rotate はローテーションメタデータを返します。置換用のベアラートークンは、 そのデバイストークンですでに認証済みの同一デバイス呼び出しにのみエコーされます。そのため、トークンのみのクライアントは 再接続前に置換トークンを永続化できます。共有/管理者ローテーションではベアラートークンはエコーされません。
  • トークンの発行、ローテーション、失効は、そのデバイスのペアリングエントリに記録された承認済みロールセットに制限されます。 トークン変更によって、ペアリング承認で付与されていないデバイスロールへ拡張したり、対象にしたりすることはできません。
  • ペアリング済みデバイストークンのセッションでは、呼び出し元が operator.admin も持っていない限り、 デバイス管理は自己スコープに制限されます。非管理者の呼び出し元が管理できるのは、自分自身の デバイスエントリの オペレータートークンのみです。Node や他の非オペレータートークンの管理は、呼び出し元自身のデバイスであっても管理者専用です。
  • device.token.rotatedevice.token.revoke は、対象のオペレータートークンのスコープセットを、 呼び出し元の現在のセッションスコープとも照合します。非管理者の呼び出し元は、自分がすでに保持しているものより広い オペレータートークンをローテーションまたは失効できません。
  • 認証失敗には、error.details.code と復旧ヒントが含まれます:
    • error.details.canRetryWithDeviceToken (boolean)
    • error.details.recommendedNextStep (retry_with_device_token, update_auth_configuration, update_auth_credentials, wait_then_retry, review_auth_configuration)
  • AUTH_TOKEN_MISMATCH に対するクライアントの動作:
    • 信頼済みクライアントは、キャッシュ済みのデバイス単位トークンで 1 回だけ制限付き再試行を試みることができます。
    • その再試行が失敗した場合、クライアントは自動再接続ループを停止し、オペレーターの対応案内を表示する必要があります。
  • AUTH_SCOPE_MISMATCH は、デバイストークンは認識されたものの、要求されたロール/スコープをカバーしていないことを意味します。 クライアントはこれを不正なトークンとして提示しないでください。オペレーターに、再ペアリングするか、より狭い/広いスコープ契約を 承認するよう促してください。

デバイス ID + ペアリング

  • Node は、鍵ペアのフィンガープリントから派生した安定したデバイス ID (device.id) を含める必要があります。
  • Gateway はデバイス + ロールごとにトークンを発行します。
  • local 自動承認が有効でない限り、新しいデバイス ID にはペアリング承認が必要です。
  • ペアリングの自動承認は、直接の local loopback 接続を中心にしています。
  • OpenClaw には、信頼済み共有シークレットヘルパーフロー用に、狭いバックエンド/コンテナローカルの自己接続パスもあります。
  • 同一ホストの tailnet または LAN 接続も、ペアリングでは引き続きリモートとして扱われ、承認が必要です。
  • WS クライアントは通常、connect 中に device ID を含めます (オペレーター + Node)。デバイスなしのオペレーター例外は、明示的な信頼パスのみです:
    • localhost 専用の安全でない HTTP 互換性のための gateway.controlUi.allowInsecureAuth=true
    • 成功した gateway.auth.mode: "trusted-proxy" オペレーター Control UI 認証。
    • gateway.controlUi.dangerouslyDisableDeviceAuth=true (非常用、重大なセキュリティ低下)。
    • 予約済み内部ヘルパーパス上の direct-loopback gateway-client バックエンド RPC。
  • デバイス ID を省略するとスコープ上の影響があります。デバイスなしのオペレーター接続が明示的な信頼パスで許可された場合でも、 OpenClaw は、そのパスに名前付きのスコープ保持例外がない限り、自己申告されたスコープを空セットにクリアします。 その後、スコープで制限されたメソッドは missing scope で失敗します。
  • gateway.controlUi.dangerouslyDisableDeviceAuth=true は、Control UI の非常用スコープ保持パスです。 任意のカスタムバックエンドや CLI 形式の WebSocket クライアントにスコープを付与するものではありません。
  • 予約済みの direct-loopback gateway-client バックエンドヘルパーパスは、 内部 local コントロールプレーン RPC に対してのみスコープを保持します。カスタムバックエンド ID はこの例外を受けません。
  • すべての接続は、サーバーが提供する connect.challenge nonce に署名する必要があります。

デバイス認証移行診断

チャレンジ前の署名動作をまだ使用しているレガシークライアントに対して、connect は現在、 安定した error.details.reason とともに、error.details.code 配下で DEVICE_AUTH_* 詳細コードを返します。

一般的な移行失敗:

メッセージ 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 ペイロードに署名します。
  • 同じ nonce を connect.params.device.nonce で送信します。
  • 推奨される署名ペイロードは v3 です。これは device/client/role/scopes/token/nonce フィールドに加えて、 platformdeviceFamily を結び付けます。
  • レガシー v2 署名は互換性のため引き続き受け入れられますが、再接続時のコマンドポリシーは ペアリング済みデバイスのメタデータピン留めによって引き続き制御されます。

TLS + ピン留め

  • TLS は WS 接続でサポートされています。
  • クライアントは任意で Gateway 証明書フィンガープリントをピン留めできます (gateway.tls 設定に加え、gateway.remote.tlsFingerprint または CLI --tls-fingerprint を参照)。

スコープ

このプロトコルは 完全な Gateway API (ステータス、チャンネル、モデル、チャット、 エージェント、セッション、Node、承認など) を公開します。正確なサーフェスは packages/gateway-protocol/src/schema.ts の TypeBox スキーマで定義されています。

関連

Was this useful?
On this page

On this page