Gateway protocol (WebSocket)

Gateway WS protocol là giao thức vận chuyển duy nhất cho control plane + node của OpenClaw. Tất cả các client (CLI, web UI, macOS app, iOS/Android nodes, headless nodes) đều kết nối qua WebSocket và khai báo role + scope của mình khi handshake.

Transport

  • WebSocket, text frames với JSON payloads.
  • Frame đầu tiên bắt buộc phải là request connect.

Handshake (connect)

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 } }
}

Khi device token được cấp, hello-ok cũng bao gồm:

{
  "auth": {
    "deviceToken": "…",
    "role": "operator",
    "scopes": ["operator.read", "operator.write"]
  }
}

Ví dụ Node

{
  "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

  • Request: {type:"req", id, method, params}
  • Response: {type:"res", id, ok, payload|error}
  • Event: {type:"event", event, payload, seq?, stateVersion?}

Các method có side-effect yêu cầu idempotency keys (xem schema).

Roles + scopes

Roles

  • operator = control plane client (CLI/UI/automation).
  • node = capability host (camera/screen/canvas/system.run).

Scopes (operator)

Các scope phổ biến:

  • operator.read
  • operator.write
  • operator.admin
  • operator.approvals
  • operator.pairing

Caps/commands/permissions (node)

Nodes khai báo capability claims khi connect:

  • caps: các danh mục capability cấp cao.
  • commands: danh sách lệnh được phép cho invoke.
  • permissions: các toggle chi tiết (ví dụ screen.record, camera.capture).

Gateway xử lý những thứ này như claims và thực thi allowlists ở phía server.

Presence

  • system-presence trả về các entry được đánh key theo device identity.
  • Các entry Presence bao gồm deviceId, roles, và scopes để UI có thể hiển thị một dòng duy nhất cho mỗi thiết bị ngay cả khi nó kết nối với cả hai vai trò operatornode.

Node helper methods

  • Nodes có thể gọi skills.bins để lấy danh sách các skill executables hiện tại cho việc kiểm tra auto-allow.

Exec approvals

  • Khi một exec request cần phê duyệt, gateway sẽ broadcast exec.approval.requested.
  • Operator clients giải quyết bằng cách gọi exec.approval.resolve (yêu cầu scope operator.approvals).

Versioning

  • PROTOCOL_VERSION nằm trong src/gateway/protocol/schema.ts.
  • Clients gửi minProtocol + maxProtocol; server sẽ từ chối nếu không khớp.
  • Schemas + models được tạo từ các định nghĩa TypeBox:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

Auth

  • Nếu OPENCLAW_GATEWAY_TOKEN (hoặc --token) được đặt, connect.params.auth.token phải khớp nếu không socket sẽ bị đóng.
  • Sau khi pairing, Gateway cấp một device token được giới hạn theo connection role + scopes. Nó được trả về trong hello-ok.auth.deviceToken và nên được client lưu lại cho các lần kết nối sau.
  • Device tokens có thể được xoay/thu hồi qua device.token.rotatedevice.token.revoke (yêu cầu scope operator.pairing).

Device identity + pairing

  • Nodes nên bao gồm một device identity ổn định (device.id) được tạo từ keypair fingerprint.
  • Gateways cấp tokens cho mỗi device + role.
  • Pairing approvals được yêu cầu cho các device ID mới trừ khi local auto-approval được bật.
  • Các kết nối Local bao gồm loopback và địa chỉ tailnet của chính gateway host (để các bind tailnet cùng host vẫn có thể auto-approve).
  • Tất cả WS clients phải bao gồm device identity trong quá trình connect (operator + node). Control UI có thể bỏ qua chỉ khi gateway.controlUi.allowInsecureAuth được bật (hoặc gateway.controlUi.dangerouslyDisableDeviceAuth cho trường hợp khẩn cấp).
  • Các kết nối non-local phải ký nonce connect.challenge do server cung cấp.

TLS + pinning

  • TLS được hỗ trợ cho các kết nối WS.
  • Clients có thể tùy chọn pin gateway cert fingerprint (xem config gateway.tls cộng với gateway.remote.tlsFingerprint hoặc CLI --tls-fingerprint).

Scope

Protocol này expose toàn bộ gateway API (status, channels, models, chat, agent, sessions, nodes, approvals, v.v.). Bề mặt chính xác được định nghĩa bởi các TypeBox schemas trong src/gateway/protocol/schema.ts.