OpenClaw Gateway-Protokoll: WebSocket-Verbindung aufbauen
Kennst du das Problem? Du arbeitest an einem verteilten System und jeder Client kocht sein eigenes Süppchen, wenn es um die Kommunikation geht. Das Gateway-Protokoll von OpenClaw löst dieses Chaos, indem es alles über einen zentralen Punkt steuert.
Das Gateway WS-Protokoll ist die zentrale Control Plane + Node Transport für OpenClaw. Alle Clients (CLI, Web-UI, macOS-App, iOS/Android-Nodes, Headless-Nodes) verbinden sich über WebSocket und geben beim Handshake ihre Role und ihren Scope an.
Transport
Abschnitt betitelt „Transport“- WebSocket, Text-Frames mit JSON-Payloads.
- Der erste Frame muss ein
connect-Request sein.
Handshake (Verbindung)
Abschnitt betitelt „Handshake (Verbindung)“Gateway → Client (Pre-Connect Challenge):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Client → Gateway:
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "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 → Client:
{ "type": "res", "id": "…", "ok": true, "payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }}Wenn ein Device-Token ausgestellt wird, enthält hello-ok ebenfalls:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}Node-Beispiel
Abschnitt betitelt „Node-Beispiel“{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "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": "…" } }}Framing
Abschnitt betitelt „Framing“- Request:
{type:"req", id, method, params} - Response:
{type:"res", id, ok, payload|error} - Event:
{type:"event", event, payload, seq?, stateVersion?}
Methoden mit Side-Effects benötigen Idempotency Keys (siehe Schema).
Rollen + Scopes
Abschnitt betitelt „Rollen + Scopes“operator= Control-Plane-Client (CLI/UI/Automatisierung).node= Capability-Host (camera/screen/canvas/system.run).
Scopes (Operator)
Abschnitt betitelt „Scopes (Operator)“Häufige Scopes:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairing
Der Method-Scope ist nur die erste Hürde. Einige Slash-Commands, die über chat.send erreicht werden, wenden zusätzlich strengere Prüfungen auf Command-Ebene an. Zum Beispiel erfordern persistente Schreibvorgänge via /config set und /config unset den Scope operator.admin.
Caps/Commands/Permissions (Node)
Abschnitt betitelt „Caps/Commands/Permissions (Node)“Nodes deklarieren ihre Capability-Ansprüche beim Verbindungsaufbau:
caps: Übergreifende Capability-Kategorien.commands: Allowlist für ausführbare Befehle.permissions: Granulare Schalter (z. B.screen.record,camera.capture).
Das Gateway behandelt diese als Claims und setzt serverseitige Allowlists durch.
Presence
Abschnitt betitelt „Presence“system-presencegibt Einträge zurück, die nach der Geräte-Identität (Device Identity) sortiert sind.- Presence-Einträge enthalten
deviceId,rolesundscopes. So können UIs eine einzelne Zeile pro Gerät anzeigen, selbst wenn es sich gleichzeitig als Operator und Node verbindet.
Node-Helper-Methoden
Abschnitt betitelt „Node-Helper-Methoden“- Nodes können
skills.binsaufrufen, um die aktuelle Liste der Skill-Executables für automatische Allow-Checks abzurufen.
Operator-Helper-Methoden
Abschnitt betitelt „Operator-Helper-Methoden“- Operator können
tools.catalog(operator.read) aufrufen, um den Runtime-Tool-Katalog für einen Agent abzurufen. Die Antwort enthält gruppierte Tools und Provenienz-Metadaten:source:coreoderpluginpluginId: Plugin-Besitzer, wennsource="plugin"optional: Gibt an, ob ein Plugin-Tool optional ist
- Operator können
tools.effective(operator.read) aufrufen, um das für eine Session aktuell gültige Tool-Inventar abzurufen.sessionKeyist erforderlich.- Das Gateway leitet den vertrauenswürdigen Runtime-Kontext serverseitig aus der Session ab, anstatt vom Aufrufer bereitgestellte Auth- oder Delivery-Kontexte zu akzeptieren.
- Die Antwort ist auf die Session beschränkt und spiegelt wider, was die aktive Konversation gerade nutzen kann (einschließlich Core-, Plugin-, Channel- sowie Session-Tools).
Exec-Freigaben
Abschnitt betitelt „Exec-Freigaben“- Wenn ein Exec-Request eine Freigabe benötigt, sendet das Gateway ein
exec.approval.requestedper Broadcast. - Operator-Clients lösen dies durch den Aufruf von
exec.approval.resolve(erfordertoperator.approvalsScope). - Für
host=nodemussexec.approval.requestdensystemRunPlanenthalten (kanonische Daten wieargv/cwd/rawCommandund Session-Metadaten). Anfragen ohnesystemRunPlanwerden abgelehnt.
Agent Delivery Fallback
Abschnitt betitelt „Agent Delivery Fallback“agent-Requests könnendeliver=trueenthalten, um eine ausgehende Zustellung anzufordern.bestEffortDeliver=falseerzwingt striktes Verhalten: Nicht auflösbare oder rein interne Delivery-Ziele gebenINVALID_REQUESTzurück.bestEffortDeliver=trueerlaubt einen Fallback auf die reine Session-Ausführung, wenn keine externe Route aufgelöst werden kann (zum Beispiel bei internen Webchat-Sessions oder mehrdeutigen Multi-Channel-Konfigurationen).
Versionierung
Abschnitt betitelt „Versionierung“- Die
PROTOCOL_VERSIONist insrc/gateway/protocol/schema.tsdefiniert. - Clients senden
minProtocolundmaxProtocol; der Server lehnt Abweichungen ab. - Schemas und Modelle werden aus TypeBox-Definitionen generiert:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check- Sowie die zugehörige Validierung.
- Wenn
OPENCLAW_GATEWAY_TOKEN(oder--token) gesetzt ist, mussconnect.params.auth.tokenübereinstimmen, sonst wird der Socket geschlossen. - Nach dem Pairing stellt das Gateway ein Device-Token aus, das auf die Rolle und die Scopes der Verbindung begrenzt ist. Es wird in
hello-ok.auth.deviceTokenzurückgegeben und sollte vom Client für zukünftige Verbindungen gespeichert werden. - Device-Token können über
device.token.rotateunddevice.token.revokerotiert oder widerrufen werden (erfordertoperator.pairingScope). - Auth-Fehler enthalten einen
error.details.codesowie Hinweise zur Behebung:error.details.canRetryWithDeviceToken(Boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Client-Verhalten bei
AUTH_TOKEN_MISMATCH:- Vertrauenswürdige Clients können einen begrenzten Retry-Versuch mit einem zwischengespeicherten Device-Token unternehmen.
- Schlägt dieser Versuch fehl, sollten Clients automatische Reconnect-Schleifen stoppen und dem Operator Handlungsanweisungen anzeigen.
Geräte-Identität + Pairing
Abschnitt betitelt „Geräte-Identität + Pairing“- Nodes sollten eine stabile Geräte-Identität (
device.id) übermitteln, die von einem Keypair-Fingerprint abgeleitet ist. - Gateways stellen Token pro Gerät und Rolle aus.
- Pairing-Freigaben sind für neue Device-IDs erforderlich, außer die lokale Auto-Freigabe ist aktiviert.
- Lokale Verbindungen umfassen Loopback-Adressen und die eigene Tailnet-Adresse des Gateway-Hosts (sodass Tailnet-Binds auf demselben Host weiterhin automatisch freigegeben werden können).
- Alle WS-Clients müssen während des
connecteinedevice-Identität angeben (Operator + Node). Die Control-UI kann dies nur in folgenden Modi weglassen:gateway.controlUi.allowInsecureAuth=truefür unsichere HTTP-Kompatibilität auf Localhost.gateway.controlUi.dangerouslyDisableDeviceAuth=true(Notfall-Option, starke Sicherheitsminderung).
- Alle Verbindungen müssen die vom Server bereitgestellte
connect.challengeNonce signieren.
Diagnose für die Device-Auth-Migration
Abschnitt betitelt „Diagnose für die Device-Auth-Migration“Für ältere Clients, die noch das Verhalten vor der Challenge-Signierung nutzen, gibt connect jetzt DEVICE_AUTH_* Detail-Codes unter error.details.code mit einem stabilen error.details.reason zurück.
Häufige Migrationsfehler:
| Nachricht | details.code | details.reason | Bedeutung |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | Client hat device.nonce weggelassen. |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | Client hat mit einer falschen Nonce signiert. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | Signatur-Payload passt nicht zum v2-Payload. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | Zeitstempel liegt außerhalb der Toleranz. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id passt nicht zum Public-Key. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | Format des Public-Key ist ungültig. |
Migrations-Ziel:
- Warte immer auf die
connect.challenge. - Signiere den v2-Payload, der die Server-Nonce enthält.
- Sende dieselbe Nonce in
connect.params.device.nonce. - Der bevorzugte Signatur-Payload ist
v3, der zusätzlichplatformunddeviceFamilyan die Felder für Gerät, Client, Rolle, Scopes, Token und Nonce bindet. - Ältere
v2-Signaturen werden aus Kompatibilitätsgründen weiterhin akzeptiert.
TLS + Pinning
Abschnitt betitelt „TLS + Pinning“- TLS wird für WS-Verbindungen unterstützt.
- Clients können optional den Fingerprint des Gateway-Zertifikats pinnen (siehe
gateway.tlsKonfiguration sowiegateway.remote.tlsFingerprintoder CLI--tls-fingerprint).
Dieses Protokoll macht die gesamte Gateway-API verfügbar (Status, Channels, Models, Chat, Agent, Sessions, Nodes, Freigaben usw.). Der exakte Umfang ist durch die TypeBox-Schemas in src/gateway/protocol/schema.ts definiert.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“OpenClaw Expert
Noch festgefahren?
Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.