Bridge protocol(legacy node transport)
なぜ存在していたのか
- セキュリティ境界: bridgeはGateway API surface全体ではなく、小さなallowlistのみを公開します。
- pairing + node identity: nodeの受け入れはGatewayが管理し、nodeごとのトークンに結び付けられます。
- Discovery UX: nodeはLAN上でBonjour経由でGatewayを発見するか、tailnet経由で直接接続できます。
- Loopback WS: 完全なWS control planeは、SSHでトンネルされない限りローカルのままです。
Transport
- TCP、1行ごとに1つのJSONオブジェクト(JSONL)。
- 任意のTLS(
bridge.tls.enabledがtrueのとき)。 - 以前のデフォルトlistenerポートは
18790でした(現在のビルドではTCP bridgeは起動しません)。
bridgeTls=1 と bridgeTlsSha256 が含まれます。なお、Bonjour/mDNS TXTレコードには認証がないため、クライアントは明示的なユーザー意思やその他の帯域外検証なしに、広告されたフィンガープリントを信頼できるpinとして扱ってはいけません。
Handshake + pairing
- クライアントは、nodeメタデータとトークン(すでにpair済みの場合)を含む
helloを送信します。 - pairされていない場合、Gatewayは
error(NOT_PAIRED/UNAUTHORIZED)を返します。 - クライアントは
pair-requestを送信します。 - Gatewayは承認を待ち、その後
pair-okとhello-okを送信します。
hello-ok は serverName を返し、canvasHostUrl を含むこともありました。
Frames
クライアント → Gateway:req/res: スコープ付きGateway RPC(chat、sessions、config、health、voicewake、skills.bins)event: nodeシグナル(voice transcript、agent request、chat subscribe、exec lifecycle)
invoke/invoke-res: nodeコマンド(canvas.*、camera.*、screen.record、location.get、sms.send)event: subscribeされたsession向けのchat更新ping/pong: keepalive
src/gateway/server-bridge.ts にありました(現在は削除済み)。
Exec lifecycle events
nodeはexec.finished または exec.denied eventを送信して、system.runアクティビティを表面化できます。
これらはGateway内でsystem eventにマッピングされます。(legacy nodeは exec.started をまだ送信することがあります。)
ペイロードフィールド(特記がない限りすべて任意):
sessionKey(必須): system eventを受け取るagent session。runId: グループ化のための一意なexec id。command: 生の、または整形済みのコマンド文字列。exitCode、timedOut、success、output: 完了の詳細(finishedのみ)。reason: 拒否理由(deniedのみ)。
履歴上のtailnet利用
- bridgeをtailnet IPにbindするには:
~/.openclaw/openclaw.jsonでbridge.bind: "tailnet"を設定します(履歴情報のみ。bridge.*はもう有効ではありません)。 - クライアントはMagicDNS名またはtailnet IP経由で接続します。
- Bonjourはネットワークをまたがりません。必要な場合は手動のhost/portまたは広域DNS‑SDを使用してください。