メインコンテンツへスキップ

Gateway所有ペアリング(Option B)

Gateway所有ペアリングでは、どのノードの参加を許可するかについて、Gateway が信頼できる唯一の情報源です。UI(macOSアプリ、将来のクライアント)は、保留中リクエストを承認または拒否するためのフロントエンドにすぎません。 重要: WSノードは、connect 時にデバイスペアリング(role node)を使用します。 node.pair.* は別のペアリングストアであり、WSハンドシェイクを制御しません。 このフローを使うのは、明示的に node.pair.* を呼び出すクライアントだけです。

概念

  • 保留中リクエスト: ノードが参加を要求した状態。承認が必要です。
  • ペアリング済みノード: 承認され、認証トークンが発行されたノード。
  • トランスポート: Gateway WSエンドポイントはリクエストを転送しますが、参加可否は決定しません。(レガシーTCP bridgeサポートは削除されました。)

ペアリングの仕組み

  1. ノードがGateway WSに接続し、ペアリングを要求します。
  2. Gatewayが保留中リクエストを保存し、node.pair.requested を発行します。
  3. リクエストを承認または拒否します(CLIまたはUI)。
  4. 承認時、Gatewayは新しいトークンを発行します(再ペアリング時にはトークンがローテーションされます)。
  5. ノードはそのトークンを使って再接続し、「ペアリング済み」になります。
保留中リクエストは5分後に自動的に期限切れになります。

CLIワークフロー(ヘッドレス対応)

openclaw nodes pending
openclaw nodes approve <requestId>
openclaw nodes reject <requestId>
openclaw nodes status
openclaw nodes rename --node <id|name|ip> --name "Living Room iPad"
nodes status は、ペアリング済み/接続済みノードとそのcapabilitiesを表示します。

APIインターフェース(gatewayプロトコル)

イベント:
  • node.pair.requested — 新しい保留中リクエストが作成されたときに発行されます。
  • node.pair.resolved — リクエストが承認/拒否/期限切れになったときに発行されます。
メソッド:
  • node.pair.request — 保留中リクエストを作成または再利用します。
  • node.pair.list — 保留中 + ペアリング済みノードを一覧表示します(operator.pairing)。
  • node.pair.approve — 保留中リクエストを承認します(トークンを発行)。
  • node.pair.reject — 保留中リクエストを拒否します。
  • node.pair.verify{ nodeId, token } を検証します。
注:
  • node.pair.request はノードごとに冪等です。繰り返し呼び出しても同じ保留中リクエストが返されます。
  • 同じ保留中ノードに対する繰り返しリクエストでは、保存済みノードメタデータと、オペレーター可視化用の最新のallowlist済み宣言コマンドスナップショットも更新されます。
  • 承認では常に新しいトークンが生成されます。node.pair.request からトークンが返されることはありません。
  • リクエストには、自動承認フローのヒントとして silent: true を含めることができます。
  • node.pair.approve は、保留中リクエストの宣言済みコマンドを使って追加承認スコープを適用します:
    • コマンドなしリクエスト: operator.pairing
    • exec 以外のコマンドリクエスト: operator.pairing + operator.write
    • system.run / system.run.prepare / system.which リクエスト: operator.pairing + operator.admin
重要:
  • ノードペアリングは、信頼/IDフローとトークン発行です。
  • これは、ノードごとのライブなノードコマンドインターフェースを固定するものではありません
  • ライブなノードコマンドは、Gatewayのグローバルなノードコマンドポリシー(gateway.nodes.allowCommands / denyCommands)適用後に、ノードが接続時に宣言した内容から決まります。
  • ノードごとの system.run のallow/askポリシーは、ペアリングレコードではなく、ノード上の exec.approvals.node.* にあります。

ノードコマンドのゲーティング(2026.3.31以降)

破壊的変更: 2026.3.31 以降、ノードペアリングが承認されるまでノードコマンドは無効になります。デバイスペアリングだけでは、宣言されたノードコマンドを公開するのに不十分になりました。
ノードが初めて接続すると、ペアリングが自動的に要求されます。ペアリングリクエストが承認されるまで、そのノードからの保留中ノードコマンドはすべてフィルタリングされ、実行されません。ペアリング承認によって信頼が確立されると、ノードが宣言したコマンドは通常のコマンドポリシーに従って利用可能になります。 これは次を意味します:
  • 以前はデバイスペアリングのみでコマンドを公開していたノードも、今後はノードペアリングを完了する必要があります。
  • ペアリング承認前にキューに入れられたコマンドは延期されず、破棄されます。

ノードイベントの信頼境界(2026.3.31以降)

破壊的変更: ノード起点の実行は、より制限された信頼済みインターフェースにとどまるようになりました。
ノード起点の要約と関連するセッションイベントは、意図された信頼済みインターフェースに制限されます。以前はより広いホストまたはセッションのツールアクセスに依存していた通知駆動またはノード起点のフローは、調整が必要になる場合があります。このハードニングにより、ノードイベントが、そのノードの信頼境界を超えてホストレベルのツールアクセスへ昇格することを防ぎます。

自動承認(macOSアプリ)

macOSアプリは、次の場合にサイレント承認を試行できます:
  • リクエストが silent とマークされており、
  • アプリが同じユーザーを使ったgateway hostへのSSH接続を確認できる場合。
サイレント承認に失敗した場合は、通常の「承認/拒否」プロンプトにフォールバックします。

ストレージ(ローカル、プライベート)

ペアリング状態はGatewayのstate directory配下に保存されます(デフォルトは ~/.openclaw):
  • ~/.openclaw/nodes/paired.json
  • ~/.openclaw/nodes/pending.json
OPENCLAW_STATE_DIR を上書きすると、nodes/ フォルダーもそれに合わせて移動します。 セキュリティ上の注意:
  • トークンはシークレットです。paired.json は機密として扱ってください。
  • トークンのローテーションには再承認(またはノードエントリーの削除)が必要です。

トランスポートの動作

  • トランスポートはステートレスであり、参加情報を保存しません。
  • Gatewayがオフライン、またはペアリングが無効な場合、ノードはペアリングできません。
  • Gatewayがremote modeでも、ペアリングは引き続きリモートGatewayのストアに対して行われます。