Gateway-gesteuertes Pairing (Option B)

Beim Gateway-gesteuerten Pairing ist das Gateway die zentrale Instanz, die entscheidet, welche Nodes beitreten dürfen. UIs (macOS-App, zukünftige Clients) sind nur Frontends, die ausstehende Anfragen genehmigen oder ablehnen.

Wichtig: WS-Nodes nutzen Device Pairing (Rolle node) beim connect. node.pair.* ist ein separater Pairing-Store und hat keinen Einfluss auf den WS-Handshake. Nur Clients, die explizit node.pair.* aufrufen, nutzen diesen Flow.

Konzepte

  • Ausstehende Anfrage: Ein Node hat um Beitritt gebeten und wartet auf Genehmigung.
  • Gepairter Node: Ein genehmigter Node mit einem ausgestellten Auth-Token.
  • Transport: Der Gateway-WS-Endpoint leitet Anfragen weiter, entscheidet aber nicht über die Mitgliedschaft. (Legacy-TCP-Bridge-Support ist veraltet/entfernt.)

So funktioniert Pairing

  1. Ein Node verbindet sich mit dem Gateway-WS und fordert Pairing an.
  2. Das Gateway speichert eine ausstehende Anfrage und sendet node.pair.requested.
  3. Du genehmigst oder lehnst die Anfrage ab (CLI oder UI).
  4. Bei Genehmigung stellt das Gateway einen neuen Token aus (Tokens werden bei erneutem Pairing rotiert).
  5. Der Node verbindet sich mit dem Token neu und ist jetzt „gepairt”.

Ausstehende Anfragen laufen automatisch nach 5 Minuten ab.

CLI-Workflow (headless-freundlich)

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 zeigt gepairte/verbundene Nodes und ihre Fähigkeiten.

API-Oberfläche (Gateway-Protokoll)

Events:

  • node.pair.requested — wird gesendet, wenn eine neue ausstehende Anfrage erstellt wird.
  • node.pair.resolved — wird gesendet, wenn eine Anfrage genehmigt/abgelehnt/abgelaufen ist.

Methoden:

  • node.pair.request — erstellt oder verwendet eine bestehende ausstehende Anfrage.
  • node.pair.list — listet ausstehende + gepairte Nodes auf.
  • node.pair.approve — genehmigt eine ausstehende Anfrage (stellt Token aus).
  • node.pair.reject — lehnt eine ausstehende Anfrage ab.
  • node.pair.verify — verifiziert { nodeId, token }.

Hinweise:

  • node.pair.request ist idempotent pro Node: Wiederholte Aufrufe geben dieselbe ausstehende Anfrage zurück.
  • Genehmigung generiert immer einen neuen Token; von node.pair.request wird nie ein Token zurückgegeben.
  • Anfragen können silent: true enthalten als Hinweis für Auto-Approval-Flows.

Auto-Approval (macOS-App)

Die macOS-App kann optional eine stille Genehmigung versuchen, wenn:

  • die Anfrage als silent markiert ist, und
  • die App eine SSH-Verbindung zum Gateway-Host mit demselben Benutzer verifizieren kann.

Wenn die stille Genehmigung fehlschlägt, fällt sie auf den normalen „Genehmigen/Ablehnen”-Dialog zurück.

Speicherung (lokal, privat)

Der Pairing-Status wird im Gateway-Statusverzeichnis gespeichert (Standard ~/.openclaw):

  • ~/.openclaw/nodes/paired.json
  • ~/.openclaw/nodes/pending.json

Wenn du OPENCLAW_STATE_DIR überschreibst, wandert der nodes/-Ordner mit.

Sicherheitshinweise:

  • Tokens sind Geheimnisse — behandle paired.json als sensibel.
  • Um einen Token zu rotieren, ist eine erneute Genehmigung erforderlich (oder das Löschen des Node-Eintrags).

Transport-Verhalten

  • Der Transport ist zustandslos und speichert keine Mitgliedschaft.
  • Wenn das Gateway offline ist oder Pairing deaktiviert ist, können Nodes nicht pairen.
  • Wenn das Gateway im Remote-Modus ist, erfolgt das Pairing trotzdem gegen den Store des Remote-Gateways.