Gateway-gesteuerte Kopplung (Option B)

Bei der Gateway-gesteuerten Kopplung ist das Gateway die zentrale Instanz, die festlegt, welche Nodes beitreten dürfen. UIs (macOS-App, zukünftige Clients) sind lediglich Frontends, die ausstehende Anfragen genehmigen oder ablehnen.

Wichtig: WS-Nodes verwenden Device-Pairing (Rolle node) während connect. node.pair.* ist ein separater Kopplungs-Store und steuert nicht den WS-Handshake. Nur Clients, die explizit node.pair.* aufrufen, nutzen diesen Ablauf.

Konzepte

  • Ausstehende Anfrage: Ein Node hat den Beitritt angefragt; erfordert Genehmigung.
  • Gekoppelter Node: Genehmigter Node mit ausgestelltem Auth-Token.
  • Transport: Der Gateway-WS-Endpunkt leitet Anfragen weiter, trifft aber keine Mitgliedschaftsentscheidungen. (Legacy-TCP-Bridge-Support ist deprecated/entfernt.)

Wie die Kopplung funktioniert

  1. Ein Node verbindet sich mit dem Gateway-WS und fordert die Kopplung 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 ein neues Token aus (Tokens werden bei erneuter Kopplung rotiert).
  5. Der Node verbindet sich mit dem Token erneut und ist nun “gekoppelt”.

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 gekoppelte/verbundene Nodes und deren Fähigkeiten an.

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 — ausstehende Anfrage erstellen oder vorhandene wiederverwenden.
  • node.pair.list — ausstehende + gekoppelte Nodes auflisten.
  • node.pair.approve — ausstehende Anfrage genehmigen (stellt Token aus).
  • node.pair.reject — ausstehende Anfrage ablehnen.
  • node.pair.verify{ nodeId, token } verifizieren.

Hinweise:

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

Auto-Genehmigung (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 Kopplungszustand wird im Gateway-State-Verzeichnis 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.
  • Zum Rotieren eines Tokens ist eine erneute Genehmigung erforderlich (oder das Löschen des Node-Eintrags).

Transport-Verhalten

  • Der Transport ist zustandslos; er speichert keine Mitgliedschaft.
  • Wenn das Gateway offline ist oder die Kopplung deaktiviert, können sich Nodes nicht koppeln.
  • Wenn das Gateway im Remote-Modus läuft, findet die Kopplung trotzdem gegen den Store des Remote-Gateways statt.