Files
openclaw-skill/openclaw-knowhow-skill/output/openclaw-docs_data/pages/Gateway_protocol_WebSocket_d83007feb8.json
Selig 4c966a3ad2 Initial commit: OpenClaw Skill Collection
6 custom skills (assign-task, dispatch-webhook, daily-briefing,
task-capture, qmd-brain, tts-voice) with technical documentation.
Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
2026-03-13 10:58:30 +08:00

106 lines
5.8 KiB
JSON
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"title": "Gateway protocol (WebSocket)",
"content": "The Gateway WS protocol is the **single control plane + node transport** for\nOpenClaw. All clients (CLI, web UI, macOS app, iOS/Android nodes, headless\nnodes) connect over WebSocket and declare their **role** + **scope** at\nhandshake time.\n\n* WebSocket, text frames with JSON payloads.\n* First frame **must** be a `connect` request.\n\n## Handshake (connect)\n\nGateway → Client (pre-connect challenge):\n\nWhen a device token is issued, `hello-ok` also includes:\n\n* **Request**: `{type:\"req\", id, method, params}`\n* **Response**: `{type:\"res\", id, ok, payload|error}`\n* **Event**: `{type:\"event\", event, payload, seq?, stateVersion?}`\n\nSide-effecting methods require **idempotency keys** (see schema).\n\n* `operator` = control plane client (CLI/UI/automation).\n* `node` = capability host (camera/screen/canvas/system.run).\n\n### Scopes (operator)\n\n* `operator.read`\n* `operator.write`\n* `operator.admin`\n* `operator.approvals`\n* `operator.pairing`\n\n### Caps/commands/permissions (node)\n\nNodes declare capability claims at connect time:\n\n* `caps`: high-level capability categories.\n* `commands`: command allowlist for invoke.\n* `permissions`: granular toggles (e.g. `screen.record`, `camera.capture`).\n\nThe Gateway treats these as **claims** and enforces server-side allowlists.\n\n* `system-presence` returns entries keyed by device identity.\n* Presence entries include `deviceId`, `roles`, and `scopes` so UIs can show a single row per device\n even when it connects as both **operator** and **node**.\n\n### Node helper methods\n\n* Nodes may call `skills.bins` to fetch the current list of skill executables\n for auto-allow checks.\n\n* When an exec request needs approval, the gateway broadcasts `exec.approval.requested`.\n* Operator clients resolve by calling `exec.approval.resolve` (requires `operator.approvals` scope).\n\n* `PROTOCOL_VERSION` lives in `src/gateway/protocol/schema.ts`.\n* Clients send `minProtocol` + `maxProtocol`; the server rejects mismatches.\n* Schemas + models are generated from TypeBox definitions:\n * `pnpm protocol:gen`\n * `pnpm protocol:gen:swift`\n * `pnpm protocol:check`\n\n* If `OPENCLAW_GATEWAY_TOKEN` (or `--token`) is set, `connect.params.auth.token`\n must match or the socket is closed.\n* After pairing, the Gateway issues a **device token** scoped to the connection\n role + scopes. It is returned in `hello-ok.auth.deviceToken` and should be\n persisted by the client for future connects.\n* Device tokens can be rotated/revoked via `device.token.rotate` and\n `device.token.revoke` (requires `operator.pairing` scope).\n\n## Device identity + pairing\n\n* Nodes should include a stable device identity (`device.id`) derived from a\n keypair fingerprint.\n* Gateways issue tokens per device + role.\n* Pairing approvals are required for new device IDs unless local auto-approval\n is enabled.\n* **Local** connects include loopback and the gateway hosts own tailnet address\n (so samehost tailnet binds can still autoapprove).\n* All WS clients must include `device` identity during `connect` (operator + node).\n Control UI can omit it **only** when `gateway.controlUi.allowInsecureAuth` is enabled\n (or `gateway.controlUi.dangerouslyDisableDeviceAuth` for break-glass use).\n* Non-local connections must sign the server-provided `connect.challenge` nonce.\n\n* TLS is supported for WS connections.\n* Clients may optionally pin the gateway cert fingerprint (see `gateway.tls`\n config plus `gateway.remote.tlsFingerprint` or CLI `--tls-fingerprint`).\n\nThis protocol exposes the **full gateway API** (status, channels, models, chat,\nagent, sessions, nodes, approvals, etc.). The exact surface is defined by the\nTypeBox schemas in `src/gateway/protocol/schema.ts`.",
"code_samples": [
{
"code": "Client → Gateway:",
"language": "unknown"
},
{
"code": "Gateway → Client:",
"language": "unknown"
},
{
"code": "When a device token is issued, `hello-ok` also includes:",
"language": "unknown"
},
{
"code": "### Node example",
"language": "unknown"
}
],
"headings": [
{
"level": "h2",
"text": "Transport",
"id": "transport"
},
{
"level": "h2",
"text": "Handshake (connect)",
"id": "handshake-(connect)"
},
{
"level": "h3",
"text": "Node example",
"id": "node-example"
},
{
"level": "h2",
"text": "Framing",
"id": "framing"
},
{
"level": "h2",
"text": "Roles + scopes",
"id": "roles-+-scopes"
},
{
"level": "h3",
"text": "Roles",
"id": "roles"
},
{
"level": "h3",
"text": "Scopes (operator)",
"id": "scopes-(operator)"
},
{
"level": "h3",
"text": "Caps/commands/permissions (node)",
"id": "caps/commands/permissions-(node)"
},
{
"level": "h2",
"text": "Presence",
"id": "presence"
},
{
"level": "h3",
"text": "Node helper methods",
"id": "node-helper-methods"
},
{
"level": "h2",
"text": "Exec approvals",
"id": "exec-approvals"
},
{
"level": "h2",
"text": "Versioning",
"id": "versioning"
},
{
"level": "h2",
"text": "Auth",
"id": "auth"
},
{
"level": "h2",
"text": "Device identity + pairing",
"id": "device-identity-+-pairing"
},
{
"level": "h2",
"text": "TLS + pinning",
"id": "tls-+-pinning"
},
{
"level": "h2",
"text": "Scope",
"id": "scope"
}
],
"url": "llms-txt#gateway-protocol-(websocket)",
"links": []
}