Протокол Gateway (WebSocket)
Протокол WS Gateway является единой плоскостью управления + транспортом узлов для OpenClaw. Все клиенты (CLI, веб-UI, приложение macOS, узлы iOS/Android, headless узлы) подключаются через WebSocket и объявляют свою роль + область во время handshake.
Транспорт
- WebSocket, текстовые кадры с JSON payload.
- Первый кадр должен быть запросом connect.
Handshake (connect)
Gateway → Client (вызов pre-connect):
{
"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 } }
}
Когда выдается токен устройства, hello-ok также включает:
{
"auth": {
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
Пример узла
{
"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": "…"
}
}
}
Кадрирование
- Запрос: \{type:"req", id, method, params\}
- Ответ: \{type:"res", id, ok, payload|error\}
- Событие: \{type:"event", event, payload, seq?, stateVersion?\}
Методы с побочными эффектами требуют ключей идемпотентности (см. схему).
Роли + области
Роли
- operator = клиент плоскости управления (CLI/UI/автоматизация).
- node = хост возможностей (камера/экран/canvas/system.run).
Области (operator)
Общие области:
- operator.read
- operator.write
- operator.admin
- operator.approvals
- operator.pairing
Caps/commands/permissions (node)
Узлы объявляют заявки на возможности во время connect:
- caps: категории возможностей высокого уровня.
- commands: список разрешений команд для invoke.
- permissions: детальные переключатели (например screen.record, camera.capture).
Gateway обрабатывает их как заявки и применяет серверные списки разрешений.
Присутствие
- system-presence возвращает записи, ключом которых является идентичность устройства.
- Записи присутствия включают deviceId, roles и scopes, чтобы UI могли показывать одну строку на устройство даже когда оно подключается как operator и node.
Вспомогательные методы узла
- Узлы могут вызывать skills.bins для получения текущего списка исполняемых файлов навыков для проверок auto-allow.
Одобрения exec
- Когда запрос exec нуждается в одобрении, gateway транслирует exec.approval.requested.
- Клиенты Operator разрешают, вызывая exec.approval.resolve (требует область operator.approvals).
Версионирование
- PROTOCOL_VERSION находится в src/gateway/protocol/schema.ts.
- Клиенты отправляют minProtocol + maxProtocol; сервер отклоняет несоответствия.
- Схемы + модели генерируются из определений TypeBox:
- pnpm protocol:gen
- pnpm protocol:gen:swift
- pnpm protocol:check
Аутентификация
- Если установлен OPENCLAW_GATEWAY_TOKEN (или --token), connect.params.auth.token должен совпадать или сокет закрывается.
- После сопряжения Gateway выдает токен устройства, ограниченный областью подключения роль + области. Он возвращается в hello-ok.auth.deviceToken и должен быть сохранен клиентом для будущих подключений.
- Токены устройств могут быть ротированы/отозваны через device.token.rotate и device.token.revoke (требует область operator.pairing).
Идентичность устройства + сопряжение
- Узлы должны включать стабильную идентичность устройства (device.id), выведенную из отпечатка ключевой пары.
- Gateways выдают токены для каждого устройства + роли.
- Одобрения сопряжения требуются для новых ID устройств, если локальное автоодобрение не включено.
- Локальные подключения включают loopback и собственный адрес tailnet хоста gateway (чтобы tailnet привязки того же хоста все еще могли автоодобряться).
- Все WS клиенты должны включать идентичность device во время connect (operator + node). Control UI может опустить ее только когда включено gateway.controlUi.allowInsecureAuth (или gateway.controlUi.dangerouslyDisableDeviceAuth для экстренного использования).
- Неlocal соединения должны подписать предоставленный сервером connect.challenge nonce.
TLS + закрепление
- TLS поддерживается для WS соединений.
- Клиенты могут опционально закрепить отпечаток сертификата gateway (см. gateway.tls конфигурацию плюс gateway.remote.tlsFingerprint или CLI --tls-fingerprint).
Область
Этот протокол предоставляет полный API gateway (статус, каналы, модели, чат, агент, сессии, узлы, одобрения и т.д.). Точная поверхность определяется схемами TypeBox в src/gateway/protocol/schema.ts.