Gateway

Протокол Gateway

Gateway WS-протокол є єдиною площиною керування + транспортом вузлів для OpenClaw. Усі клієнти (CLI, веб-інтерфейс, застосунок macOS, вузли iOS/Android, headless вузли) підключаються через WebSocket і оголошують свою роль + область дії під час рукостискання.

Транспорт

  • WebSocket, текстові фрейми з JSON-навантаженням.
  • Перший фрейм має бути запитом connect.
  • Фрейми до підключення обмежені 64 KiB. Після успішного рукостискання клієнти мають дотримуватися лімітів hello-ok.policy.maxPayload і hello-ok.policy.maxBufferedBytes. Коли діагностику ввімкнено, завеликі вхідні фрейми й повільні вихідні буфери генерують події payload.large до того, як gateway закриє або відкине відповідний фрейм. Ці події зберігають розміри, ліміти, поверхні та безпечні коди причин. Вони не зберігають тіло повідомлення, вміст вкладень, сире тіло фрейму, токени, cookies або секретні значення.

Рукостискання (connect)

Gateway → Клієнт (виклик до підключення):

json
{  "type": "event",  "event": "connect.challenge",  "payload": { "nonce": "…", "ts": 1737264000000 }}

Клієнт → Gateway:

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 3,    "maxProtocol": 4,    "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 → Клієнт:

json
{  "type": "res",  "id": "…",  "ok": true,  "payload": {    "type": "hello-ok",    "protocol": 4,    "server": { "version": "…", "connId": "…" },    "features": { "methods": ["…"], "events": ["…"] },    "snapshot": { "…": "…" },    "auth": {      "role": "operator",      "scopes": ["operator.read", "operator.write"]    },    "policy": {      "maxPayload": 26214400,      "maxBufferedBytes": 52428800,      "tickIntervalMs": 15000    }  }}

Поки Gateway ще завершує запуск sidecar-компонентів, запит connect може повернути повторювану помилку UNAVAILABLE з details.reason, встановленим у "startup-sidecars", і retryAfterMs. Клієнти мають повторити цю відповідь у межах свого загального бюджету підключення, а не показувати її як остаточний збій рукостискання.

server, features, snapshot і policy усі є обов’язковими за схемою (packages/gateway-protocol/src/schema/frames.ts). auth також є обов’язковим і повідомляє узгоджені роль/області дії. pluginSurfaceUrls є необов’язковим і зіставляє назви поверхонь plugin, наприклад canvas, зі scoped розміщеними URL.

Scoped URL поверхонь plugin можуть завершуватися. Вузли можуть викликати node.pluginSurface.refresh з { "surface": "canvas" }, щоб отримати свіжий запис у pluginSurfaceUrls. Експериментальний рефакторинг Canvas plugin не підтримує застарілий шлях сумісності canvasHostUrl, canvasCapability або node.canvas.capability.refresh; поточні нативні клієнти й gateway мають використовувати поверхні plugin.

Коли токен пристрою не видано, hello-ok.auth повідомляє узгоджені дозволи без полів токенів:

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

Довірені бекенд-клієнти в тому самому процесі (client.id: "gateway-client", client.mode: "backend") можуть опускати device на прямих loopback-з’єднаннях, коли вони автентифікуються спільним gateway-токеном/паролем. Цей шлях зарезервований для внутрішніх RPC площини керування й не дає застарілим базовим станам поєднання CLI/пристрою блокувати локальну бекенд-роботу, як-от оновлення сесій subagent. Віддалені клієнти, клієнти з браузерним origin, клієнти-вузли й явні клієнти з токеном пристрою/ідентичністю пристрою далі використовують звичайні перевірки поєднання й підвищення областей дії.

Коли токен пристрою видано, hello-ok також містить:

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

Вбудований bootstrap через QR/код налаштування є свіжим шляхом передачі на мобільний пристрій. Успішне підключення базового коду налаштування повертає основний токен вузла плюс один обмежений токен оператора:

json
{  "auth": {    "deviceToken": "…",    "role": "node",    "scopes": [],    "deviceTokens": [      {        "deviceToken": "…",        "role": "operator",        "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]      }    ]  }}

Передача оператору навмисно обмежена, щоб QR-онбординг міг запустити мобільний цикл оператора й завершити нативне налаштування без надання областей дії мутації поєднання або operator.admin. Вона включає operator.talk.secrets, щоб нативний клієнт міг прочитати конфігурацію Talk, потрібну після bootstrap. Ширший доступ до поєднання й адміністрування потребує окремого затвердженого поєднання оператора або потоку токена. Клієнти мають зберігати hello-ok.auth.deviceTokens лише коли connect використовував bootstrap-автентифікацію на довіреному транспорті, такому як wss:// або loopback/local pairing.

Приклад вузла

json
{  "type": "req",  "id": "…",  "method": "connect",  "params": {    "minProtocol": 3,    "maxProtocol": 4,    "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 = хост можливостей (camera/screen/canvas/system.run).

Області дії (оператор)

Поширені області дії:

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

talk.config з includeSecrets: true потребує operator.talk.secrets (або operator.admin). Коли секрети включено, клієнти мають читати активні облікові дані провайдера Talk з talk.resolved.config.apiKey; talk.providers.<id>.apiKey залишається у формі джерела й може бути об’єктом SecretRef або заредагованим рядком.

Зареєстровані plugin методи gateway RPC можуть запитувати власну область дії оператора, але зарезервовані основні префікси адміністрування (config.*, exec.approvals.*, wizard.*, update.*) завжди резолвляться в operator.admin.

Область дії методу є лише першим шлюзом. Деякі slash-команди, доступні через chat.send, застосовують суворіші перевірки на рівні команди додатково. Наприклад, сталі записи /config set і /config unset потребують operator.admin.

node.pair.approve також має додаткову перевірку області дії під час затвердження поверх базової області дії методу:

  • запити без команд: operator.pairing
  • запити з non-exec командами вузла: operator.pairing + operator.write
  • запити, що містять system.run, system.run.prepare або system.which: operator.pairing + operator.admin

Можливості/команди/дозволи (вузол)

Вузли оголошують claims можливостей під час підключення:

  • caps: високорівневі категорії можливостей, як-от camera, canvas, screen, location, voice і talk.
  • commands: allowlist команд для invoke.
  • permissions: деталізовані перемикачі (наприклад, screen.record, camera.capture).

Gateway розглядає їх як claims і застосовує серверні allowlist.

Присутність

  • system-presence повертає записи з ключами за ідентичністю пристрою.
  • Записи присутності містять deviceId, roles і scopes, щоб UI могли показувати один рядок на пристрій навіть коли він підключається і як operator, і як node.
  • node.list містить необов’язкові поля lastSeenAtMs і lastSeenReason. Підключені вузли повідомляють час свого поточного з’єднання як lastSeenAtMs з причиною connect; поєднані вузли також можуть повідомляти сталу фонову присутність, коли довірена подія вузла оновлює їхні метадані поєднання.

Фонова подія активності вузла

Вузли можуть викликати node.event з event: "node.presence.alive", щоб записати, що поєднаний вузол був активним під час фонового пробудження, не позначаючи його підключеним.

json
{  "event": "node.presence.alive",  "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"}

trigger є закритим enum: background, silent_push, bg_app_refresh, significant_location, manual або connect. Невідомі рядки trigger нормалізуються до background gateway перед збереженням. Подія є сталою лише для автентифікованих сесій пристроїв вузла; сесії без пристрою або без поєднання повертають handled: false.

Успішні gateway повертають структурований результат:

json
{  "ok": true,  "event": "node.presence.alive",  "handled": true,  "reason": "persisted"}

Старіші gateway можуть усе ще повертати { "ok": true } для node.event; клієнти мають трактувати це як підтверджений RPC, а не як стале збереження присутності.

Обмеження областями дії для broadcast-подій

Надіслані сервером broadcast-події WebSocket обмежуються областями дії, щоб сесії з областю поєднання або лише вузлові сесії не отримували пасивно вміст сесії.

  • Фрейми чату, агента й результатів інструментів (зокрема потокові події agent і результати викликів інструментів) потребують щонайменше operator.read. Сесії без operator.read повністю пропускають ці фрейми.
  • Визначені plugin broadcast-події plugin.* обмежуються operator.write або operator.admin, залежно від того, як plugin їх зареєстрував.
  • Події статусу й транспорту (heartbeat, presence, tick, життєвий цикл connect/disconnect тощо) залишаються необмеженими, щоб стан транспорту був видимий кожній автентифікованій сесії.
  • Невідомі сімейства broadcast-подій за замовчуванням обмежуються областями дії (fail-closed), якщо зареєстрований обробник явно їх не послаблює.

Кожне клієнтське з’єднання зберігає власний per-client порядковий номер, тому broadcast-події зберігають монотонне впорядкування на цьому сокеті, навіть коли різні клієнти бачать різні відфільтровані за областю дії підмножини потоку подій.

Поширені сімейства методів RPC

Публічна поверхня WS ширша за наведені вище приклади рукостискання/автентифікації. Це не згенерований dump — hello-ok.features.methods є консервативним списком discovery, побудованим із src/gateway/server-methods-list.ts плюс завантажених експортів методів plugin/channel. Розглядайте його як discovery функцій, а не повний перелік src/gateway/server-methods/*.ts.

Система та ідентичність
  • health повертає кешований або щойно перевірений знімок стану Gateway.
  • diagnostics.stability повертає нещодавній обмежений реєстратор діагностичної стабільності. Він зберігає операційні метадані, як-от назви подій, лічильники, розміри в байтах, показники пам’яті, стан черги/сеансу, назви каналів/Plugin і ідентифікатори сеансів. Він не зберігає текст чату, тіла webhook, результати інструментів, необроблені тіла запитів або відповідей, токени, cookies чи секретні значення. Потрібна область читання оператора.
  • status повертає зведення Gateway у стилі /status; чутливі поля включаються лише для клієнтів оператора з областю адміністратора.
  • gateway.identity.get повертає ідентичність пристрою Gateway, яку використовують потоки ретрансляції та сполучення.
  • system-presence повертає поточний знімок присутності для підключених пристроїв оператора/Node.
  • system-event додає системну подію та може оновлювати/транслювати контекст присутності.
  • last-heartbeat повертає останню збережену подію Heartbeat.
  • set-heartbeats вмикає або вимикає обробку Heartbeat на Gateway.
Моделі та використання
  • models.list повертає каталог моделей, дозволених під час виконання. Передайте { "view": "configured" } для налаштованих моделей розміру пікера (спершу agents.defaults.models, потім models.providers.*.models) або { "view": "all" } для повного каталогу.
  • usage.status повертає вікна використання провайдера / зведення залишкових квот.
  • usage.cost повертає агреговані зведення витрат за діапазон дат. Передайте agentId для одного агента або agentScope: "all", щоб агрегувати налаштованих агентів.
  • doctor.memory.status повертає готовність векторної пам’яті / кешованих embedding для активного робочого простору агента за замовчуванням. Передавайте { "probe": true } або { "deep": true } лише коли викликач явно хоче виконати live ping провайдера embedding. Клієнти, обізнані з Dreaming, також можуть передати { "agentId": "agent-id" }, щоб обмежити статистику сховища Dreaming вибраним робочим простором агента; якщо agentId пропущено, зберігається fallback агента за замовчуванням і агрегуються налаштовані робочі простори Dreaming.
  • doctor.memory.dreamDiary, doctor.memory.backfillDreamDiary, doctor.memory.resetDreamDiary, doctor.memory.resetGroundedShortTerm, doctor.memory.repairDreamingArtifacts і doctor.memory.dedupeDreamDiary приймають необов’язкові параметри { "agentId": "agent-id" } для переглядів/дій Dreaming вибраного агента. Коли agentId пропущено, вони працюють із налаштованим робочим простором агента за замовчуванням.
  • doctor.memory.remHarness повертає обмежений попередній перегляд harness REM лише для читання для віддалених клієнтів control plane. Він може містити шляхи робочого простору, фрагменти пам’яті, відрендерений grounded Markdown і кандидатів для deep promotion, тому викликачам потрібен operator.read.
  • sessions.usage повертає зведення використання за сеансами. Передайте agentId для одного агента або agentScope: "all", щоб перелічити налаштованих агентів разом.
  • sessions.usage.timeseries повертає використання часових рядів для одного сеансу.
  • sessions.usage.logs повертає записи журналу використання для одного сеансу.
Канали та помічники входу
  • channels.status повертає вбудовані + bundled зведення стану каналів/Plugin.
  • channels.logout виконує вихід із певного каналу/облікового запису, якщо канал підтримує вихід.
  • web.login.start запускає потік входу через QR/веб для поточного провайдера вебканалу з підтримкою QR.
  • web.login.wait очікує завершення цього потоку входу через QR/веб і в разі успіху запускає канал.
  • push.test надсилає тестовий push APNs на зареєстрований iOS Node.
  • voicewake.get повертає збережені тригери wake-word.
  • voicewake.set оновлює тригери wake-word і транслює зміну.
Повідомлення та журнали
  • send — це прямий RPC вихідної доставки для надсилань, націлених на канал/обліковий запис/thread, поза chat runner.
  • logs.tail повертає налаштований хвіст файлового журналу Gateway з керуванням cursor/limit і max-byte.
Talk і TTS
  • talk.catalog повертає каталог провайдерів Talk лише для читання для мовлення, потокової транскрипції та голосу в реальному часі. Він містить канонічні ідентифікатори провайдерів, псевдоніми реєстру, мітки, налаштований стан, необов’язковий результат ready на рівні групи, відкриті ідентифікатори моделей/голосів, канонічні режими, транспорти, стратегії brain і прапорці аудіо/можливостей реального часу, не повертаючи секрети провайдера й не змінюючи глобальну конфігурацію. Поточні Gateway встановлюють ready після застосування вибору провайдера під час виконання; клієнти мають трактувати його відсутність як неперевірений стан для сумісності зі старішими Gateway.
  • talk.config повертає ефективне корисне навантаження конфігурації Talk; includeSecrets потребує operator.talk.secrets (або operator.admin).
  • talk.session.create створює сеанс Talk, яким володіє Gateway, для realtime/gateway-relay, transcription/gateway-relay або stt-tts/managed-room. Для stt-tts/managed-room викликачі operator.write, які передають sessionKey, також мають передати spawnedBy для обмеженої видимості ключа сеансу; створення sessionKey без області та brain: "direct-tools" потребують operator.admin.
  • talk.session.join перевіряє токен сеансу managed-room, за потреби надсилає події session.ready або session.replaced і повертає метадані кімнати/сеансу плюс нещодавні події Talk без plaintext токена або збереженого hash токена.
  • talk.session.appendAudio додає вхідний аудіо PCM у base64 до сеансів ретрансляції в реальному часі та транскрипції, якими володіє Gateway.
  • talk.session.startTurn, talk.session.endTurn і talk.session.cancelTurn керують життєвим циклом turn managed-room із відхиленням застарілого turn до очищення стану.
  • talk.session.cancelOutput зупиняє аудіовихід асистента, насамперед для barge-in, обмеженого VAD, у сеансах ретрансляції Gateway.
  • talk.session.submitToolResult завершує виклик інструмента провайдера, створений сеансом ретрансляції в реальному часі, яким володіє Gateway. Передайте options: { willContinue: true } для проміжного результату інструмента, коли фінальний результат буде надано пізніше, або options: { suppressResponse: true }, коли результат інструмента має задовольнити виклик провайдера без запуску ще однієї відповіді асистента в реальному часі.
  • talk.session.steer надсилає голосове керування активним запуском у сеанс Talk із агентною підтримкою, яким володіє Gateway. Він приймає { sessionId, text, mode? }, де mode — це status, steer, cancel або followup; пропущений режим класифікується за промовленим текстом.
  • talk.session.close закриває сеанс ретрансляції, транскрипції або managed-room, яким володіє Gateway, і надсилає термінальні події Talk.
  • talk.mode встановлює/транслює поточний стан режиму Talk для клієнтів WebChat/Control UI.
  • talk.client.create створює сеанс провайдера в реальному часі, яким володіє клієнт, використовуючи webrtc або provider-websocket, тоді як Gateway володіє конфігурацією, обліковими даними, інструкціями та політикою інструментів.
  • talk.client.toolCall дає змогу транспортам реального часу, якими володіє клієнт, пересилати виклики інструментів провайдера до політики Gateway. Перший підтримуваний інструмент — openclaw_agent_consult; клієнти отримують ідентифікатор запуску та очікують звичайних подій життєвого циклу чату перед надсиланням результату інструмента, специфічного для провайдера.
  • talk.client.steer надсилає голосове керування активним запуском для транспортів реального часу, якими володіє клієнт. Gateway визначає активний вбудований запуск із sessionKey і повертає структурований результат прийняття/відхилення замість мовчазного відкидання steering.
  • talk.event — це єдиний канал подій Talk для адаптерів реального часу, транскрипції, STT/TTS, managed-room, телефонії та зустрічей.
  • talk.speak синтезує мовлення через активного провайдера мовлення Talk.
  • tts.status повертає стан увімкнення TTS, активного провайдера, fallback-провайдерів і стан конфігурації провайдера.
  • tts.providers повертає видимий інвентар провайдерів TTS.
  • tts.enable і tts.disable перемикають стан налаштувань TTS.
  • tts.setProvider оновлює бажаного провайдера TTS.
  • tts.convert виконує одноразове перетворення тексту на мовлення.
Секрети, конфігурація, оновлення та майстер
  • secrets.reload повторно розв’язує активні SecretRefs і замінює стан секретів під час виконання лише за повного успіху.
  • secrets.resolve розв’язує призначення секретів, націлених на команду, для певного набору команд/цілей.
  • config.get повертає поточний знімок конфігурації та hash.
  • config.set записує перевірене корисне навантаження конфігурації.
  • config.patch об’єднує часткове оновлення конфігурації. Деструктивна заміна масиву потребує відповідного шляху в replacePaths; вкладені масиви під елементами масиву використовують шляхи [], як-от agents.list[].skills.
  • config.apply перевіряє + замінює повне корисне навантаження конфігурації.
  • config.schema повертає live корисне навантаження схеми конфігурації, яке використовують інструменти Control UI і CLI: схема, uiHints, версія та метадані генерації, включно з метаданими схеми Plugin + каналу, коли runtime може їх завантажити. Схема містить метадані полів title / description, отримані з тих самих міток і довідкового тексту, які використовує UI, включно з гілками вкладених об’єктів, wildcard, елементів масиву та композиції anyOf / oneOf / allOf, коли існує відповідна документація полів.
  • config.schema.lookup повертає корисне навантаження пошуку з областю шляху для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідна підказка + hintPath, необов’язковий reloadKind і безпосередні зведення дочірніх елементів для деталізації в UI/CLI. reloadKind є одним із restart, hot або none і віддзеркалює планувальник перезавантаження конфігурації Gateway для запитаного шляху. Вузли схеми пошуку зберігають користувацьку документацію та поширені поля перевірки (title, description, type, enum, const, format, pattern, числові/рядкові/масивні/об’єктні межі та прапорці на кшталт additionalProperties, deprecated, readOnly, writeOnly). Зведення дочірніх елементів відкривають key, нормалізований path, type, required, hasChildren, необов’язковий reloadKind, а також відповідні hint / hintPath.
  • update.run запускає потік оновлення Gateway і планує перезапуск лише коли саме оновлення завершилося успішно; викликачі із сеансом можуть включити continuationMessage, щоб запуск продовжив один наступний turn агента через чергу продовження після перезапуску. Оновлення через менеджер пакетів і керовані supervised оновлення git-checkout із control plane використовують відокремлену передачу керованій службі замість заміни дерева пакетів або зміни checkout/build output усередині live Gateway. Запущена передача повертає ok: true з result.reason: "managed-service-handoff-started" і handoff.status: "started"; недоступні або невдалі передачі повертають ok: false з managed-service-handoff-unavailable або managed-service-handoff-failed, а також handoff.command, коли потрібне ручне оновлення в shell. Недоступна передача означає, що OpenClaw не має безпечної межі supervisor або тривкої ідентичності служби, як-от OPENCLAW_SYSTEMD_UNIT для systemd. Під час запущеної передачі sentinel перезапуску може короткочасно повідомляти stats.reason: "restart-health-pending"; продовження затримується, доки CLI не перевірить перезапущений Gateway і не запише фінальний sentinel ok.
  • update.status оновлює та повертає останній sentinel перезапуску оновлення, включно з версією, що працює після перезапуску, якщо вона доступна.
  • wizard.start, wizard.next, wizard.status і wizard.cancel відкривають onboarding-майстер через WS RPC.
Помічники агентів і робочих просторів
  • agents.list повертає налаштовані записи агентів, включно з чинною моделлю та метаданими runtime.
  • agents.create, agents.update і agents.delete керують записами агентів і прив’язкою робочого простору.
  • agents.files.list, agents.files.get і agents.files.set керують початковими файлами робочого простору, відкритими для агента.
  • tasks.list, tasks.get і tasks.cancel відкривають реєстр завдань Gateway для SDK та операторських клієнтів.
  • artifacts.list, artifacts.get і artifacts.download відкривають зведення артефактів, отриманих із транскриптів, і завантаження для явної області sessionKey, runId або taskId. Запити запусків і завдань визначають власницьку сесію на сервері та повертають лише медіа транскриптів із відповідним походженням; небезпечні або локальні джерела URL повертають непідтримувані завантаження замість отримання на сервері.
  • environments.list і environments.status відкривають для клієнтів SDK виявлення локального для Gateway і вузлового середовища лише для читання.
  • agent.identity.get повертає чинну ідентичність помічника для агента або сесії.
  • agent.wait очікує завершення запуску та повертає термінальний знімок, коли він доступний.
Керування сесіями
  • sessions.list повертає поточний індекс сесій, включно з метаданими agentRuntime для кожного рядка, коли налаштовано backend runtime агента.
  • sessions.subscribe і sessions.unsubscribe перемикають підписки на події зміни сесій для поточного клієнта WS.
  • sessions.messages.subscribe і sessions.messages.unsubscribe перемикають підписки на події транскриптів/повідомлень для однієї сесії.
  • sessions.preview повертає обмежені попередні перегляди транскриптів для конкретних ключів сесій.
  • sessions.describe повертає один рядок сесії Gateway для точного ключа сесії.
  • sessions.resolve визначає або канонізує ціль сесії.
  • sessions.create створює новий запис сесії.
  • sessions.send надсилає повідомлення в наявну сесію.
  • sessions.steer є варіантом переривання й скеровування для активної сесії.
  • sessions.abort перериває активну роботу для сесії. Викликач може передати key плюс необов’язковий runId або передати лише runId для активних запусків, які Gateway може зіставити із сесією.
  • sessions.patch оновлює метадані/перевизначення сесії та повідомляє визначену канонічну модель плюс чинний agentRuntime.
  • sessions.reset, sessions.delete і sessions.compact виконують обслуговування сесій.
  • sessions.get повертає повний збережений рядок сесії.
  • Виконання чату й надалі використовує chat.history, chat.send, chat.abort і chat.inject. chat.history нормалізовано для відображення в клієнтах UI: вбудовані теги директив вилучаються з видимого тексту, текстові XML-навантаження викликів інструментів (зокрема <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> і обрізані блоки викликів інструментів) та витеклі ASCII/повноширинні токени керування моделлю вилучаються, суто беззвучні рядки помічника з токенами, як-от точні NO_REPLY / no_reply, пропускаються, а надмірно великі рядки можуть замінюватися заповнювачами.
  • chat.message.get є додатковим обмеженим читачем повного повідомлення для одного видимого запису транскрипту. Клієнти передають sessionKey, необов’язковий agentId, коли вибір сесії має область агента, плюс messageId транскрипту, раніше показаний через chat.history, а Gateway повертає ту саму нормалізовану для відображення проєкцію без полегшеного ліміту обрізання історії, якщо збережений запис досі доступний і не є надмірно великим.
  • chat.send приймає одноходовий fastMode: "auto", щоб використовувати швидкий режим для викликів моделі, запущених до автоматичного порогу, а потім запускати пізніші повторні спроби, fallback, результати інструментів або виклики продовження без швидкого режиму. Поріг за замовчуванням становить 60 секунд і може налаштовуватися для кожної моделі через agents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. Викликач chat.send може передати одноходовий fastAutoOnSeconds, щоб перевизначити поріг для цього запиту.
Сполучення пристроїв і токени пристроїв
  • device.pair.list повертає очікувані та схвалені спряжені пристрої.
  • device.pair.setupCode створює мобільний код налаштування та, за замовчуванням, URL даних PNG QR. Він вимагає operator.admin і навмисно пропущений у рекламованому виявленні. Результат містить setupCode, необов’язковий qrDataUrl, gatewayUrl, несекретну мітку auth і urlSource.
  • device.pair.approve, device.pair.reject і device.pair.remove керують записами сполучення пристроїв.
  • device.token.rotate ротує токен спряженого пристрою в межах його схваленої ролі та області викликача.
  • device.token.revoke відкликає токен спряженого пристрою в межах його схваленої ролі та області викликача.

Код налаштування вбудовує короткочасний початковий обліковий засіб. Клієнти не повинні записувати його в журнал або зберігати поза потоком сполучення.

Сполучення Node, виклики й очікувана робота
  • node.pair.request, node.pair.list, node.pair.approve, node.pair.reject, node.pair.remove і node.pair.verify охоплюють сполучення вузлів і перевірку bootstrap.
  • node.list і node.describe повертають відомий/підключений стан вузла.
  • node.rename оновлює мітку спряженого вузла.
  • node.invoke пересилає команду до підключеного вузла.
  • node.invoke.result повертає результат для запиту виклику.
  • node.event передає події, що походять від вузла, назад у gateway.
  • node.pending.pull і node.pending.ack є API черги підключеного вузла.
  • node.pending.enqueue і node.pending.drain керують надійною очікуваною роботою для offline/відключених вузлів.
Сімейства схвалень
  • exec.approval.request, exec.approval.get, exec.approval.list і exec.approval.resolve охоплюють одноразові запити схвалення exec плюс пошук/відтворення очікуваних схвалень.
  • exec.approval.waitDecision очікує одне очікуване схвалення exec і повертає остаточне рішення (або null у разі timeout).
  • exec.approvals.get і exec.approvals.set керують знімками політики схвалення exec у gateway.
  • exec.approvals.node.get і exec.approvals.node.set керують локальною для вузла політикою схвалення exec через команди ретрансляції вузла.
  • plugin.approval.request, plugin.approval.list, plugin.approval.waitDecision і plugin.approval.resolve охоплюють потоки схвалення, визначені plugin.
Автоматизація, Skills та інструменти
  • Автоматизація: wake планує негайне або під час наступного heartbeat впровадження тексту пробудження; cron.get, cron.list, cron.status, cron.add, cron.update, cron.remove, cron.run, cron.runs керують запланованою роботою.
  • cron.run залишається RPC у стилі додавання до черги для ручних запусків. Клієнти, яким потрібна семантика завершення, мають прочитати повернений runId і опитувати cron.runs.
  • cron.runs приймає необов’язковий непорожній фільтр runId, щоб клієнти могли відстежувати один поставлений у чергу ручний запуск без перегонів з іншими записами історії для того самого завдання.
  • Skills та інструменти: commands.list, skills.*, tools.catalog, tools.effective, tools.invoke.

Поширені сімейства подій

  • chat: оновлення чату UI, як-от chat.inject, та інші події чату лише з транскриптами. У протоколі v4 delta-навантаження несуть deltaText; message залишається накопиченим знімком помічника. Заміни не за префіксом установлюють replace=true і використовують deltaText як текст заміни.
  • session.message, session.operation і session.tool: транскрипт, операція сесії в процесі виконання та оновлення потоку подій для підписаної сесії.
  • sessions.changed: індекс сесій або метадані змінено.
  • presence: оновлення знімка присутності системи.
  • tick: періодична подія keepalive / liveness.
  • health: оновлення знімка стану gateway.
  • heartbeat: оновлення потоку подій heartbeat.
  • cron: подія зміни запуску/завдання cron.
  • shutdown: сповіщення про вимкнення gateway.
  • node.pair.requested / node.pair.resolved: життєвий цикл сполучення вузла.
  • node.invoke.request: широкомовний запит виклику вузла.
  • device.pair.requested / device.pair.resolved: життєвий цикл спряженого пристрою.
  • voicewake.changed: конфігурацію тригера wake-word змінено.
  • exec.approval.requested / exec.approval.resolved: життєвий цикл схвалення exec.
  • plugin.approval.requested / plugin.approval.resolved: життєвий цикл схвалення plugin.

Допоміжні методи вузлів

  • Вузли можуть викликати skills.bins, щоб отримати поточний список виконуваних файлів навичок для перевірок auto-allow.

RPC реєстру завдань

Операторські клієнти можуть переглядати й скасовувати записи фонових завдань Gateway через RPC реєстру завдань. Ці методи повертають очищені зведення завдань, а не необроблений стан runtime.

  • tasks.list вимагає operator.read.
    • Параметри: необов’язковий status ("queued", "running", "completed", "failed", "cancelled" або "timed_out") або масив цих статусів, необов’язковий agentId, необов’язковий sessionKey, необов’язковий limit від 1 до 500 і необов’язковий рядок cursor.
    • Результат: { "tasks": TaskSummary[], "nextCursor"?: string }.
  • tasks.get вимагає operator.read.
    • Параметри: { "taskId": string }.
    • Результат: { "task": TaskSummary }.
    • Відсутні ідентифікатори завдань повертають форму помилки not-found Gateway.
  • tasks.cancel вимагає operator.write.
    • Параметри: { "taskId": string, "reason"?: string }.
    • Результат: { "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }.
    • found повідомляє, чи мав реєстр відповідне завдання. cancelled повідомляє, чи runtime прийняв або записав скасування.

TaskSummary містить id, status і необов’язкові метадані, як-от kind, runtime, title, agentId, sessionKey, childSessionKey, ownerKey, runId, taskId, flowId, parentTaskId, sourceId, часові позначки, прогрес, термінальне зведення й очищений текст помилки. agentId ідентифікує агента, який виконує завдання; sessionKey і ownerKey зберігають контекст запитувача та керування.

Допоміжні методи оператора

  • Оператори можуть викликати commands.list (operator.read), щоб отримати інвентар команд середовища виконання для агента.
    • agentId необов’язковий; не вказуйте його, щоб читати робочий простір агента за замовчуванням.
    • scope керує тим, на яку поверхню націлюється основне name:
      • text повертає основний текстовий токен команди без початкового /
      • native і стандартний шлях both повертають нативні імена з урахуванням провайдера, коли вони доступні
    • textAliases містить точні slash-аліаси, як-от /model і /m.
    • nativeName містить нативну назву команди з урахуванням провайдера, коли вона існує.
    • provider необов’язковий і впливає лише на нативне іменування та доступність нативних команд Plugin.
    • includeArgs=false вилучає серіалізовані метадані аргументів із відповіді.
  • Оператори можуть викликати tools.catalog (operator.read), щоб отримати каталог інструментів середовища виконання для агента. Відповідь містить згруповані інструменти та метадані походження:
    • source: core або plugin
    • pluginId: власник Plugin, коли source="plugin"
    • optional: чи є інструмент Plugin необов’язковим
  • Оператори можуть викликати tools.effective (operator.read), щоб отримати фактичний інвентар інструментів середовища виконання для сеансу.
    • sessionKey обов’язковий.
    • Gateway виводить довірений контекст середовища виконання з сеансу на боці сервера замість приймати auth або контекст доставки, наданий викликачем.
    • Відповідь є серверною проєкцією активного інвентарю в межах сеансу, зокрема core, Plugin, channel і вже виявлені інструменти MCP-сервера.
    • tools.effective доступний лише для читання для MCP: він може пропустити прогрітий каталог MCP сеансу через фінальну політику інструментів, але не створює середовища виконання MCP, не підключає транспорти й не викликає tools/list. Якщо відповідного прогрітого каталогу немає, відповідь може містити повідомлення на кшталт mcp-not-yet-connected, mcp-not-yet-listed або mcp-stale-catalog.
    • Елементи фактичних інструментів використовують source="core", source="plugin", source="channel" або source="mcp".
  • Оператори можуть викликати tools.invoke (operator.write), щоб викликати один доступний інструмент через той самий шлях політики Gateway, що й /tools/invoke.
    • name обов’язковий. args, sessionKey, agentId, confirm і idempotencyKey необов’язкові.
    • Якщо наявні і sessionKey, і agentId, розв’язаний агент сеансу має збігатися з agentId.
    • Core-обгортки лише для власників, як-от cron, gateway і nodes, потребують ідентичності власника/адміністратора (operator.admin), хоча сам метод tools.invoke є operator.write.
    • Відповідь є конвертом для SDK із полями ok, toolName, необов’язковим output і типізованими полями error. Відмови через схвалення або політику повертають ok:false у payload замість обходу конвеєра політики інструментів Gateway.
  • Оператори можуть викликати skills.status (operator.read), щоб отримати видимий інвентар навичок для агента.
    • agentId необов’язковий; не вказуйте його, щоб читати робочий простір агента за замовчуванням.
    • Відповідь містить придатність, відсутні вимоги, перевірки конфігурації та санітизовані параметри встановлення без розкриття необроблених секретних значень.
  • Оператори можуть викликати skills.search і skills.detail (operator.read) для метаданих пошуку ClawHub.
  • Оператори можуть викликати skills.upload.begin, skills.upload.chunk і skills.upload.commit (operator.admin), щоб підготувати приватний архів навички перед установленням. Це окремий шлях адміністративного завантаження для довірених клієнтів, а не звичайний потік установлення навичок ClawHub, і він вимкнений за замовчуванням, якщо не ввімкнено skills.install.allowUploadedArchives.
    • skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? }) створює завантаження, прив’язане до цього slug і значення force.
    • skills.upload.chunk({ uploadId, offset, dataBase64 }) додає байти за точним декодованим offset.
    • skills.upload.commit({ uploadId, sha256? }) перевіряє фінальний розмір і SHA-256. Commit лише завершує завантаження; він не встановлює навичку.
    • Завантажені архіви навичок є zip-архівами, що містять кореневий SKILL.md. Внутрішня назва каталогу архіву ніколи не вибирає ціль установлення.
  • Оператори можуть викликати skills.install (operator.admin) у трьох режимах:
    • Режим ClawHub: { source: "clawhub", slug, version?, force? } встановлює папку навички в каталог skills/ робочого простору агента за замовчуванням.
    • Режим завантаження: { source: "upload", uploadId, slug, force?, sha256?, timeoutMs? } встановлює підтверджене завантаження в каталог skills/<slug> робочого простору агента за замовчуванням. Значення slug і force мають збігатися з початковим запитом skills.upload.begin. Цей режим відхиляється, якщо не ввімкнено skills.install.allowUploadedArchives. Налаштування не впливає на встановлення ClawHub.
    • Режим інсталятора Gateway: { name, installId, timeoutMs? } запускає оголошену дію metadata.openclaw.install на хості Gateway. Старіші клієнти все ще можуть надсилати dangerouslyForceUnsafeInstall; це поле застаріле, приймається лише для сумісності протоколу й ігнорується. Використовуйте security.installPolicy для рішень щодо встановлення, якими володіє оператор.
  • Оператори можуть викликати skills.update (operator.admin) у двох режимах:
    • Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у робочому просторі агента за замовчуванням.
    • Режим конфігурації патчить значення skills.entries.<skillKey>, як-от enabled, apiKey і env.

Подання models.list

models.list приймає необов’язковий параметр view:

  • Не вказано або "default": поточна поведінка середовища виконання. Якщо налаштовано agents.defaults.models, відповіддю є дозволений каталог, зокрема динамічно виявлені моделі для записів provider/*. Інакше відповіддю є повний каталог Gateway.
  • "configured": поведінка розміру picker. Якщо налаштовано agents.defaults.models, він усе одно має пріоритет, зокрема виявлення в межах провайдера для записів provider/*. Без allowlist відповідь використовує явні записи models.providers.*.models, повертаючись до повного каталогу лише тоді, коли немає налаштованих рядків моделей.
  • "all": повний каталог Gateway з обходом agents.defaults.models. Використовуйте це для діагностики та UI виявлення, а не для звичайних picker моделей.

Схвалення exec

  • Коли запит exec потребує схвалення, Gateway транслює exec.approval.requested.
  • Клієнти операторів розв’язують це викликом exec.approval.resolve (потребує scope operator.approvals).
  • Для host=node exec.approval.request має містити systemRunPlan (канонічні argv/cwd/rawCommand/метадані сеансу). Запити без systemRunPlan відхиляються.
  • Після схвалення переспрямовані виклики node.invoke system.run повторно використовують цей канонічний systemRunPlan як авторитетний контекст command/cwd/session.
  • Якщо викликач змінює command, rawCommand, cwd, agentId або sessionKey між підготовкою та фінальним схваленим переспрямуванням system.run, Gateway відхиляє запуск замість довіряти зміненому payload.

Резервний варіант доставки агентом

  • Запити agent можуть містити deliver=true, щоб запитати вихідну доставку.
  • bestEffortDeliver=false зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставки повертають INVALID_REQUEST.
  • bestEffortDeliver=true дозволяє резервний перехід до виконання лише в межах сеансу, коли неможливо розв’язати зовнішній маршрут доставки (наприклад, внутрішні/webchat-сеанси або неоднозначні багатоканальні конфігурації).
  • Фінальні результати agent можуть містити result.deliveryStatus, коли було запитано доставку, використовуючи ті самі статуси sent, suppressed, partial_failed і failed, які задокументовані для openclaw agent --json --deliver.

Версіонування

  • PROTOCOL_VERSION міститься в packages/gateway-protocol/src/version.ts.
  • Клієнти надсилають minProtocol + maxProtocol; сервер відхиляє діапазони, які не містять його поточний протокол. Поточні клієнти й сервери потребують протокол v4.
  • Схеми + моделі генеруються з визначень TypeBox:
    • pnpm protocol:gen
    • pnpm protocol:gen:swift
    • pnpm protocol:check

Константи клієнта

Еталонний клієнт у src/gateway/client.ts використовує ці значення за замовчуванням. Значення стабільні в межах protocol v4 і є очікуваною базою для сторонніх клієнтів.

Константа Значення за замовчуванням Джерело
PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
MIN_CLIENT_PROTOCOL_VERSION 4 packages/gateway-protocol/src/version.ts
Таймаут запиту (на RPC) 30_000 ms src/gateway/client.ts (requestTimeoutMs)
Таймаут preauth / connect-challenge 15_000 ms src/gateway/handshake-timeouts.ts (config/env може збільшити спарений бюджет server/client)
Початковий backoff перепідключення 1_000 ms src/gateway/client.ts (backoffMs)
Максимальний backoff перепідключення 30_000 ms src/gateway/client.ts (scheduleReconnect)
Fast-retry clamp після закриття device-token 250 ms src/gateway/client.ts
Пільговий час force-stop перед terminate() 250 ms FORCE_STOP_TERMINATE_GRACE_MS
Таймаут за замовчуванням stopAndWait() 1_000 ms STOP_AND_WAIT_TIMEOUT_MS
Інтервал tick за замовчуванням (до hello-ok) 30_000 ms src/gateway/client.ts
Закриття через таймаут tick code 4000, коли тиша перевищує tickIntervalMs * 2 src/gateway/client.ts
MAX_PAYLOAD_BYTES 25 * 1024 * 1024 (25 MB) src/gateway/server-constants.ts

Сервер оголошує фактичні policy.tickIntervalMs, policy.maxPayload і policy.maxBufferedBytes у hello-ok; клієнти мають дотримуватися цих значень, а не стандартних значень до handshake.

Auth

  • Автентифікація Gateway за спільним секретом використовує connect.params.auth.token або connect.params.auth.password, залежно від налаштованого режиму автентифікації.
  • Режими з ідентичністю, як-от Tailscale Serve (gateway.auth.allowTailscale: true) або не-loopback gateway.auth.mode: "trusted-proxy", задовольняють перевірку автентифікації підключення через заголовки запиту замість connect.params.auth.*.
  • Private-ingress gateway.auth.mode: "none" повністю пропускає автентифікацію підключення за спільним секретом; не відкривайте цей режим на публічному/ненадійному ingress.
  • Після спарювання Gateway видає токен пристрою, обмежений роллю підключення
    • scopes. Він повертається в hello-ok.auth.deviceToken, і клієнт має зберігати його для майбутніх підключень.
  • Клієнти мають зберігати основний hello-ok.auth.deviceToken після будь-якого успішного підключення.
  • Повторне підключення з цим збереженим токеном пристрою також має повторно використовувати збережений затверджений набір scopes для цього токена. Це зберігає доступ для читання/проби/статусу, який уже було надано, і не дає повторним підключенням непомітно звузитися до неявного scope лише для адміністратора.
  • Складання автентифікації підключення на боці клієнта (selectConnectAuth у src/gateway/client.ts):
    • auth.password є ортогональним і завжди передається, коли заданий.
    • auth.token заповнюється в порядку пріоритету: спочатку явний спільний токен, потім явний deviceToken, потім збережений токен для пристрою (ключований за deviceId + role).
    • auth.bootstrapToken надсилається лише тоді, коли жоден із наведених вище варіантів не визначив auth.token. Спільний токен або будь-який визначений токен пристрою пригнічує його.
    • Автоматичне підвищення збереженого токена пристрою під час одноразової повторної спроби AUTH_TOKEN_MISMATCH дозволене лише для довірених endpoints — loopback або wss:// із закріпленим tlsFingerprint. Публічний wss:// без pinning не підходить.
  • Вбудований bootstrap через код налаштування повертає основний токен вузла hello-ok.auth.deviceToken плюс обмежений токен оператора в hello-ok.auth.deviceTokens для довіреної передачі на мобільний пристрій. Токен оператора містить operator.talk.secrets для читання нативної конфігурації Talk, але не містить scopes мутації спарювання та operator.admin.
  • Поки non-baseline bootstrap через код налаштування очікує схвалення, деталі PAIRING_REQUIRED містять recommendedNextStep: "wait_then_retry", retryable: true і pauseReconnect: false. Клієнти мають продовжувати повторне підключення з тим самим bootstrap-токеном, доки запит не буде схвалено або токен не стане недійсним.
  • Зберігайте hello-ok.auth.deviceTokens лише тоді, коли підключення використовувало bootstrap-автентифікацію на довіреному транспорті, як-от wss:// або loopback/local pairing.
  • Якщо клієнт надає явний deviceToken або явні scopes, цей запитаний викликачем набір scopes залишається авторитетним; кешовані scopes повторно використовуються лише тоді, коли клієнт повторно використовує збережений токен для пристрою.
  • Токени пристроїв можна ротувати/відкликати через device.token.rotate і device.token.revoke (потрібен scope operator.pairing). Ротація або відкликання вузла чи іншої неоператорської ролі також потребує operator.admin.
  • device.token.rotate повертає метадані ротації. Він повторює замінний bearer-токен лише для викликів із того самого пристрою, які вже автентифіковані цим токеном пристрою, щоб token-only клієнти могли зберегти заміну перед повторним підключенням. Ротації зі спільним/адміністративним доступом не повторюють bearer-токен.
  • Видача, ротація та відкликання токенів залишаються обмеженими затвердженим набором ролей, записаним у записі спарювання цього пристрою; мутація токена не може розширити або націлитися на роль пристрою, яку схвалення спарювання ніколи не надавало.
  • Для token-сесій спарених пристроїв керування пристроями є self-scoped, якщо викликач також не має operator.admin: викликачі без прав адміністратора можуть керувати лише токеном оператора для запису власного пристрою. Керування токенами вузла та інших неоператорських ролей доступне лише адміністратору, навіть для власного пристрою викликача.
  • device.token.rotate і device.token.revoke також перевіряють цільовий набір scopes токена оператора щодо поточних scopes сесії викликача. Викликачі без прав адміністратора не можуть ротувати або відкликати ширший токен оператора, ніж уже мають.
  • Помилки автентифікації містять error.details.code плюс підказки для відновлення:
    • error.details.canRetryWithDeviceToken (boolean)
    • error.details.recommendedNextStep (retry_with_device_token, update_auth_configuration, update_auth_credentials, wait_then_retry, review_auth_configuration)
  • Поведінка клієнта для AUTH_TOKEN_MISMATCH:
    • Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном для пристрою.
    • Якщо ця повторна спроба не вдається, клієнти мають зупинити автоматичні цикли повторного підключення й показати оператору вказівки щодо дій.
  • AUTH_SCOPE_MISMATCH означає, що токен пристрою розпізнано, але він не покриває запитану роль/scopes. Клієнти не мають показувати це як недійсний токен; запропонуйте оператору повторно спарити або схвалити вужчий/ширший контракт scopes.

Ідентичність пристрою + спарювання

  • Вузли мають містити стабільну ідентичність пристрою (device.id), отриману з відбитка keypair.
  • Gateways видають токени для кожного пристрою + ролі.
  • Схвалення спарювання потрібні для нових ID пристроїв, якщо не ввімкнене локальне автоматичне схвалення.
  • Автоматичне схвалення спарювання зосереджене на прямих підключеннях local loopback.
  • OpenClaw також має вузький backend/container-local шлях самопідключення для довірених helper-потоків зі спільним секретом.
  • Підключення same-host tailnet або LAN усе одно вважаються віддаленими для спарювання та потребують схвалення.
  • WS-клієнти зазвичай містять ідентичність device під час connect (оператор + вузол). Єдині винятки для оператора без пристрою — явні довірені шляхи:
    • gateway.controlUi.allowInsecureAuth=true для сумісності з небезпечним HTTP лише на localhost.
    • успішна автентифікація оператора Control UI через gateway.auth.mode: "trusted-proxy".
    • gateway.controlUi.dangerouslyDisableDeviceAuth=true (break-glass, серйозне зниження безпеки).
    • direct-loopback backend RPCs gateway-client на зарезервованому внутрішньому helper-шляху.
  • Пропуск ідентичності пристрою має наслідки для scopes. Коли підключення оператора без пристрою дозволене через явний довірений шлях, OpenClaw усе одно очищає самостійно оголошені scopes до порожнього набору, якщо цей шлях не має названого винятку збереження scopes. Методи, обмежені scopes, тоді завершуються помилкою missing scope.
  • gateway.controlUi.dangerouslyDisableDeviceAuth=true є шляхом збереження scopes break-glass для Control UI. Він не надає scopes довільним користувацьким backend або CLI-подібним WebSocket-клієнтам.
  • Зарезервований direct-loopback backend helper-шлях gateway-client зберігає scopes лише для внутрішніх локальних control-plane RPCs; користувацькі backend IDs не отримують цього винятку.
  • Усі підключення мають підписувати наданий сервером nonce connect.challenge.

Діагностика міграції автентифікації пристрою

Для legacy клієнтів, які досі використовують поведінку підпису до challenge, connect тепер повертає коди деталей DEVICE_AUTH_* у error.details.code зі стабільним error.details.reason.

Поширені помилки міграції:

Повідомлення details.code details.reason Значення
device nonce required DEVICE_AUTH_NONCE_REQUIRED device-nonce-missing Клієнт пропустив device.nonce (або надіслав порожнє значення).
device nonce mismatch DEVICE_AUTH_NONCE_MISMATCH device-nonce-mismatch Клієнт підписав зі застарілим/неправильним nonce.
device signature invalid DEVICE_AUTH_SIGNATURE_INVALID device-signature Payload підпису не відповідає v2 payload.
device signature expired DEVICE_AUTH_SIGNATURE_EXPIRED device-signature-stale Підписана мітка часу виходить за межі дозволеного skew.
device identity mismatch DEVICE_AUTH_DEVICE_ID_MISMATCH device-id-mismatch device.id не відповідає відбитку публічного ключа.
device public key invalid DEVICE_AUTH_PUBLIC_KEY_INVALID device-public-key Помилка формату/канонікалізації публічного ключа.

Ціль міграції:

  • Завжди чекайте на connect.challenge.
  • Підписуйте v2 payload, який містить серверний nonce.
  • Надсилайте той самий nonce у connect.params.device.nonce.
  • Рекомендований payload підпису — v3, який прив’язує platform і deviceFamily на додаток до полів device/client/role/scopes/token/nonce.
  • Legacy підписи v2 залишаються прийнятими для сумісності, але pinning метаданих спареного пристрою все одно керує політикою команд під час повторного підключення.

TLS + pinning

  • TLS підтримується для WS-підключень.
  • Клієнти можуть необов’язково закріпити відбиток сертифіката Gateway (див. конфігурацію gateway.tls плюс gateway.remote.tlsFingerprint або CLI --tls-fingerprint).

Scope

Цей протокол відкриває повний API gateway (статус, канали, моделі, чат, агент, сесії, вузли, схвалення тощо). Точну поверхню визначають схеми TypeBox у packages/gateway-protocol/src/schema.ts.

Пов’язане

Was this useful?
On this page

On this page