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 → Клієнт (виклик до підключення):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Клієнт → Gateway:
{ "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 → Клієнт:
{ "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 повідомляє узгоджені
дозволи без полів токенів:
{ "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }}Довірені бекенд-клієнти в тому самому процесі (client.id: "gateway-client",
client.mode: "backend") можуть опускати device на прямих loopback-з’єднаннях, коли
вони автентифікуються спільним gateway-токеном/паролем. Цей шлях зарезервований
для внутрішніх RPC площини керування й не дає застарілим базовим станам поєднання CLI/пристрою
блокувати локальну бекенд-роботу, як-от оновлення сесій subagent. Віддалені клієнти,
клієнти з браузерним origin, клієнти-вузли й явні клієнти з токеном пристрою/ідентичністю пристрою
далі використовують звичайні перевірки поєднання й підвищення областей дії.
Коли токен пристрою видано, hello-ok також містить:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}Вбудований bootstrap через QR/код налаштування є свіжим шляхом передачі на мобільний пристрій. Успішне підключення базового коду налаштування повертає основний токен вузла плюс один обмежений токен оператора:
{ "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.
Приклад вузла
{ "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.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.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", щоб записати, що поєднаний вузол був
активним під час фонового пробудження, не позначаючи його підключеним.
{ "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 повертають структурований результат:
{ "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 і не запише фінальний sentinelok.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абоpluginpluginId: власник 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для рішень щодо встановлення, якими володіє оператор.
- Режим ClawHub:
- Оператори можуть викликати
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(потребує scopeoperator.approvals). - Для
host=nodeexec.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:genpnpm protocol:gen:swiftpnpm 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) або не-loopbackgateway.auth.mode: "trusted-proxy", задовольняють перевірку автентифікації підключення через заголовки запиту замістьconnect.params.auth.*. - Private-ingress
gateway.auth.mode: "none"повністю пропускає автентифікацію підключення за спільним секретом; не відкривайте цей режим на публічному/ненадійному ingress. - Після спарювання Gateway видає токен пристрою, обмежений роллю підключення
- scopes. Він повертається в
hello-ok.auth.deviceToken, і клієнт має зберігати його для майбутніх підключень.
- scopes. Він повертається в
- Клієнти мають зберігати основний
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(потрібен scopeoperator.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.