diff --git a/docs/uk/gateway/protocol.md b/docs/uk/gateway/protocol.md index c5cd33d82..f88a8057d 100644 --- a/docs/uk/gateway/protocol.md +++ b/docs/uk/gateway/protocol.md @@ -1,40 +1,41 @@ --- read_when: - - Реалізація або оновлення клієнтів шлюзу WS + - Реалізація або оновлення клієнтів gateway WS - Налагодження невідповідностей протоколу або збоїв підключення - Повторне генерування схеми/моделей протоколу -summary: 'Протокол Gateway WebSocket: рукостискання, кадри, версіонування' +summary: 'Протокол Gateway WebSocket: рукостискання, кадри, керування версіями' title: Протокол Gateway x-i18n: - generated_at: "2026-04-23T00:49:07Z" + generated_at: "2026-04-23T17:12:49Z" model: gpt-5.4 provider: openai - source_hash: 9d4ea65fbe31962ed8ece04a645cfe5aaff9fee8b5f89bc896b461cd45567634 + source_hash: 706a6c67129a8e15283ab2635cca11dcc3c6af35aeaefa70d95c28ccd5097a28 source_path: gateway/protocol.md workflow: 15 --- # Протокол Gateway (WebSocket) -Протокол Gateway WS — це **єдина контрольна площина + транспорт Node** для -OpenClaw. Усі клієнти (CLI, веб-інтерфейс, застосунок macOS, Node iOS/Android, headless -Node) підключаються через WebSocket і оголошують свою **роль** + **область видимості** під час рукостискання. +Протокол Gateway WS — це **єдина площина керування + транспорт Node** для +OpenClaw. Усі клієнти (CLI, веб-інтерфейс, застосунок macOS, iOS/Android Node, +headless Node) підключаються через WebSocket і оголошують свої **роль** + **область доступу** під +час рукостискання. ## Транспорт -- WebSocket, текстові кадри з JSON-корисним навантаженням. +- WebSocket, текстові кадри з JSON-навантаженнями. - Перший кадр **має** бути запитом `connect`. - Кадри до підключення обмежені 64 KiB. Після успішного рукостискання клієнти - повинні дотримуватися обмежень `hello-ok.policy.maxPayload` і - `hello-ok.policy.maxBufferedBytes`. Коли діагностику ввімкнено, - надто великі вхідні кадри й повільні вихідні буфери генерують події `payload.large` - до того, як Gateway закриє з’єднання або відкине відповідний кадр. Ці події зберігають - розміри, обмеження, поверхні та безпечні коди причин. Вони не зберігають тіло повідомлення, - вміст вкладень, тіло необробленого кадру, токени, cookie або секретні значення. + мають дотримуватися обмежень `hello-ok.policy.maxPayload` і + `hello-ok.policy.maxBufferedBytes`. Якщо діагностику ввімкнено, + надто великі вхідні кадри та повільні вихідні буфери генерують події `payload.large` + до того, як gateway закриє з’єднання або відкине відповідний кадр. Ці події зберігають + розміри, ліміти, поверхні та безпечні коди причин. Вони не зберігають тіло повідомлення, + вміст вкладень, сире тіло кадру, токени, cookie або секретні значення. ## Рукостискання (connect) -Gateway → клієнт (виклик до підключення): +Gateway → Клієнт (виклик до підключення): ```json { @@ -79,7 +80,7 @@ Gateway → клієнт (виклик до підключення): } ``` -Gateway → клієнт: +Gateway → Клієнт: ```json { @@ -101,12 +102,12 @@ Gateway → клієнт: } ``` -`server`, `features`, `snapshot` і `policy` — усі обов’язкові за схемою +`server`, `features`, `snapshot` і `policy` — усі обов’язкові згідно зі схемою (`src/gateway/protocol/schema/frames.ts`). `canvasHostUrl` є необов’язковим. `auth` -повідомляє про узгоджені роль/області видимості, коли вони доступні, і містить `deviceToken`, -коли Gateway його видає. +повідомляє про узгоджені role/scopes, коли вони доступні, і включає `deviceToken`, +коли gateway його видає. -Коли токен пристрою не видається, `hello-ok.auth` усе одно може повідомляти про узгоджені +Якщо токен пристрою не видається, `hello-ok.auth` усе одно може повідомляти про узгоджені дозволи: ```json @@ -151,11 +152,11 @@ Gateway → клієнт: ``` Для вбудованого потоку bootstrap node/operator основний токен node лишається -`scopes: []`, а будь-який переданий токен operator лишається обмеженим списком дозволів -bootstrap operator (`operator.approvals`, `operator.read`, -`operator.talk.secrets`, `operator.write`). Перевірки областей видимості bootstrap лишаються +`scopes: []`, а будь-який переданий токен operator лишається обмеженим allowlist bootstrap operator +(`operator.approvals`, `operator.read`, +`operator.talk.secrets`, `operator.write`). Перевірки bootstrap scope лишаються прив’язаними до префікса ролі: записи operator задовольняють лише запити operator, а ролі, що не є operator, -усе одно потребують областей видимості під власним префіксом ролі. +усе одно потребують scopes під власним префіксом ролі. ### Приклад Node @@ -192,24 +193,24 @@ bootstrap operator (`operator.approvals`, `operator.read`, } ``` -## Кадрування +## Форматування кадрів - **Запит**: `{type:"req", id, method, params}` - **Відповідь**: `{type:"res", id, ok, payload|error}` - **Подія**: `{type:"event", event, payload, seq?, stateVersion?}` -Методи з побічними ефектами вимагають **ключі ідемпотентності** (див. схему). +Методи з побічними ефектами потребують **ключів ідемпотентності** (див. схему). -## Ролі + області видимості +## Ролі + scopes ### Ролі -- `operator` = клієнт контрольної площини (CLI/UI/автоматизація). +- `operator` = клієнт площини керування (CLI/UI/автоматизація). - `node` = хост можливостей (camera/screen/canvas/system.run). -### Області видимості (operator) +### Scopes (operator) -Поширені області видимості: +Поширені scopes: - `operator.read` - `operator.write` @@ -218,336 +219,269 @@ bootstrap operator (`operator.approvals`, `operator.read`, - `operator.pairing` - `operator.talk.secrets` -`talk.config` з `includeSecrets: true` вимагає `operator.talk.secrets` +`talk.config` з `includeSecrets: true` потребує `operator.talk.secrets` (або `operator.admin`). -Методи Gateway RPC, зареєстровані Plugin, можуть запитувати власну область видимості operator, але -зарезервовані базові префікси адміністратора (`config.*`, `exec.approvals.*`, `wizard.*`, +Методи gateway RPC, зареєстровані Plugin, можуть вимагати власний scope operator, але +зарезервовані префікси core admin (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) завжди зіставляються з `operator.admin`. -Область видимості методу — лише перший бар’єр. Деякі slash-команди, доступні через -`chat.send`, додатково застосовують суворіші перевірки на рівні команд. Наприклад, сталі -записи `/config set` і `/config unset` вимагають `operator.admin`. +Scope методу — лише перший рівень перевірки. Деякі slash-команди, до яких звертаються через +`chat.send`, додатково застосовують суворіші перевірки на рівні команди. Наприклад, постійні +записи `/config set` і `/config unset` потребують `operator.admin`. -`node.pair.approve` також має додаткову перевірку області видимості під час схвалення поверх -базової області видимості методу: +`node.pair.approve` також має додаткову перевірку scope під час схвалення поверх +базового scope методу: -- запити без команди: `operator.pairing` -- запити з командами node, що не належать до exec: `operator.pairing` + `operator.write` -- запити, які містять `system.run`, `system.run.prepare` або `system.which`: +- запити без команд: `operator.pairing` +- запити з командами node, що не є exec: `operator.pairing` + `operator.write` +- запити, що включають `system.run`, `system.run.prepare` або `system.which`: `operator.pairing` + `operator.admin` ### Caps/commands/permissions (node) -Node оголошують твердження про можливості під час підключення: +Node оголошують заявлені можливості під час підключення: - `caps`: високорівневі категорії можливостей. -- `commands`: список дозволених команд для invoke. +- `commands`: allowlist команд для invoke. - `permissions`: детальні перемикачі (наприклад, `screen.record`, `camera.capture`). -Gateway трактує це як **заявлені можливості** та забезпечує примусові списки дозволів на боці сервера. +Gateway розглядає це як **заяви** та застосовує allowlist на боці сервера. ## Presence - `system-presence` повертає записи, згруповані за ідентичністю пристрою. -- Записи presence містять `deviceId`, `roles` і `scopes`, щоб UI міг показувати один рядок на пристрій, - навіть коли він підключений і як **operator**, і як **node**. +- Записи presence містять `deviceId`, `roles` і `scopes`, щоб UI могли показувати один рядок на пристрій, + навіть коли він підключається і як **operator**, і як **node**. -## Обмеження областей видимості для broadcast-подій +## Обмеження scope для широкомовних подій -Broadcast-події WebSocket, які сервер надсилає клієнтам, обмежуються областями видимості, щоб сесії лише з pairing-областю або сесії тільки для node не отримували пасивно вміст сесій. +Широкомовні події WebSocket, які надсилає сервер, обмежуються через scope, щоб сесії лише з pairing scope або лише Node не отримували пасивно вміст сесії. -- **Кадри chat, agent і tool-result** (включно з потоковими подіями `agent` і результатами викликів інструментів) вимагають щонайменше `operator.read`. Сесії без `operator.read` повністю пропускають ці кадри. -- **Broadcast-події `plugin.*`, визначені Plugin**, обмежуються `operator.write` або `operator.admin` залежно від того, як Plugin їх зареєстрував. -- **Події стану й транспорту** (`heartbeat`, `presence`, `tick`, життєвий цикл connect/disconnect тощо) лишаються без обмежень, щоб стан транспорту залишався спостережуваним для кожної автентифікованої сесії. -- **Невідомі сімейства broadcast-подій** за замовчуванням обмежуються областями видимості (fail-closed), якщо зареєстрований обробник явно не послаблює це правило. +- **Кадри chat, agent і результатів інструментів** (включно з потоковими подіями `agent` і результатами викликів інструментів) вимагають щонайменше `operator.read`. Сесії без `operator.read` повністю пропускають ці кадри. +- **Широкомовні події `plugin.*`, визначені Plugin**, обмежуються до `operator.write` або `operator.admin` залежно від того, як Plugin їх зареєстрував. +- **Події статусу й транспорту** (`heartbeat`, `presence`, `tick`, життєвий цикл підключення/відключення тощо) лишаються без обмежень, щоб стан транспорту лишався видимим для кожної автентифікованої сесії. +- **Невідомі сімейства широкомовних подій** за замовчуванням обмежуються через scope (fail-closed), якщо зареєстрований обробник явно не послаблює ці обмеження. -Кожне клієнтське з’єднання підтримує власний номер послідовності для конкретного клієнта, тому broadcast-події зберігають монотонне впорядкування на цьому сокеті, навіть коли різні клієнти бачать різні підмножини потоку подій, відфільтровані за областями видимості. +Кожне клієнтське з’єднання підтримує власний порядковий номер для клієнта, тому широкомовні події зберігають монотонний порядок у цьому сокеті, навіть коли різні клієнти бачать різні відфільтровані через scope підмножини потоку подій. -## Поширені сімейства RPC-методів +## Поширені сімейства методів RPC -Ця сторінка не є згенерованим повним дампом, але публічна поверхня WS ширша, -ніж наведені вище приклади рукостискання/автентифікації. Це основні сімейства методів, які -Gateway відкриває сьогодні. +Публічна поверхня WS ширша за наведені вище приклади рукостискання/автентифікації. Це +не згенерований дамп — `hello-ok.features.methods` є консервативним +списком виявлення, збудованим із `src/gateway/server-methods-list.ts` плюс експортованих +методів завантажених plugin/channel. Розглядайте це як виявлення можливостей, а не як повне +перелічення `src/gateway/server-methods/*.ts`. -`hello-ok.features.methods` — це консервативний список виявлення можливостей, побудований із -`src/gateway/server-methods-list.ts` плюс експорту методів завантажених plugin/channel. -Сприймайте його як виявлення можливостей, а не як згенерований дамп усіх допоміжних викликів, -реалізованих у `src/gateway/server-methods/*.ts`. + + + - `health` повертає кешований або щойно перевірений знімок стану gateway. + - `diagnostics.stability` повертає недавній обмежений записувач стабільності діагностики. Він зберігає операційні метадані, такі як назви подій, кількість, розміри в байтах, показники пам’яті, стан черги/сесії, назви channel/plugin і ідентифікатори сесій. Він не зберігає текст chat, тіла webhook, виводи інструментів, сирі тіла запитів чи відповідей, токени, cookie або секретні значення. Потрібен scope operator read. + - `status` повертає підсумок gateway у стилі `/status`; чутливі поля включаються лише для клієнтів operator з admin scope. + - `gateway.identity.get` повертає ідентичність пристрою gateway, що використовується у relay та потоках pairing. + - `system-presence` повертає поточний знімок presence для підключених пристроїв operator/node. + - `system-event` додає системну подію та може оновлювати/транслювати контекст presence. + - `last-heartbeat` повертає останню збережену подію Heartbeat. + - `set-heartbeats` перемикає обробку Heartbeat на gateway. + -### Система та ідентичність + + - `models.list` повертає каталог моделей, дозволених під час виконання. + - `usage.status` повертає зведення вікон використання провайдера/залишку квоти. + - `usage.cost` повертає агреговані зведення вартості використання для діапазону дат. + - `doctor.memory.status` повертає готовність vector-memory / embedding для активного робочого простору агента за замовчуванням. + - `sessions.usage` повертає зведення використання для кожної сесії. + - `sessions.usage.timeseries` повертає часовий ряд використання для однієї сесії. + - `sessions.usage.logs` повертає записи журналу використання для однієї сесії. + -- `health` повертає кешований або щойно перевірений знімок стану Gateway. -- `diagnostics.stability` повертає нещодавній обмежений засіб запису діагностичної - стабільності. Він зберігає операційні метадані, такі як назви подій, кількість, розміри в байтах, - показники пам’яті, стан черги/сесії, назви channel/plugin і ідентифікатори сесій. - Він не зберігає текст chat, тіла webhook, вивід інструментів, необроблені тіла запитів або - відповідей, токени, cookie чи секретні значення. Потрібна область видимості operator read. -- `status` повертає підсумок Gateway у стилі `/status`; чутливі поля - включаються лише для клієнтів operator з областю видимості admin. -- `gateway.identity.get` повертає ідентичність пристрою Gateway, що використовується в потоках relay і - pairing. -- `system-presence` повертає поточний знімок presence для підключених - пристроїв operator/node. -- `system-event` додає системну подію та може оновлювати/транслювати контекст - presence. -- `last-heartbeat` повертає останню збережену подію Heartbeat. -- `set-heartbeats` перемикає обробку Heartbeat на Gateway. + + - `channels.status` повертає зведення статусу вбудованих і bundled channel/plugin. + - `channels.logout` виходить із конкретного channel/account, якщо channel підтримує вихід. + - `web.login.start` запускає потік входу через QR/web для поточного web channel provider, що підтримує QR. + - `web.login.wait` очікує завершення цього потоку входу через QR/web і запускає channel в разі успіху. + - `push.test` надсилає тестовий APNs push до зареєстрованого iOS Node. + - `voicewake.get` повертає збережені тригери wake-word. + - `voicewake.set` оновлює тригери wake-word і транслює зміну. + -### Моделі та використання + + - `send` — це RPC прямої вихідної доставки для надсилання з націленням на channel/account/thread поза runner chat. + - `logs.tail` повертає tail налаштованого файлового журналу gateway з елементами керування cursor/limit і max-byte. + -- `models.list` повертає каталог моделей, дозволених у поточному середовищі виконання. -- `usage.status` повертає зведення вікон використання/залишкових квот провайдера. -- `usage.cost` повертає зведення агрегованих витрат використання за діапазон дат. -- `doctor.memory.status` повертає готовність векторної пам’яті / вбудовувань для - активного робочого простору агента за замовчуванням. -- `sessions.usage` повертає зведення використання за сесіями. -- `sessions.usage.timeseries` повертає часовий ряд використання для однієї сесії. -- `sessions.usage.logs` повертає записи журналу використання для однієї сесії. + + - `talk.config` повертає корисне навантаження ефективної конфігурації Talk; `includeSecrets` потребує `operator.talk.secrets` (або `operator.admin`). + - `talk.mode` встановлює/транслює поточний стан режиму Talk для клієнтів WebChat/Control UI. + - `talk.speak` синтезує мовлення через активного провайдера мовлення Talk. + - `tts.status` повертає стан увімкнення TTS, активного провайдера, резервних провайдерів і стан конфігурації провайдера. + - `tts.providers` повертає видимий перелік провайдерів TTS. + - `tts.enable` і `tts.disable` перемикають стан налаштувань TTS. + - `tts.setProvider` оновлює бажаного провайдера TTS. + - `tts.convert` виконує одноразове перетворення text-to-speech. + -### Канали та допоміжні засоби входу + + - `secrets.reload` повторно розв’язує активні SecretRefs і замінює стан секретів під час виконання лише за повного успіху. + - `secrets.resolve` розв’язує призначення секретів для цільових комбінацій команда/ціль. + - `config.get` повертає поточний знімок конфігурації та хеш. + - `config.set` записує валідоване навантаження конфігурації. + - `config.patch` об’єднує часткове оновлення конфігурації. + - `config.apply` валідує й замінює повне навантаження конфігурації. + - `config.schema` повертає навантаження актуальної схеми конфігурації, яке використовують Control UI і інструменти CLI: schema, `uiHints`, версію та метадані генерації, зокрема метадані схеми plugin + channel, коли середовище виконання може їх завантажити. Схема містить метадані полів `title` / `description`, похідні від тих самих міток і довідкового тексту, що використовує UI, зокрема для вкладених object, wildcard, array-item і гілок композиції `anyOf` / `oneOf` / `allOf`, коли для відповідних полів є документація. + - `config.schema.lookup` повертає навантаження пошуку, обмежене шляхом, для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідну підказку + `hintPath` і зведення безпосередніх дочірніх елементів для деталізації в UI/CLI. Вузли схеми в результаті пошуку зберігають орієнтовану на користувача документацію та поширені поля валідації (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, числові/рядкові/масивні/об’єктні межі та прапорці на кшталт `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Зведення дочірніх елементів містять `key`, нормалізований `path`, `type`, `required`, `hasChildren`, а також відповідні `hint` / `hintPath`. + - `update.run` запускає потік оновлення gateway і планує перезапуск лише тоді, коли саме оновлення завершилося успішно. + - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` відкривають доступ до wizard онбордингу через WS RPC. + -- `channels.status` повертає зведення стану вбудованих і bundled channel/plugin. -- `channels.logout` виходить із конкретного channel/account, якщо channel - підтримує вихід. -- `web.login.start` запускає потік входу QR/web для поточного web - channel provider із підтримкою QR. -- `web.login.wait` очікує завершення цього потоку входу QR/web і запускає - channel у разі успіху. -- `push.test` надсилає тестовий APNs push на зареєстрований Node iOS. -- `voicewake.get` повертає збережені тригери слова активації. -- `voicewake.set` оновлює тригери слова активації та транслює зміну. + + - `agents.list` повертає налаштовані записи Agent. + - `agents.create`, `agents.update` і `agents.delete` керують записами Agent і підключенням workspace. + - `agents.files.list`, `agents.files.get` і `agents.files.set` керують файлами bootstrap workspace, відкритими для Agent. + - `agent.identity.get` повертає ефективну ідентичність помічника для Agent або сесії. + - `agent.wait` очікує завершення запуску й повертає кінцевий знімок, якщо він доступний. + -### Повідомлення та журнали + + - `sessions.list` повертає поточний індекс сесій. + - `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події змін сесії для поточного WS-клієнта. + - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають підписки на події transcript/повідомлень для однієї сесії. + - `sessions.preview` повертає обмежені попередні перегляди transcript для вказаних ключів сесій. + - `sessions.resolve` розв’язує або канонізує ціль сесії. + - `sessions.create` створює новий запис сесії. + - `sessions.send` надсилає повідомлення до наявної сесії. + - `sessions.steer` — це варіант переривання й спрямування для активної сесії. + - `sessions.abort` перериває активну роботу для сесії. + - `sessions.patch` оновлює метадані/перевизначення сесії. + - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сесії. + - `sessions.get` повертає повний збережений рядок сесії. + - Виконання chat, як і раніше, використовує `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` нормалізується для відображення в UI-клієнтах: вбудовані теги директив прибираються з видимого тексту, XML-навантаження викликів інструментів у вигляді plain-text (включно з `...`, `...`, `...`, `...` і обрізаними блоками викликів інструментів) та витеклі ASCII/full-width керівні токени моделі видаляються, чисті рядки помічника з мовчазних токенів, як-от точні `NO_REPLY` / `no_reply`, опускаються, а надто великі рядки можуть замінюватися заповнювачами. + -- `send` — це прямий RPC доставки назовні для - надсилання до channel/account/thread поза виконавцем chat. -- `logs.tail` повертає хвіст налаштованого файлового журналу Gateway з керуванням курсором/лімітом і - максимальним розміром у байтах. + + - `device.pair.list` повертає пристрої, що очікують схвалення, і вже схвалені пристрої. + - `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують записами пейрингу пристроїв. + - `device.token.rotate` ротує токен спареного пристрою в межах його схвалених role і scopes. + - `device.token.revoke` відкликає токен спареного пристрою. + -### Talk і TTS + + - `node.pair.request`, `node.pair.list`, `node.pair.approve`, `node.pair.reject` і `node.pair.verify` охоплюють пейринг Node і bootstrap verification. + - `node.list` і `node.describe` повертають стан відомих/підключених Node. + - `node.rename` оновлює мітку спареного Node. + - `node.invoke` пересилає команду до підключеного Node. + - `node.invoke.result` повертає результат запиту invoke. + - `node.event` переносить події, що походять від Node, назад у gateway. + - `node.canvas.capability.refresh` оновлює токени можливостей canvas, обмежені scope. + - `node.pending.pull` і `node.pending.ack` — це API черги для підключеного Node. + - `node.pending.enqueue` і `node.pending.drain` керують стійкою відкладеною роботою для offline/disconnected Node. + -- `talk.config` повертає ефективне корисне навантаження конфігурації Talk; `includeSecrets` - вимагає `operator.talk.secrets` (або `operator.admin`). -- `talk.mode` установлює/транслює поточний стан режиму Talk для - клієнтів WebChat/Control UI. -- `talk.speak` синтезує мовлення через активного мовленнєвого провайдера Talk. -- `tts.status` повертає стан увімкнення TTS, активного провайдера, резервних провайдерів - і стан конфігурації провайдера. -- `tts.providers` повертає видимий перелік провайдерів TTS. -- `tts.enable` і `tts.disable` перемикають стан налаштувань TTS. -- `tts.setProvider` оновлює бажаного провайдера TTS. -- `tts.convert` виконує одноразове перетворення тексту на мовлення. + + - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють одноразові запити approval для exec, а також пошук/повторення відкладених approval. + - `exec.approval.waitDecision` очікує на одне відкладене approval exec і повертає підсумкове рішення (або `null` за тайм-аутом). + - `exec.approvals.get` і `exec.approvals.set` керують знімками політики approval для gateway exec. + - `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для Node політикою approval exec через relay-команди Node. + - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють потоки approval, визначені Plugin. + -### Секрети, конфігурація, оновлення та майстер налаштування - -- `secrets.reload` повторно розв’язує активні SecretRefs і замінює стан секретів у середовищі виконання - лише за повного успіху. -- `secrets.resolve` розв’язує призначення секретів для цільових команд для конкретного - набору command/target. -- `config.get` повертає поточний знімок конфігурації та хеш. -- `config.set` записує перевірене корисне навантаження конфігурації. -- `config.patch` об’єднує часткове оновлення конфігурації. -- `config.apply` перевіряє + замінює повне корисне навантаження конфігурації. -- `config.schema` повертає корисне навантаження поточної схеми конфігурації, яке використовують Control UI і - інструменти CLI: схема, `uiHints`, версія та метадані генерації, зокрема - метадані схеми plugin + channel, коли середовище виконання може їх завантажити. Схема - містить метадані полів `title` / `description`, похідні від тих самих міток - і тексту довідки, які використовує UI, зокрема для вкладених об’єктів, wildcard, - елементів масиву та гілок композиції `anyOf` / `oneOf` / `allOf`, коли існує - відповідна документація для полів. -- `config.schema.lookup` повертає корисне навантаження пошуку з обмеженням шляхом для одного шляху конфігурації: - нормалізований шлях, неглибокий вузол схеми, зіставлену підказку + `hintPath` і - зведення безпосередніх дочірніх елементів для деталізації в UI/CLI. - - Вузли схеми пошуку зберігають орієнтовану на користувача документацію та типові поля перевірки: - `title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, - числові/рядкові/масивні/об’єктні межі та булеві прапорці, такі як - `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`. - - Зведення дочірніх елементів показують `key`, нормалізований `path`, `type`, `required`, - `hasChildren`, а також зіставлені `hint` / `hintPath`. -- `update.run` запускає потік оновлення Gateway і планує перезапуск лише тоді, - коли саме оновлення було успішним. -- `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` відкривають - майстер налаштування onboarding через WS RPC. - -### Наявні основні сімейства - -#### Допоміжні засоби агента та робочого простору - -- `agents.list` повертає налаштовані записи агентів. -- `agents.create`, `agents.update` і `agents.delete` керують записами агентів і - прив’язкою робочого простору. -- `agents.files.list`, `agents.files.get` і `agents.files.set` керують файлами - bootstrap робочого простору, відкритими для агента. -- `agent.identity.get` повертає фактичну ідентичність помічника для агента або - сесії. -- `agent.wait` очікує завершення запуску й повертає термінальний знімок, коли - він доступний. - -#### Керування сесіями - -- `sessions.list` повертає поточний індекс сесій. -- `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події - змін сесії для поточного WS-клієнта. -- `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають - підписки на події транскрипту/повідомлень для однієї сесії. -- `sessions.preview` повертає обмежені попередні перегляди транскрипту для конкретних - ключів сесій. -- `sessions.resolve` розв’язує або канонізує ціль сесії. -- `sessions.create` створює новий запис сесії. -- `sessions.send` надсилає повідомлення в наявну сесію. -- `sessions.steer` — це варіант переривання й спрямування для активної сесії. -- `sessions.abort` перериває активну роботу для сесії. -- `sessions.patch` оновлює метадані/перевизначення сесії. -- `sessions.reset`, `sessions.delete` і `sessions.compact` виконують - обслуговування сесії. -- `sessions.get` повертає повний збережений рядок сесії. -- виконання chat, як і раніше, використовує `chat.history`, `chat.send`, `chat.abort` і - `chat.inject`. -- `chat.history` нормалізується для відображення клієнтам UI: вбудовані теги директив - прибираються з видимого тексту, XML-корисні навантаження викликів інструментів у звичайному тексті (зокрема - `...`, `...`, - `...`, `...` і - обрізані блоки викликів інструментів), а також витеклі ASCII/повноширинні керівні токени моделі - прибираються, рядки помічника, що складаються лише з беззвучних токенів, такі як точні `NO_REPLY` / - `no_reply`, опускаються, а надто великі рядки можуть замінюватися заповнювачами. - -#### Pairing пристроїв і токени пристроїв - -- `device.pair.list` повертає очікувальні та схвалені спарені пристрої. -- `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують - записами pairing пристроїв. -- `device.token.rotate` обертає токен спареного пристрою в межах його схвалених - ролі та областей видимості. -- `device.token.revoke` відкликає токен спареного пристрою. - -#### Pairing Node, invoke і очікувальна робота - -- `node.pair.request`, `node.pair.list`, `node.pair.approve`, - `node.pair.reject` і `node.pair.verify` охоплюють pairing Node і bootstrap - verification. -- `node.list` і `node.describe` повертають стан відомих/підключених Node. -- `node.rename` оновлює мітку спареного Node. -- `node.invoke` пересилає команду підключеному Node. -- `node.invoke.result` повертає результат для запиту invoke. -- `node.event` передає події, що походять від Node, назад у Gateway. -- `node.canvas.capability.refresh` оновлює токени можливостей canvas з обмеженою областю дії. -- `node.pending.pull` і `node.pending.ack` — це API черги для підключених Node. -- `node.pending.enqueue` і `node.pending.drain` керують стійкою очікувальною роботою - для офлайн/відключених Node. - -#### Сімейства схвалень - -- `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і - `exec.approval.resolve` охоплюють одноразові запити на схвалення exec плюс - пошук/повторення очікувальних схвалень. -- `exec.approval.waitDecision` очікує рішення щодо одного очікувального схвалення exec і повертає - фінальне рішення (або `null` у разі тайм-ауту). -- `exec.approvals.get` і `exec.approvals.set` керують знімками політики схвалення exec - Gateway. -- `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для Node політикою exec - approval через команди relay Node. -- `plugin.approval.request`, `plugin.approval.list`, - `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють - потоки схвалення, визначені Plugin. - -#### Інші основні сімейства - -- automation: - - `wake` планує негайне або на наступний Heartbeat введення тексту пробудження - - `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, - `cron.run`, `cron.runs` -- skills/tools: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective` + + - Автоматизація: `wake` планує негайне або наступне за Heartbeat вбудовування тексту пробудження; `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують запланованою роботою. + - Skills та інструменти: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`. + + ### Поширені сімейства подій -- `chat`: оновлення UI chat, такі як `chat.inject` та інші події chat, - пов’язані лише з транскриптом. -- `session.message` і `session.tool`: оновлення транскрипту/потоку подій для - сесії, на яку оформлено підписку. -- `sessions.changed`: індекс сесій або метадані змінено. -- `presence`: оновлення знімка системного presence. -- `tick`: періодична подія keepalive / перевірки доступності. -- `health`: оновлення знімка стану Gateway. +- `chat`: оновлення chat у UI, як-от `chat.inject` та інші події chat, що стосуються + лише transcript. +- `session.message` і `session.tool`: оновлення transcript/потоку подій для + сесії, на яку є підписка. +- `sessions.changed`: індекс сесій або метадані змінилися. +- `presence`: оновлення знімка system presence. +- `tick`: періодична подія keepalive / liveness. +- `health`: оновлення знімка стану gateway. - `heartbeat`: оновлення потоку подій Heartbeat. - `cron`: подія зміни запуску/завдання Cron. -- `shutdown`: сповіщення про завершення роботи Gateway. -- `node.pair.requested` / `node.pair.resolved`: життєвий цикл pairing Node. -- `node.invoke.request`: broadcast запиту invoke для Node. +- `shutdown`: сповіщення про вимкнення gateway. +- `node.pair.requested` / `node.pair.resolved`: життєвий цикл пейрингу Node. +- `node.invoke.request`: широкомовний запит invoke Node. - `device.pair.requested` / `device.pair.resolved`: життєвий цикл спареного пристрою. -- `voicewake.changed`: змінено конфігурацію тригера слова активації. +- `voicewake.changed`: конфігурацію тригерів wake-word змінено. - `exec.approval.requested` / `exec.approval.resolved`: життєвий цикл - схвалення exec. + approval exec. - `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл - схвалення plugin. + approval Plugin. ### Допоміжні методи Node - Node можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів skill - для перевірок автоматичного дозволу. + для автоматичних перевірок allow. ### Допоміжні методи operator -- Operator можуть викликати `commands.list` (`operator.read`), щоб отримати перелік команд середовища виконання для агента. - - `agentId` необов’язковий; не вказуйте його, щоб читати робочий простір агента за замовчуванням. - - `scope` керує тим, на яку поверхню націлений основний `name`: +- Operators можуть викликати `commands.list` (`operator.read`), щоб отримати runtime + інвентар команд для Agent. + - `agentId` необов’язковий; опустіть його, щоб читати workspace Agent за замовчуванням. + - `scope` керує тим, яку поверхню націлює основне `name`: - `text` повертає основний текстовий токен команди без початкового `/` - - `native` і стандартний шлях `both` повертають орієнтовані на провайдера native-імена, + - `native` і типовий шлях `both` повертають нативні назви з урахуванням provider, коли вони доступні - - `textAliases` містить точні slash-аліаси, такі як `/model` і `/m`. - - `nativeName` містить орієнтовану на провайдера native-назву команди, коли вона існує. - - `provider` необов’язковий і впливає лише на native-іменування та доступність native-команд plugin. - - `includeArgs=false` пропускає серіалізовані метадані аргументів у відповіді. -- Operator можуть викликати `tools.catalog` (`operator.read`), щоб отримати каталог інструментів середовища виконання для - агента. Відповідь містить згруповані інструменти та метадані походження: + - `textAliases` містить точні slash-аліаси, як-от `/model` і `/m`. + - `nativeName` містить нативну назву з урахуванням provider, якщо така існує. + - `provider` необов’язковий і впливає лише на нативне іменування та доступність нативних команд + Plugin. + - `includeArgs=false` опускає із відповіді серіалізовані метадані аргументів. +- Operators можуть викликати `tools.catalog` (`operator.read`), щоб отримати runtime-каталог інструментів для + Agent. Відповідь містить згруповані інструменти й метадані походження: - `source`: `core` або `plugin` - - `pluginId`: власник plugin, коли `source="plugin"` - - `optional`: чи є інструмент plugin необов’язковим -- Operator можуть викликати `tools.effective` (`operator.read`), щоб отримати фактичний перелік інструментів середовища виконання - для сесії. + - `pluginId`: власник Plugin, коли `source="plugin"` + - `optional`: чи є інструмент Plugin необов’язковим +- Operators можуть викликати `tools.effective` (`operator.read`), щоб отримати runtime-effective + інвентар інструментів для сесії. - `sessionKey` обов’язковий. - - Gateway виводить довірений контекст середовища виконання із сесії на боці сервера, замість того щоб приймати - наданий викликачем контекст автентифікації або доставки. - - Відповідь має область дії сесії та відображає те, що активна розмова може використовувати просто зараз, - зокрема core, plugin і channel tools. -- Operator можуть викликати `skills.status` (`operator.read`), щоб отримати видимий - перелік skills для агента. - - `agentId` необов’язковий; не вказуйте його, щоб читати робочий простір агента за замовчуванням. - - Відповідь містить відповідність вимогам, відсутні вимоги, перевірки конфігурації та - санітизовані параметри встановлення без розкриття необроблених секретних значень. -- Operator можуть викликати `skills.search` і `skills.detail` (`operator.read`) для + - Gateway виводить trusted runtime context із сесії на боці сервера замість того, щоб приймати + auth або контекст доставки, надані викликачем. + - Відповідь прив’язана до сесії та відображає те, що активна розмова може використовувати просто зараз, + зокрема інструменти core, plugin і channel. +- Operators можуть викликати `skills.status` (`operator.read`), щоб отримати видимий + інвентар Skills для Agent. + - `agentId` необов’язковий; опустіть його, щоб читати workspace Agent за замовчуванням. + - Відповідь містить відповідність умовам, відсутні вимоги, перевірки конфігурації та + очищені параметри встановлення без розкриття сирих секретних значень. +- Operators можуть викликати `skills.search` і `skills.detail` (`operator.read`) для метаданих виявлення ClawHub. -- Operator можуть викликати `skills.install` (`operator.admin`) у двох режимах: +- Operators можуть викликати `skills.install` (`operator.admin`) у двох режимах: - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` установлює - папку skill у каталог `skills/` робочого простору агента за замовчуванням. - - Режим інсталятора Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` - запускає оголошену дію `metadata.openclaw.install` на хості Gateway. -- Operator можуть викликати `skills.update` (`operator.admin`) у двох режимах: + теку skill до каталогу `skills/` workspace Agent за замовчуванням. + - Режим інсталятора gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` + виконує оголошену дію `metadata.openclaw.install` на хості gateway. +- Operators можуть викликати `skills.update` (`operator.admin`) у двох режимах: - Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у - робочому просторі агента за замовчуванням. - - Режим Config вносить зміни до значень `skills.entries.`, таких як `enabled`, + workspace Agent за замовчуванням. + - Режим config патчить значення `skills.entries.`, як-от `enabled`, `apiKey` і `env`. -## Схвалення exec +## Approval для exec -- Коли запит exec потребує схвалення, Gateway транслює `exec.approval.requested`. -- Клієнти operator виконують підтвердження, викликаючи `exec.approval.resolve` (потрібна область видимості `operator.approvals`). -- Для `host=node` `exec.approval.request` має містити `systemRunPlan` (канонічні метадані `argv`/`cwd`/`rawCommand`/сесії). Запити без `systemRunPlan` відхиляються. -- Після схвалення переслані виклики `node.invoke system.run` повторно використовують цей канонічний +- Коли запит exec потребує approval, gateway транслює `exec.approval.requested`. +- Клієнти operator виконують підтвердження, викликаючи `exec.approval.resolve` (потрібен scope `operator.approvals`). +- Для `host=node` `exec.approval.request` має включати `systemRunPlan` (канонічні метадані `argv`/`cwd`/`rawCommand`/сесії). Запити без `systemRunPlan` відхиляються. +- Після approval переслані виклики `node.invoke system.run` повторно використовують цей канонічний `systemRunPlan` як авторитетний контекст команди/cwd/сесії. - Якщо викликач змінює `command`, `rawCommand`, `cwd`, `agentId` або - `sessionKey` між prepare і остаточним пересиланням схваленого `system.run`, - Gateway відхиляє запуск замість того, щоб довіряти зміненому корисному навантаженню. + `sessionKey` між підготовкою й фінальним пересиланням схваленого `system.run`, + gateway відхиляє запуск замість того, щоб довіряти зміненому навантаженню. -## Резервна доставка агента +## Резервний режим доставки Agent -- Запити `agent` можуть містити `deliver=true`, щоб запросити вихідну доставку. -- `bestEffortDeliver=false` зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`. -- `bestEffortDeliver=true` дозволяє резервне виконання лише в межах сесії, коли неможливо розв’язати зовнішній маршрут доставки (наприклад, для внутрішніх/webchat сесій або неоднозначних багатоканальних конфігурацій). +- Запити `agent` можуть включати `deliver=true`, щоб запросити вихідну доставку. +- `bestEffortDeliver=false` зберігає строгий режим: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`. +- `bestEffortDeliver=true` дозволяє перейти до виконання лише в межах сесії, якщо не вдається розв’язати жодного зовнішнього маршруту доставки (наприклад, для внутрішніх/webchat-сесій або неоднозначних багатоканальних конфігурацій). -## Версіонування +## Керування версіями -- `PROTOCOL_VERSION` розташовано в `src/gateway/protocol/schema/protocol-schemas.ts`. +- `PROTOCOL_VERSION` знаходиться в `src/gateway/protocol/schema/protocol-schemas.ts`. - Клієнти надсилають `minProtocol` + `maxProtocol`; сервер відхиляє невідповідності. - Схеми + моделі генеруються з визначень TypeBox: - `pnpm protocol:gen` @@ -557,132 +491,132 @@ Gateway відкриває сьогодні. ### Константи клієнта Еталонний клієнт у `src/gateway/client.ts` використовує ці значення за замовчуванням. Вони -стабільні впродовж protocol v3 і є очікуваною базою для сторонніх клієнтів. +стабільні в межах протоколу v3 і є очікуваною базовою лінією для сторонніх клієнтів. -| Константа | Значення за замовчуванням | Джерело | -| ------------------------------------------ | ----------------------------------------------------- | ---------------------------------------------------------- | -| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| Тайм-аут запиту (на RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) | -| Тайм-аут preauth / connect-challenge | `10_000` ms | `src/gateway/handshake-timeouts.ts` (clamp `250`–`10_000`) | -| Початковий 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` | -| Пауза примусової зупинки перед `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 | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | -| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` | +| Константа | Значення за замовчуванням | Джерело | +| ----------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------- | +| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | +| Тайм-аут запиту (для кожного RPC) | `30_000` мс | `src/gateway/client.ts` (`requestTimeoutMs`) | +| Тайм-аут preauth / connect-challenge | `10_000` мс | `src/gateway/handshake-timeouts.ts` (clamp `250`–`10_000`) | +| Початковий backoff повторного підключення | `1_000` мс | `src/gateway/client.ts` (`backoffMs`) | +| Максимальний backoff повторного підключення | `30_000` мс | `src/gateway/client.ts` (`scheduleReconnect`) | +| Fast-retry clamp після закриття device-token | `250` мс | `src/gateway/client.ts` | +| Пільговий час примусової зупинки перед `terminate()` | `250` мс | `FORCE_STOP_TERMINATE_GRACE_MS` | +| Тайм-аут за замовчуванням для `stopAndWait()` | `1_000` мс | `STOP_AND_WAIT_TIMEOUT_MS` | +| Інтервал tick за замовчуванням (до `hello-ok`) | `30_000` мс | `src/gateway/client.ts` | +| Закриття через тайм-аут tick | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | +| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 МБ) | `src/gateway/server-constants.ts` | -Сервер оголошує фактичні `policy.tickIntervalMs`, `policy.maxPayload` -і `policy.maxBufferedBytes` у `hello-ok`; клієнти повинні дотримуватися цих значень, +Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload` +і `policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися саме цих значень, а не значень за замовчуванням до рукостискання. -## Автентифікація +## Auth -- Автентифікація Gateway за спільним секретом використовує `connect.params.auth.token` або - `connect.params.auth.password`, залежно від налаштованого режиму автентифікації. -- Режими з ідентичністю, такі як Tailscale Serve - (`gateway.auth.allowTailscale: true`) або не-loopback - `gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації connect на основі - заголовків запиту, а не `connect.params.auth.*`. -- Для private-ingress `gateway.auth.mode: "none"` повністю пропускає автентифікацію connect за спільним секретом; не відкривайте цей режим у публічному/недовіреному ingress. -- Після pairing Gateway видає **токен пристрою** з областю дії, обмеженою роллю + областями видимості - з’єднання. Він повертається в `hello-ok.auth.deviceToken` і має - зберігатися клієнтом для наступних підключень. -- Клієнти повинні зберігати основний `hello-ok.auth.deviceToken` після будь-якого +- Автентифікація gateway за спільним секретом використовує `connect.params.auth.token` або + `connect.params.auth.password` залежно від налаштованого режиму auth. +- Режими з прив’язкою до ідентичності, як-от Tailscale Serve + (`gateway.auth.allowTailscale: true`) або non-loopback + `gateway.auth.mode: "trusted-proxy"`, проходять перевірку auth для connect на основі + заголовків запиту замість `connect.params.auth.*`. +- Приватний вхідний режим `gateway.auth.mode: "none"` повністю пропускає auth за спільним секретом для connect; не відкривайте цей режим на публічному/недовіреному ingress. +- Після pairing Gateway видає **device token**, обмежений role + scopes + цього з’єднання. Він повертається в `hello-ok.auth.deviceToken` і має + зберігатися клієнтом для майбутніх підключень. +- Клієнти мають зберігати основний `hello-ok.auth.deviceToken` після будь-якого успішного підключення. -- Повторне підключення з цим **збереженим** токеном пристрою також має повторно використовувати - збережений набір схвалених областей видимості для цього токена. Це зберігає вже наданий доступ - до читання/перевірок/стану й уникає непомітного звуження повторних підключень до - вужчої неявної області лише для admin. -- Формування client-side connect auth (`selectConnectAuth` у +- Повторне підключення з цим **збереженим** device token також має повторно використовувати збережений + схвалений набір scopes для цього токена. Це зберігає вже наданий доступ для читання/перевірки/статусу + і не дає повторним підключенням непомітно звузитися до + вужчого неявного admin-only scope. +- Формування auth для connect на боці клієнта (`selectConnectAuth` у `src/gateway/client.ts`): - - `auth.password` ортогональний і завжди пересилається, якщо встановлений. - - `auth.token` заповнюється в такому порядку пріоритету: спочатку явний спільний токен, - потім явний `deviceToken`, потім збережений токен для конкретного пристрою (з ключем за + - `auth.password` ортогональний і завжди пересилається, якщо заданий. + - `auth.token` заповнюється в такому порядку пріоритету: спочатку явний shared token, + потім явний `deviceToken`, потім збережений токен для пристрою (з ключем за `deviceId` + `role`). - - `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище варіантів не розв’язав - `auth.token`. Спільний токен або будь-який розв’язаний токен пристрою його пригнічує. - - Автопідвищення збереженого токена пристрою під час одноразової - спроби повтору `AUTH_TOKEN_MISMATCH` обмежене лише **довіреними кінцевими точками** — - loopback або `wss://` із закріпленим `tlsFingerprint`. Публічний `wss://` - без pinning не підходить. -- Додаткові записи `hello-ok.auth.deviceTokens` — це токени передачі bootstrap. + - `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище варіантів не визначив + `auth.token`. Shared token або будь-який визначений device token його пригнічують. + - Автопідвищення збереженого device token під час одноразової + повторної спроби `AUTH_TOKEN_MISMATCH` дозволене **лише для довірених endpoint** — + loopback або `wss://` із зафіксованим `tlsFingerprint`. Публічний `wss://` + без фіксації не підходить. +- Додаткові записи `hello-ok.auth.deviceTokens` — це токени handoff для bootstrap. Зберігайте їх лише тоді, коли підключення використовувало bootstrap auth у довіреному транспорті, - такому як `wss://` або loopback/local pairing. -- Якщо клієнт надає **явний** `deviceToken` або явні `scopes`, цей - набір областей видимості, запитаний викликачем, лишається авторитетним; кешовані області видимості - повторно використовуються лише тоді, коли клієнт повторно використовує збережений токен для конкретного пристрою. -- Токени пристроїв можна обертати/відкликати через `device.token.rotate` і - `device.token.revoke` (потрібна область видимості `operator.pairing`). -- Видача/обертання токенів лишається обмеженою схваленим набором ролей, записаним у - записі pairing цього пристрою; обертання токена не може розширити пристрій до - ролі, яку ніколи не надав дозвіл pairing. -- Для сесій з токеном спареного пристрою керування пристроєм має власну область дії, якщо тільки - викликач також не має `operator.admin`: викликачі без admin можуть видаляти/відкликати/обертати + наприклад `wss://` або loopback/local pairing. +- Якщо клієнт передає **явний** `deviceToken` або явні `scopes`, цей + набір scopes, запитаний викликачем, залишається авторитетним; кешовані scopes повторно використовуються лише + тоді, коли клієнт повторно використовує збережений токен для пристрою. +- Device token можна ротувати/відкликати через `device.token.rotate` і + `device.token.revoke` (потрібен scope `operator.pairing`). +- Видача/ротація токенів лишається обмеженою схваленим набором role, записаним + у записі pairing цього пристрою; ротація токена не може розширити пристрій до + role, яку схвалення pairing ніколи не дозволяло. +- Для сесій із device token спареного пристрою керування пристроєм є самостійно обмеженим, якщо + викликач також не має `operator.admin`: викликачі без admin можуть видаляти/відкликати/ротувати лише **власний** запис пристрою. -- `device.token.rotate` також перевіряє запитаний набір областей видимості operator щодо - поточних областей видимості сесії викликача. Викликачі без admin не можуть обертати токен до - ширшого набору областей видимості operator, ніж вони вже мають. -- Збої автентифікації містять `error.details.code` плюс підказки щодо відновлення: - - `error.details.canRetryWithDeviceToken` (булеве значення) +- `device.token.rotate` також перевіряє запитаний набір operator scopes щодо + поточних scopes сесії викликача. Викликачі без admin не можуть ротувати токен у + ширший набір operator scopes, ніж вони вже мають. +- Збої auth містять `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`: - - Довірені клієнти можуть виконати одну обмежену повторну спробу із кешованим токеном для конкретного пристрою. - - Якщо ця повторна спроба не вдається, клієнти повинні зупинити цикли автоматичного повторного підключення та показати вказівки для дій operator. + - Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном для пристрою. + - Якщо ця повторна спроба не вдалася, клієнти мають припинити цикли автоматичного повторного підключення та показати оператору вказівки щодо необхідних дій. ## Ідентичність пристрою + pairing -- Node повинні містити стабільну ідентичність пристрою (`device.id`), похідну від - відбитка ключової пари. -- Gateway видає токени для кожного пристрою + ролі. -- Для нових `device.id` потрібні схвалення pairing, якщо не ввімкнено локальне автоматичне схвалення. +- Node мають включати стабільну ідентичність пристрою (`device.id`), похідну від + відбитка keypair. +- Gateway видають токени для кожного пристрою + role. +- Для нових device ID потрібні схвалення pairing, якщо не ввімкнено локальне автоматичне схвалення. - Автоматичне схвалення pairing зосереджене на прямих локальних loopback-підключеннях. -- OpenClaw також має вузький шлях самопідключення backend/container-local для - довірених допоміжних потоків зі спільним секретом. +- OpenClaw також має вузький шлях backend/container-local self-connect для + довірених допоміжних потоків зі shared-secret. - Підключення tailnet або LAN на тому самому хості все одно вважаються віддаленими для pairing і потребують схвалення. - Усі WS-клієнти мають включати ідентичність `device` під час `connect` (operator + node). - Control UI може пропускати її лише в таких режимах: + Control UI може не включати її лише в таких режимах: - `gateway.controlUi.allowInsecureAuth=true` для сумісності з небезпечним HTTP лише на localhost. - - успішна автентифікація operator Control UI через `gateway.auth.mode: "trusted-proxy"`. + - успішний auth operator Control UI з `gateway.auth.mode: "trusted-proxy"`. - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (аварійний режим, серйозне зниження безпеки). -- Усі з’єднання мають підписувати nonce `connect.challenge`, наданий сервером. +- Усі підключення мають підписувати наданий сервером nonce `connect.challenge`. -### Діагностика міграції автентифікації пристрою +### Діагностика міграції auth пристроїв -Для застарілих клієнтів, які все ще використовують поведінку підписування до challenge, `connect` тепер повертає +Для застарілих клієнтів, які досі використовують поведінку підпису до 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` | Корисне навантаження підпису не відповідає корисному навантаженню v2. | -| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Часова мітка підпису поза межами дозволеного зсуву. | -| `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` | Збій формату/канонізації публічного ключа. | +| Повідомлення | 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` | Навантаження підпису не відповідає навантаженню v2. | +| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Підписана позначка часу виходить за межі дозволеного зсуву. | +| `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, яке містить серверний nonce. +- Підписуйте навантаження v2, яке включає nonce сервера. - Надсилайте той самий nonce у `connect.params.device.nonce`. -- Бажане корисне навантаження підпису — `v3`, яке прив’язує `platform` і `deviceFamily` +- Бажаним навантаженням підпису є `v3`, яке прив’язує `platform` і `deviceFamily` на додачу до полів device/client/role/scopes/token/nonce. -- Застарілі підписи `v2` і далі приймаються для сумісності, але pinning метаданих +- Застарілі підписи `v2` усе ще приймаються для сумісності, але прив’язка метаданих спареного пристрою все одно керує політикою команд під час повторного підключення. -## TLS + pinning +## TLS + фіксація -- Для WS-з’єднань підтримується TLS. -- Клієнти можуть за бажанням закріпити відбиток сертифіката Gateway (див. конфігурацію `gateway.tls` +- Для WS-підключень підтримується TLS. +- Клієнти можуть за бажанням фіксувати відбиток сертифіката gateway (див. конфігурацію `gateway.tls` плюс `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`). -## Область дії +## Обсяг -Цей протокол відкриває **повний API Gateway** (status, channels, models, chat, -agent, sessions, nodes, approvals тощо). Точна поверхня визначається схемами -TypeBox у `src/gateway/protocol/schema.ts`. +Цей протокол відкриває **повний API gateway** (status, channels, models, chat, +agent, sessions, nodes, approvals тощо). Точна поверхня визначена +схемами TypeBox у `src/gateway/protocol/schema.ts`. diff --git a/docs/uk/tools/exec-approvals.md b/docs/uk/tools/exec-approvals.md index 202066bbb..180342951 100644 --- a/docs/uk/tools/exec-approvals.md +++ b/docs/uk/tools/exec-approvals.md @@ -1,70 +1,60 @@ --- read_when: - Налаштування підтверджень виконання або списків дозволених дій - - Реалізація UX підтвердження виконання в застосунку macOS + - Реалізація UX підтвердження виконання у застосунку macOS - Перегляд запитів на вихід із пісочниці та їхніх наслідків summary: Підтвердження виконання, списки дозволених дій і запити на вихід із пісочниці title: Підтвердження виконання x-i18n: - generated_at: "2026-04-21T06:27:24Z" + generated_at: "2026-04-23T17:12:54Z" model: gpt-5.4 provider: openai - source_hash: 0738108dd21e24eb6317d437b7ac693312743eddc3ec295ba62c4e60356cb33e + source_hash: 3b86106d3a145047ab2400d45aece0a66c7ec5ea4785e7538476c55477aab087 source_path: tools/exec-approvals.md workflow: 15 --- # Підтвердження виконання -Підтвердження виконання — це **запобіжний механізм companion app / host вузла** для того, щоб дозволити агенту в пісочниці запускати -команди на реальному хості (`gateway` або `node`). Думайте про це як про запобіжне блокування: -команди дозволяються лише тоді, коли збігаються політика + список дозволених дій + (необов’язкове) підтвердження користувача. -Підтвердження виконання діють **додатково** до політики інструментів і підвищеного доступу (якщо тільки elevated не встановлено в `full`, що пропускає підтвердження). -Ефективна політика — це **суворіша** з `tools.exec.*` і типових значень підтверджень; якщо поле підтверджень пропущене, використовується значення `tools.exec`. -Виконання на хості також використовує локальний стан підтверджень на цій машині. Локальне -`ask: "always"` у `~/.openclaw/exec-approvals.json` продовжує показувати запити, навіть якщо -типові значення сесії або конфігурації вимагають `ask: "on-miss"`. -Використовуйте `openclaw approvals get`, `openclaw approvals get --gateway` або -`openclaw approvals get --node `, щоб переглянути запитану політику, -джерела політики хоста та ефективний результат. -Для локальної машини `openclaw exec-policy show` показує той самий об’єднаний вигляд, а -`openclaw exec-policy set|preset` може за один крок синхронізувати локально запитану політику з -локальним файлом підтверджень хоста. Коли локальна область запитує `host=node`, -`openclaw exec-policy show` повідомляє про цю область як керовану вузлом під час виконання, а не -вдає, що локальний файл підтверджень є ефективним джерелом істини. +Підтвердження виконання — це **захисний механізм companion app / хоста node**, який дозволяє агенту в пісочниці запускати команди на реальному хості (`gateway` або `node`). Це запобіжник: команди дозволяються лише тоді, коли політика + список дозволених дій + (необов’язкове) підтвердження користувача збігаються. Підтвердження виконання накладаються **поверх** політики інструментів і підвищеного режиму доступу (крім випадку, коли elevated встановлено в `full`, що пропускає підтвердження). -Якщо UI companion app **недоступний**, будь-який запит, який потребує підтвердження, -вирішується через **резервний режим ask** (типово: deny). + +Ефективна політика є **суворішою** з `tools.exec.*` і типових значень підтверджень; якщо поле підтверджень не вказано, використовується значення `tools.exec`. Виконання на хості також використовує локальний стан підтверджень на цій машині — локальне для хоста `ask: "always"` у `~/.openclaw/exec-approvals.json` продовжить запитувати підтвердження, навіть якщо налаштування сеансу чи конфігурації вимагають `ask: "on-miss"`. + -Власні клієнти підтвердження в чаті також можуть показувати специфічні для каналу можливості в -повідомленні з очікуванням підтвердження. Наприклад, Matrix може додавати скорочення у вигляді реакцій -до запиту на підтвердження (`✅` дозволити один раз, `❌` відхилити та `♾️` дозволити завжди, коли доступно), -і при цьому залишати команди `/approve ...` у повідомленні як резервний варіант. +## Перевірка ефективної політики + +- `openclaw approvals get`, `... --gateway`, `... --node ` — показують запитану політику, джерела політики хоста та ефективний результат. +- `openclaw exec-policy show` — об’єднане подання для локальної машини. +- `openclaw exec-policy set|preset` — синхронізує локально запитану політику з локальним файлом підтверджень хоста за один крок. + +Коли локальна область видимості запитує `host=node`, `exec-policy show` повідомляє про цю область як про таку, що керується node під час виконання, замість того щоб удавати, ніби локальний файл підтверджень є джерелом істини. + +Якщо UI companion app **недоступний**, будь-який запит, який зазвичай мав би показати запит на підтвердження, обробляється через **резервний режим ask** (типово: deny). + + +Нативні клієнти підтвердження в чаті можуть додавати специфічні для каналу елементи взаємодії до повідомлення з очікуванням підтвердження. Наприклад, Matrix додає скорочення через реакції (`✅` дозволити один раз, `❌` заборонити, `♾️` дозволити завжди), водночас залишаючи команди `/approve ...` у повідомленні як запасний варіант. + ## Де це застосовується Підтвердження виконання застосовуються локально на хості виконання: - **gateway host** → процес `openclaw` на машині gateway -- **node host** → runner вузла (macOS companion app або headless host вузла) +- **node host** → раннер node (companion app macOS або headless-хост node) Примітка щодо моделі довіри: -- Виклики, автентифіковані через Gateway, вважаються довіреними операторами для цього Gateway. -- Під’єднані вузли поширюють цю можливість довіреного оператора на host вузла. -- Підтвердження виконання знижують ризик випадкового виконання, але не є межею автентифікації на рівні користувача. -- Схвалені запуски на host вузла прив’язують канонічний контекст виконання: канонічний cwd, точний argv, прив’язку env, - коли вона присутня, і зафіксований шлях до виконуваного файла, коли це застосовно. -- Для shell-скриптів і прямих викликів файлів інтерпретатора/середовища виконання OpenClaw також намагається прив’язати - один конкретний локальний файловий операнд. Якщо цей прив’язаний файл зміниться після підтвердження, але до виконання, - запуск буде відхилено замість виконання зміненого вмісту. -- Ця прив’язка файлів навмисно є best-effort, а не повною семантичною моделлю для кожного - шляху завантаження інтерпретатора/середовища виконання. Якщо режим підтвердження не може визначити рівно один конкретний локальний - файл для прив’язки, він відмовляється створювати запуск із підтвердженням, а не вдає повне покриття. +- Викликачі, автентифіковані через Gateway, є довіреними операторами для цього Gateway. +- Спарені node поширюють ці можливості довіреного оператора на хост node. +- Підтвердження виконання зменшують ризик випадкового виконання, але не є межею автентифікації на рівні користувача. +- Схвалені запуски на хості node прив’язують канонічний контекст виконання: канонічний cwd, точний argv, прив’язку env за наявності та закріплений шлях до виконуваного файла, коли це застосовно. +- Для shell-скриптів і прямих викликів файлів через інтерпретатор/середовище виконання OpenClaw також намагається прив’язати один конкретний локальний файловий операнд. Якщо цей прив’язаний файл зміниться після підтвердження, але до виконання, запуск буде заборонено замість виконання зміненого вмісту. +- Ця прив’язка до файла навмисно є best-effort, а не повною семантичною моделлю для кожного шляху завантаження інтерпретатора/середовища виконання. Якщо режим підтвердження не може визначити рівно один конкретний локальний файл для прив’язки, він відмовляється створювати запуск, підкріплений підтвердженням, замість того щоб удавати повне покриття. -Розділення в macOS: +Поділ на macOS: -- **служба host вузла** пересилає `system.run` до **застосунку macOS** через локальний IPC. +- **служба node host** пересилає `system.run` до **застосунку macOS** через локальний IPC. - **застосунок macOS** застосовує підтвердження + виконує команду в контексті UI. ## Налаштування та зберігання @@ -113,7 +103,7 @@ x-i18n: Якщо ви хочете, щоб виконання на хості працювало без запитів на підтвердження, потрібно відкрити **обидва** шари політики: - запитану політику виконання в конфігурації OpenClaw (`tools.exec.*`) -- локальну політику підтверджень хоста в `~/.openclaw/exec-approvals.json` +- локальну для хоста політику підтверджень у `~/.openclaw/exec-approvals.json` Тепер це типова поведінка хоста, якщо ви явно не зробите її суворішою: @@ -121,17 +111,17 @@ x-i18n: - `tools.exec.ask`: `off` - host `askFallback`: `full` -Важлива відмінність: +Важлива різниця: - `tools.exec.host=auto` вибирає, де виконується exec: у пісочниці, якщо вона доступна, інакше на gateway. - YOLO вибирає, як підтверджується виконання на хості: `security=full` плюс `ask=off`. -- У режимі YOLO OpenClaw не додає окремий евристичний бар’єр підтвердження для обфускації команд або шар відхилення попередньої перевірки скриптів поверх налаштованої політики виконання на хості. -- `auto` не робить маршрутизацію через gateway безкоштовним обхідним шляхом із сесії в пісочниці. Запит `host=node` для окремого виклику дозволяється з `auto`, а `host=gateway` дозволяється з `auto` лише тоді, коли активного середовища пісочниці немає. Якщо вам потрібне стабільне типове значення без `auto`, встановіть `tools.exec.host` або використовуйте `/exec host=...` явно. +- У режимі YOLO OpenClaw не додає окремий евристичний бар’єр підтвердження для маскування команд або шар відхилення script-preflight поверх налаштованої політики виконання на хості. +- `auto` не робить маршрутизацію через gateway безкоштовним обхідним шляхом із сеансу в пісочниці. Запит `host=node` на рівні окремого виклику дозволено з `auto`, а `host=gateway` дозволено з `auto` лише тоді, коли активне середовище виконання пісочниці відсутнє. Якщо вам потрібне стабільне типове значення без `auto`, встановіть `tools.exec.host` або використовуйте `/exec host=...` явно. -Якщо ви хочете більш консервативне налаштування, знову зробіть будь-який із шарів суворішим до `allowlist` / `on-miss` +Якщо вам потрібніше консервативніше налаштування, знову зробіть будь-який шар суворішим, повернувши `allowlist` / `on-miss` або `deny`. -Постійне налаштування gateway-host "ніколи не запитувати": +Постійне налаштування для gateway host у режимі "ніколи не запитувати": ```bash openclaw config set tools.exec.host gateway @@ -140,7 +130,7 @@ openclaw config set tools.exec.ask off openclaw gateway restart ``` -Потім налаштуйте файл підтверджень хоста відповідно: +Потім приведіть файл підтверджень хоста у відповідність: ```bash openclaw approvals set --stdin <<'EOF' @@ -155,22 +145,22 @@ openclaw approvals set --stdin <<'EOF' EOF ``` -Локальний скорочений спосіб для тієї ж політики gateway-host на поточній машині: +Локальний скорочений варіант для тієї самої політики gateway host на поточній машині: ```bash openclaw exec-policy preset yolo ``` -Цей локальний скорочений спосіб оновлює обидва: +Цей локальний скорочений варіант оновлює обидва: - локальні `tools.exec.host/security/ask` - локальні типові значення `~/.openclaw/exec-approvals.json` -Він навмисно є лише локальним. Якщо вам потрібно змінити підтвердження gateway-host або node-host +Він навмисно є лише локальним. Якщо вам потрібно змінити підтвердження gateway host або node host віддалено, і надалі використовуйте `openclaw approvals set --gateway` або `openclaw approvals set --node `. -Для host вузла застосуйте той самий файл підтверджень на цьому вузлі: +Для хоста node застосуйте той самий файл підтверджень на цій node: ```bash openclaw approvals set --node --stdin <<'EOF' @@ -185,18 +175,18 @@ openclaw approvals set --node --stdin <<'EOF' EOF ``` -Важливе обмеження лише для локального середовища: +Важливе обмеження лише для локальної машини: -- `openclaw exec-policy` не синхронізує підтвердження вузла +- `openclaw exec-policy` не синхронізує підтвердження node - `openclaw exec-policy set --host node` відхиляється -- підтвердження виконання вузла отримуються від вузла під час виконання, тому оновлення для вузла потрібно робити через `openclaw approvals --node ...` +- підтвердження виконання для node отримуються з node під час виконання, тому оновлення, націлені на node, потрібно виконувати через `openclaw approvals --node ...` -Скорочений спосіб лише для поточної сесії: +Скорочений варіант лише для сеансу: -- `/exec security=full ask=off` змінює лише поточну сесію. -- `/elevated full` — це аварійний скорочений спосіб, який також пропускає підтвердження виконання для цієї сесії. +- `/exec security=full ask=off` змінює лише поточний сеанс. +- `/elevated full` — це аварійний скорочений варіант, який також пропускає підтвердження виконання для цього сеансу. -Якщо файл підтверджень хоста залишається суворішим за конфігурацію, усе одно перемагає суворіша політика хоста. +Якщо файл підтверджень хоста залишається суворішим, ніж конфігурація, усе одно застосовується суворіша політика хоста. ## Параметри політики @@ -208,22 +198,22 @@ EOF ### Ask (`exec.ask`) -- **off**: ніколи не запитувати. -- **on-miss**: запитувати лише тоді, коли список дозволених дій не збігається. -- **always**: запитувати для кожної команди. -- Тривала довіра `allow-always` не пригнічує запити, коли ефективний режим ask дорівнює `always` +- **off**: ніколи не запитувати підтвердження. +- **on-miss**: запитувати підтвердження лише тоді, коли немає збігу зі списком дозволених дій. +- **always**: запитувати підтвердження для кожної команди. +- тривала довіра `allow-always` не пригнічує запити, коли ефективний режим ask — `always` ### Ask fallback (`askFallback`) -Якщо потрібне підтвердження, але UI недосяжний, fallback визначає дію: +Якщо потрібен запит на підтвердження, але жоден UI недоступний, резервний режим вирішує: - **deny**: блокувати. - **allowlist**: дозволяти лише за наявності збігу зі списком дозволених дій. - **full**: дозволяти. -### Посилений захист для inline interpreter eval (`tools.exec.strictInlineEval`) +### Посилення для inline-eval інтерпретаторів (`tools.exec.strictInlineEval`) -Коли `tools.exec.strictInlineEval=true`, OpenClaw розглядає форми inline code-eval як такі, що потребують підтвердження, навіть якщо сам бінарний файл інтерпретатора є в списку дозволених дій. +Коли `tools.exec.strictInlineEval=true`, OpenClaw розглядає форми inline code-eval як такі, що потребують лише явного підтвердження, навіть якщо сам двійковий файл інтерпретатора є у списку дозволених дій. Приклади: @@ -235,18 +225,15 @@ EOF - `lua -e` - `osascript -e` -Це defense-in-depth для завантажувачів інтерпретаторів, які не зіставляються чисто з одним стабільним файловим операндом. У strict mode: +Це defense-in-depth для завантажувачів інтерпретаторів, які не зіставляються чисто з одним стабільним файловим операндом. У strict-режимі: - ці команди все одно потребують явного підтвердження; - `allow-always` не зберігає для них нові записи списку дозволених дій автоматично. ## Список дозволених дій (для кожного агента) -Списки дозволених дій є **окремими для кожного агента**. Якщо існує кілька агентів, перемкніть агента, -якого ви редагуєте, у застосунку macOS. Шаблони — це **нечутливі до регістру glob-збіги**. -Шаблони мають розгортатися до **шляхів бінарних файлів** (записи лише з базовою назвою ігноруються). -Застарілі записи `agents.default` мігрують у `agents.main` під час завантаження. -Ланцюжки shell, наприклад `echo ok && pwd`, усе одно вимагають, щоб кожен сегмент верхнього рівня задовольняв правила списку дозволених дій. +Списки дозволених дій є **окремими для кожного агента**. Якщо існує кілька агентів, перемкніть агента, який редагується, у застосунку macOS. Шаблони — це **нечутливі до регістру glob-збіги**. Шаблони мають указувати на **шляхи до двійкових файлів** (записи лише з базовим іменем ігноруються). Застарілі записи `agents.default` переносяться до `agents.main` під час завантаження. +Shell-ланцюжки на кшталт `echo ok && pwd` усе одно вимагають, щоб кожен сегмент верхнього рівня відповідав правилам списку дозволених дій. Приклади: @@ -256,79 +243,34 @@ EOF Кожен запис списку дозволених дій відстежує: -- **id** — стабільний UUID, який використовується для ідентифікації в UI (необов’язково) -- **last used** — позначка часу останнього використання +- **id** — стабільний UUID, що використовується для ідентичності в UI (необов’язково) +- **last used** — мітка часу останнього використання - **last used command** - **last resolved path** ## Автодозвіл для CLI зі Skills Коли ввімкнено **Auto-allow skill CLIs**, виконувані файли, на які посилаються відомі Skills, -вважаються такими, що входять до списку дозволених дій на вузлах (macOS node або headless host вузла). Для цього використовується -`skills.bins` через Gateway RPC, щоб отримати список bin-файлів Skills. Вимкніть це, якщо вам потрібні суворі ручні списки дозволених дій. +вважаються такими, що входять до списку дозволених дій на node (macOS node або headless node host). Для цього використовується +`skills.bins` через Gateway RPC, щоб отримати список bin для skill. Вимкніть це, якщо вам потрібні суворі ручні списки дозволених дій. Важливі примітки щодо довіри: - Це **неявний зручний список дозволених дій**, окремий від ручних записів списку дозволених шляхів. -- Він призначений для середовищ довірених операторів, де Gateway і вузол перебувають у межах однієї моделі довіри. +- Його призначено для довірених операторських середовищ, де Gateway і node перебувають у межах однієї моделі довіри. - Якщо вам потрібна сувора явна довіра, залиште `autoAllowSkills: false` і використовуйте лише ручні записи списку дозволених шляхів. ## Safe bins (лише stdin) -`tools.exec.safeBins` визначає невеликий список **бінарних файлів лише для stdin** (наприклад, `cut`), -які можуть працювати в режимі allowlist **без** явних записів у списку дозволених дій. Safe bins відхиляють -позиційні файлові аргументи та токени, схожі на шляхи, тому вони можуть працювати лише з вхідним потоком. -Ставтеся до цього як до вузького швидкого шляху для фільтрів потоку, а не як до загального списку довіри. -**Не** додавайте бінарні файли інтерпретаторів або середовищ виконання (наприклад, `python3`, `node`, `ruby`, `bash`, `sh`, `zsh`) до `safeBins`. -Якщо команда за своєю природою може обчислювати код, виконувати підкоманди або читати файли, віддавайте перевагу явним записам у списку дозволених дій і залишайте запити на підтвердження ввімкненими. -Користувацькі safe bins мають визначати явний профіль у `tools.exec.safeBinProfiles.`. -Перевірка є детермінованою лише за формою argv (без перевірок існування файлової системи хоста), що -запобігає поведінці файлового oracle існування через різницю між allow/deny. -Файлові параметри відхиляються для типових safe bins (наприклад, `sort -o`, `sort --output`, -`sort --files0-from`, `sort --compress-program`, `sort --random-source`, -`sort --temporary-directory`/`-T`, `wc --files0-from`, `jq -f/--from-file`, -`grep -f/--file`). -Safe bins також застосовують явну політику прапорців для кожного бінарного файла для параметрів, які порушують поведінку -лише stdin (наприклад, `sort -o/--output/--compress-program` і рекурсивні прапорці grep). -Довгі параметри перевіряються fail-closed у режимі safe-bin: невідомі прапорці та неоднозначні -скорочення відхиляються. -Прапорці, відхилені профілем safe-bin: +`tools.exec.safeBins` визначає невеликий список **двійкових файлів лише для stdin** (наприклад, `cut`), які можуть працювати в режимі allowlist **без** явних записів у списку дозволених дій. Safe bins відхиляють позиційні файлові аргументи та токени, схожі на шляхи, тож вони можуть працювати лише з вхідним потоком. Сприймайте це як вузький fast-path для фільтрів потоку, а не як загальний список довіри. -[//]: # "SAFE_BIN_DENIED_FLAGS:START" - -- `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r` -- `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f` -- `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o` -- `wc`: `--files0-from` - -[//]: # "SAFE_BIN_DENIED_FLAGS:END" - -Safe bins також примусово обробляють токени argv як **буквальний текст** під час виконання (без globbing -і без розгортання `$VARS`) для сегментів лише stdin, тож шаблони на кшталт `*` або `$HOME/...` не можуть -використовуватися для прихованого читання файлів. -Safe bins також мають розгортатися з довірених каталогів бінарних файлів (системні типові значення плюс необов’язкові -`tools.exec.safeBinTrustedDirs`). Записи `PATH` ніколи не вважаються автоматично довіреними. -Типові довірені каталоги safe-bin навмисно мінімальні: `/bin`, `/usr/bin`. -Якщо ваш виконуваний файл safe-bin розташований у шляхах менеджера пакетів/користувача (наприклад -`/opt/homebrew/bin`, `/usr/local/bin`, `/opt/local/bin`, `/snap/bin`), додайте їх явно -до `tools.exec.safeBinTrustedDirs`. -Ланцюжки shell і перенаправлення не дозволяються автоматично в режимі allowlist. - -Ланцюжки shell (`&&`, `||`, `;`) дозволені, коли кожен сегмент верхнього рівня відповідає списку дозволених дій -(включно з safe bins або автодозволом Skills). Перенаправлення залишаються непідтримуваними в режимі allowlist. -Підстановка команд (`$()` / зворотні лапки) відхиляється під час розбору allowlist, зокрема всередині -подвійних лапок; використовуйте одинарні лапки, якщо вам потрібен буквальний текст `$()`. -У підтвердженнях companion app для macOS сирий текст shell, що містить керівний синтаксис shell або синтаксис розгортання -(`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`, `)`), розглядається як відсутність збігу в allowlist, якщо -лише сам бінарний файл shell не внесено до списку дозволених дій. -Для обгорток shell (`bash|sh|zsh ... -c/-lc`) перевизначення env в межах запиту зводяться до -невеликого явного списку дозволених значень (`TERM`, `LANG`, `LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`). -Для рішень allow-always у режимі allowlist відомі dispatch-обгортки -(`env`, `nice`, `nohup`, `stdbuf`, `timeout`) зберігають внутрішні шляхи до виконуваних файлів замість шляхів обгорток. -Мультиплексори shell (`busybox`, `toybox`) також розгортаються для shell-аплетів (`sh`, `ash`, -тощо), тож зберігаються внутрішні виконувані файли, а не бінарні файли мультиплексора. Якщо обгортку або -мультиплексор не можна безпечно розгорнути, запис allowlist не зберігається автоматично. -Якщо ви додаєте до списку дозволених дій інтерпретатори на кшталт `python3` або `node`, віддавайте перевагу `tools.exec.strictInlineEval=true`, щоб inline eval усе одно потребував явного підтвердження. У strict mode `allow-always` усе ще може зберігати нешкідливі виклики інтерпретатора/скрипта, але носії inline-eval автоматично не зберігаються. + +**Не** додавайте двійкові файли інтерпретаторів або середовищ виконання (наприклад, `python3`, `node`, +`ruby`, `bash`, `sh`, `zsh`) до `safeBins`. Якщо команда може обчислювати код, +виконувати підкоманди або читати файли за своєю природою, віддавайте перевагу явним записам +списку дозволених дій і залишайте ввімкненими запити на підтвердження. Власні safe bins мають визначати явний +профіль у `tools.exec.safeBinProfiles.`. + Типові safe bins: @@ -338,214 +280,282 @@ Safe bins також мають розгортатися з довірених [//]: # "SAFE_BIN_DEFAULTS:END" -`grep` і `sort` не входять до типового списку. Якщо ви вмикаєте їх явно, зберігайте явні записи allowlist для -їхніх робочих процесів, не пов’язаних лише зі stdin. -Для `grep` у режимі safe-bin передавайте шаблон через `-e`/`--regexp`; позиційна форма шаблону -відхиляється, щоб файлові операнди не можна було приховати як неоднозначні позиційні аргументи. +`grep` і `sort` не входять до типового списку. Якщо ви їх увімкнете, зберігайте явні +записи списку дозволених дій для їхніх робочих сценаріїв не через stdin. Для `grep` у режимі safe-bin +передавайте шаблон через `-e`/`--regexp`; позиційна форма шаблону відхиляється, +щоб файлові операнди не можна було протягнути як неоднозначні позиційні аргументи. -### Safe bins порівняно з allowlist + + + Перевірка є детермінованою лише за формою argv (без перевірок існування + файлової системи хоста), що запобігає поведінці oracle щодо існування файлів через + відмінності між allow/deny. Для типових safe bins параметри, орієнтовані на файли, заборонені; + довгі параметри перевіряються за принципом fail-closed (невідомі прапорці та + неоднозначні скорочення відхиляються). + + Заборонені прапорці за профілем safe-bin: + + [//]: # "SAFE_BIN_DENIED_FLAGS:START" + + - `grep`: `--dereference-recursive`, `--directories`, `--exclude-from`, `--file`, `--recursive`, `-R`, `-d`, `-f`, `-r` + - `jq`: `--argfile`, `--from-file`, `--library-path`, `--rawfile`, `--slurpfile`, `-L`, `-f` + - `sort`: `--compress-program`, `--files0-from`, `--output`, `--random-source`, `--temporary-directory`, `-T`, `-o` + - `wc`: `--files0-from` + + [//]: # "SAFE_BIN_DENIED_FLAGS:END" + + Safe bins також змушують трактувати токени argv як **буквальний текст** під + час виконання (без globbing і без розгортання `$VARS`) для сегментів лише зі + stdin, тому шаблони на кшталт `*` або `$HOME/...` не можна використати для + прихованого читання файлів. + + + + + Safe bins мають розв’язуватися з довірених каталогів двійкових файлів (системні типові + значення плюс необов’язкові `tools.exec.safeBinTrustedDirs`). Записи `PATH` ніколи не + вважаються автоматично довіреними. Типові довірені каталоги навмисно мінімальні: + `/bin`, `/usr/bin`. Якщо виконуваний файл safe-bin розташований у + шляхах менеджера пакетів або користувача (наприклад `/opt/homebrew/bin`, + `/usr/local/bin`, `/opt/local/bin`, `/snap/bin`), додайте їх явно до + `tools.exec.safeBinTrustedDirs`. + + + + Shell-ланцюжки (`&&`, `||`, `;`) дозволені, якщо кожен сегмент верхнього рівня + відповідає списку дозволених дій (включно із safe bins або автодозволом skill). + Перенаправлення, як і раніше, не підтримуються в режимі allowlist. Підстановка команд + (`$()` / backticks) відхиляється під час розбору allowlist, зокрема всередині + подвійних лапок; використовуйте одинарні лапки, якщо вам потрібен буквальний текст `$()`. + + У підтвердженнях companion app на macOS необроблений shell-текст, що містить shell-керування + або синтаксис розгортання (`&&`, `||`, `;`, `|`, `` ` ``, `$`, `<`, `>`, `(`, + `)`), вважається відсутністю збігу зі списком дозволених дій, якщо сам двійковий файл shell не + входить до списку дозволених дій. + + Для shell-обгорток (`bash|sh|zsh ... -c/-lc`) перевизначення env у межах запиту + зводяться до невеликого явного allowlist (`TERM`, `LANG`, + `LC_*`, `COLORTERM`, `NO_COLOR`, `FORCE_COLOR`). + + Для рішень `allow-always` у режимі allowlist відомі обгортки-диспетчери + (`env`, `nice`, `nohup`, `stdbuf`, `timeout`) зберігають шлях до внутрішнього виконуваного файла + замість шляху до обгортки. Shell-мультиплексори (`busybox`, `toybox`) + розгортаються для shell-аплетів (`sh`, `ash` тощо) так само. Якщо + обгортку або мультиплексор не можна безпечно розгорнути, жоден запис до списку дозволених дій + автоматично не зберігається. + + Якщо ви додаєте до списку дозволених дій інтерпретатори на кшталт `python3` або `node`, віддавайте перевагу + `tools.exec.strictInlineEval=true`, щоб inline eval усе одно вимагав + явного підтвердження. У strict-режимі `allow-always` усе ще може зберігати нешкідливі + виклики інтерпретатора/скрипту, але носії inline-eval автоматично не зберігаються. + + + + +### Safe bins проти allowlist | Тема | `tools.exec.safeBins` | Allowlist (`exec-approvals.json`) | | ---------------- | ------------------------------------------------------ | ------------------------------------------------------------ | -| Мета | Автоматично дозволяти вузькі stdin-фільтри | Явно довіряти конкретним виконуваним файлам | -| Тип збігу | Назва виконуваного файла + політика argv safe-bin | Glob-шаблон шляху до розгорнутого виконуваного файла | -| Область аргументів | Обмежується профілем safe-bin і правилами буквальних токенів | Лише збіг шляху; аргументи в іншому — ваша відповідальність | +| Мета | Автодозвіл для вузьких stdin-фільтрів | Явна довіра до конкретних виконуваних файлів | +| Тип збігу | Ім’я виконуваного файла + політика argv safe-bin | Glob-шаблон для шляху до розв’язаного виконуваного файла | +| Область аргументів | Обмежена профілем safe-bin і правилами буквальних токенів | Лише збіг за шляхом; аргументи в іншому — на вашій відповідальності | | Типові приклади | `head`, `tail`, `tr`, `wc` | `jq`, `python3`, `node`, `ffmpeg`, власні CLI | -| Найкраще застосування | Текстові перетворення з низьким ризиком у конвеєрах | Будь-який інструмент із ширшою поведінкою або побічними ефектами | +| Найкраще застосування | Низькоризикові текстові перетворення в конвеєрах | Будь-який інструмент із ширшою поведінкою або побічними ефектами | Розташування конфігурації: -- `safeBins` походить із конфігурації (`tools.exec.safeBins` або `agents.list[].tools.exec.safeBins` для окремого агента). -- `safeBinTrustedDirs` походить із конфігурації (`tools.exec.safeBinTrustedDirs` або `agents.list[].tools.exec.safeBinTrustedDirs` для окремого агента). -- `safeBinProfiles` походить із конфігурації (`tools.exec.safeBinProfiles` або `agents.list[].tools.exec.safeBinProfiles` для окремого агента). Ключі профілю для окремого агента мають пріоритет над глобальними ключами. +- `safeBins` надходить із конфігурації (`tools.exec.safeBins` або `agents.list[].tools.exec.safeBins` для окремого агента). +- `safeBinTrustedDirs` надходить із конфігурації (`tools.exec.safeBinTrustedDirs` або `agents.list[].tools.exec.safeBinTrustedDirs` для окремого агента). +- `safeBinProfiles` надходить із конфігурації (`tools.exec.safeBinProfiles` або `agents.list[].tools.exec.safeBinProfiles` для окремого агента). Ключі профілю окремого агента перевизначають глобальні ключі. - записи allowlist зберігаються в локальному для хоста `~/.openclaw/exec-approvals.json` у `agents..allowlist` (або через Control UI / `openclaw approvals allowlist ...`). -- `openclaw security audit` попереджає через `tools.exec.safe_bins_interpreter_unprofiled`, коли бінарні файли інтерпретаторів/середовищ виконання з’являються в `safeBins` без явних профілів. -- `openclaw doctor --fix` може створити каркас для відсутніх користувацьких записів `safeBinProfiles.` як `{}` (перегляньте й зробіть суворішими після цього). Бінарні файли інтерпретаторів/середовищ виконання не створюються автоматично. +- `openclaw security audit` попереджає через `tools.exec.safe_bins_interpreter_unprofiled`, коли двійкові файли інтерпретаторів/середовищ виконання з’являються в `safeBins` без явних профілів. +- `openclaw doctor --fix` може згенерувати відсутні записи `safeBinProfiles.` як `{}` (після цього перегляньте й посильте їх). Для двійкових файлів інтерпретаторів/середовищ виконання автогенерація не виконується. -Приклад користувацького профілю: +Приклад власного профілю: __OC_I18N_900005__ -Якщо ви явно додаєте `jq` до `safeBins`, OpenClaw усе одно відхиляє builtin `env` у режимі safe-bin, -щоб `jq -n env` не міг вивантажити env процесу хоста без явного шляху allowlist +Якщо ви явно додаєте `jq` до `safeBins`, OpenClaw однаково відхиляє builtin `env` у режимі safe-bin, +щоб `jq -n env` не міг вивантажити середовище процесу хоста без явного шляху в allowlist або запиту на підтвердження. ## Редагування в Control UI Використовуйте картку **Control UI → Nodes → Exec approvals**, щоб редагувати типові значення, перевизначення -для окремих агентів і allowlist. Виберіть область (типові значення або агент), налаштуйте політику, +для окремих агентів і списки дозволених дій. Виберіть область дії (Defaults або агент), змініть політику, додайте/видаліть шаблони allowlist, а потім натисніть **Save**. UI показує метадані **last used** -для кожного шаблону, щоб список було зручно підтримувати в порядку. +для кожного шаблону, щоб вам було простіше підтримувати порядок у списку. -Селектор цілі вибирає **Gateway** (локальні підтвердження) або **Node**. Вузли -мають оголошувати `system.execApprovals.get/set` (застосунок macOS або headless host вузла). -Якщо вузол ще не оголошує підтвердження виконання, відредагуйте його локальний -`~/.openclaw/exec-approvals.json` напряму. +Селектор цілі вибирає **Gateway** (локальні підтвердження) або **Node**. Node +мають оголошувати `system.execApprovals.get/set` (застосунок macOS або headless node host). +Якщо node ще не оголошує підтвердження виконання, відредагуйте її локальний +`~/.openclaw/exec-approvals.json` безпосередньо. -CLI: `openclaw approvals` підтримує редагування gateway або вузла (див. [CLI підтверджень](/cli/approvals)). +CLI: `openclaw approvals` підтримує редагування gateway або node (див. [CLI підтверджень](/cli/approvals)). ## Потік підтвердження -Коли потрібен запит на підтвердження, gateway розсилає `exec.approval.requested` клієнтам операторів. -Control UI і застосунок macOS обробляють це через `exec.approval.resolve`, а потім gateway пересилає -схвалений запит до host вузла. +Коли потрібен запит на підтвердження, gateway транслює `exec.approval.requested` клієнтам-операторам. +Control UI і застосунок macOS обробляють його через `exec.approval.resolve`, а потім gateway пересилає +схвалений запит на хост node. Для `host=node` запити на підтвердження містять канонічне корисне навантаження `systemRunPlan`. Gateway використовує -цей план як авторитетний контекст команди/cwd/сесії під час пересилання схвалених запитів `system.run`. +цей план як авторитетний контекст команди/cwd/сеансу під час пересилання схвалених запитів `system.run`. -Це важливо для затримки асинхронного підтвердження: +Це важливо через затримку асинхронного підтвердження: -- шлях виконання вузла заздалегідь готує один канонічний план +- шлях виконання node заздалегідь готує один канонічний план - запис підтвердження зберігає цей план і його метадані прив’язки -- після схвалення фінальний пересланий виклик `system.run` повторно використовує збережений план - замість того, щоб довіряти пізнішим змінам виклику -- якщо виклик змінює `command`, `rawCommand`, `cwd`, `agentId` або +- після схвалення фінальний пересланий виклик `system.run` повторно використовує збережений план, + замість того щоб довіряти пізнішим змінам від викликувача +- якщо викликач змінює `command`, `rawCommand`, `cwd`, `agentId` або `sessionKey` після створення запиту на підтвердження, gateway відхиляє пересланий запуск як невідповідність підтвердженню -## Команди інтерпретатора/середовища виконання +## Команди інтерпретаторів/середовищ виконання -Запуски інтерпретатора/середовища виконання з підтвердженням навмисно консервативні: +Запуски інтерпретаторів/середовищ виконання, підкріплені підтвердженням, навмисно є консервативними: - Точний контекст argv/cwd/env завжди прив’язується. -- Прямі форми shell-скриптів і прямих файлів середовища виконання прив’язуються best-effort до одного конкретного - локального знімка файла. -- Поширені форми обгорток менеджерів пакетів, які все ще розгортаються до одного прямого локального файла (наприклад +- Прямі форми shell-скриптів і прямі файлові форми середовища виконання прив’язуються в режимі best-effort до одного конкретного локального знімка файла. +- Поширені форми обгорток менеджерів пакетів, які все ще розв’язуються до одного прямого локального файла (наприклад `pnpm exec`, `pnpm node`, `npm exec`, `npx`), розгортаються перед прив’язкою. - Якщо OpenClaw не може визначити рівно один конкретний локальний файл для команди інтерпретатора/середовища виконання - (наприклад скрипти пакетів, форми eval, специфічні для середовища виконання ланцюжки завантажувачів або неоднозначні багатофайлові - форми), виконання з підтвердженням відхиляється замість заяв про семантичне покриття, якого насправді - немає. -- Для таких робочих процесів віддавайте перевагу пісочниці, окремій межі хоста або явному довіреному - робочому процесу allowlist/full, де оператор приймає ширшу семантику середовища виконання. + (наприклад package scripts, форми eval, специфічні для середовища виконання ланцюжки завантажувачів або неоднозначні багатофайлові + форми), виконання, підкріплене підтвердженням, відхиляється замість того, щоб заявляти про семантичне покриття, якого + насправді немає. +- Для таких сценаріїв віддавайте перевагу пісочниці, окремій межі хоста або явному + довіреному режиму allowlist/full, де оператор приймає ширшу семантику середовища виконання. -Коли потрібні підтвердження, інструмент exec одразу повертає ідентифікатор підтвердження. Використовуйте цей ідентифікатор, щоб -співвідносити подальші системні події (`Exec finished` / `Exec denied`). Якщо жодне рішення не надійде до завершення -часу очікування, запит вважається тайм-аутом підтвердження й відображається як причина відмови. +Коли потрібні підтвердження, інструмент exec негайно повертає ID підтвердження. Використовуйте цей ID для +співвіднесення з подальшими системними подіями (`Exec finished` / `Exec denied`). Якщо рішення не надійде до завершення +часу очікування, запит вважається таким, що завершився тайм-аутом підтвердження, і це показується як причина відмови. -### Поведінка доставлення followup +### Поведінка доставки подальших повідомлень -Після завершення схваленого асинхронного exec OpenClaw надсилає followup-хід `agent` у ту саму сесію. +Після завершення схваленого асинхронного exec OpenClaw надсилає подальший хід `agent` у той самий сеанс. -- Якщо існує дійсна зовнішня ціль доставлення (канал із підтримкою доставлення плюс ціль `to`), доставлення followup використовує цей канал. -- У потоках лише webchat або внутрішніх сесій без зовнішньої цілі доставлення followup залишається лише в межах сесії (`deliver: false`). -- Якщо виклик явно запитує суворе зовнішнє доставлення без зовнішнього каналу, який можна розгорнути, запит завершується помилкою `INVALID_REQUEST`. -- Якщо ввімкнено `bestEffortDeliver` і жоден зовнішній канал не можна розгорнути, доставлення знижується до режиму лише сесії замість помилки. +- Якщо існує дійсна зовнішня ціль доставки (канал доставки плюс ціль `to`), подальша доставка використовує цей канал. +- У потоках лише webchat або внутрішніх сеансах без зовнішньої цілі подальша доставка залишається лише в межах сеансу (`deliver: false`). +- Якщо викликач явно вимагає сувору зовнішню доставку без можливості розв’язати зовнішній канал, запит завершується помилкою `INVALID_REQUEST`. +- Якщо ввімкнено `bestEffortDeliver` і жоден зовнішній канал не можна розв’язати, доставка знижується до режиму лише для сеансу замість помилки. Діалог підтвердження містить: - команду + аргументи - cwd - id агента -- розгорнутий шлях до виконуваного файла +- розв’язаний шлях до виконуваного файла - метадані хоста + політики Дії: -- **Allow once** → виконати зараз -- **Always allow** → додати до allowlist + виконати +- **Allow once** → запустити зараз +- **Always allow** → додати до allowlist + запустити - **Deny** → заблокувати ## Пересилання підтверджень до чат-каналів -Ви можете пересилати запити на підтвердження exec до будь-якого чат-каналу (включно з каналами Plugin) і схвалювати -їх через `/approve`. Для цього використовується звичайний конвеєр вихідного доставлення. +Ви можете пересилати запити на підтвердження exec до будь-якого чат-каналу (включно з каналами Plugin) і підтверджувати +їх через `/approve`. Для цього використовується звичайний конвеєр вихідної доставки. Конфігурація: __OC_I18N_900006__ Відповідь у чаті: __OC_I18N_900007__ -Команда `/approve` обробляє як підтвердження exec, так і підтвердження Plugin. Якщо ID не збігається з активним підтвердженням exec, вона автоматично перевіряє підтвердження Plugin. +Команда `/approve` обробляє як підтвердження exec, так і підтвердження Plugin. Якщо ID не відповідає жодному активному підтвердженню exec, вона автоматично перевіряє підтвердження Plugin. ### Пересилання підтверджень Plugin -Пересилання підтверджень Plugin використовує той самий конвеєр доставлення, що й підтвердження exec, але має -власну незалежну конфігурацію в `approvals.plugin`. Увімкнення або вимкнення одного не впливає на інше. +Пересилання підтверджень Plugin використовує той самий конвеєр доставки, що й підтвердження exec, але має власну +незалежну конфігурацію в `approvals.plugin`. Увімкнення або вимкнення одного не впливає на інше. __OC_I18N_900008__ Форма конфігурації ідентична `approvals.exec`: `enabled`, `mode`, `agentFilter`, `sessionFilter` і `targets` працюють однаково. -Канали, які підтримують спільні інтерактивні відповіді, показують однакові кнопки підтвердження як для exec, так і для -підтверджень Plugin. Канали без спільного інтерактивного UI переходять до звичайного тексту з інструкціями `/approve`. +Канали, які підтримують спільні інтерактивні відповіді, відображають однакові кнопки підтвердження як для exec, так і для +підтверджень Plugin. Канали без спільного інтерактивного UI повертаються до простого тексту з інструкціями +`/approve`. ### Підтвердження в тому самому чаті на будь-якому каналі -Коли запит на підтвердження exec або Plugin походить із чат-поверхні, що підтримує доставлення, той самий чат -тепер може схвалити його через `/approve` типово. Це стосується таких каналів, як Slack, Matrix і -Microsoft Teams, на додаток до наявних потоків Web UI і terminal UI. +Коли запит на підтвердження exec або Plugin походить із чат-поверхні, що підтримує доставку, той самий чат +тепер за типових налаштувань може підтверджувати його через `/approve`. Це стосується таких каналів, як Slack, Matrix і +Microsoft Teams, на додачу до наявних потоків Web UI і terminal UI. -Цей спільний шлях текстових команд використовує звичайну модель автентифікації каналу для цієї розмови. Якщо +Цей спільний шлях через текстову команду використовує звичайну модель автентифікації каналу для цієї розмови. Якщо початковий чат уже може надсилати команди й отримувати відповіді, запитам на підтвердження більше не потрібен -окремий власний адаптер доставлення лише для того, щоб залишатися в стані очікування. +окремий нативний адаптер доставки лише для того, щоб залишатися активними. -Discord і Telegram також підтримують `/approve` у тому самому чаті, але ці канали все ще використовують свій -розгорнутий список approver для авторизації, навіть коли власне доставлення підтверджень вимкнено. +Discord і Telegram також підтримують `/approve` у тому самому чаті, але ці канали й далі використовують +свій розв’язаний список тих, хто може схвалювати, для авторизації, навіть коли нативну доставку підтверджень вимкнено. -Для Telegram та інших власних клієнтів підтвердження, які викликають Gateway напряму, -цей fallback навмисно обмежений помилками типу "підтвердження не знайдено". Реальна +Для Telegram та інших нативних клієнтів підтвердження, які викликають Gateway безпосередньо, +цей запасний варіант навмисно обмежено збоями типу «підтвердження не знайдено». Реальна відмова/помилка підтвердження exec не повторюється мовчки як підтвердження Plugin. -### Власне доставлення підтверджень +### Нативна доставка підтверджень -Деякі канали також можуть виступати як власні клієнти підтвердження. Власні клієнти додають approver DM, fanout до початкового чату -та специфічний для каналу інтерактивний UX підтвердження поверх спільного потоку `/approve` у тому самому чаті. +Деякі канали також можуть діяти як нативні клієнти підтвердження. Нативні клієнти додають DM для тих, хто схвалює, fanout до початкового чату +та специфічний для каналу інтерактивний UX підтвердження поверх спільного потоку `/approve` +у тому самому чаті. -Коли доступні власні картки/кнопки підтвердження, цей власний UI є основним -шляхом взаємодії для агента. Агент не повинен також дублювати звичайну команду чату -`/approve`, якщо тільки результат інструмента не вказує, що підтвердження через чат недоступні або -ручне підтвердження — єдиний шлях, що залишився. +Коли доступні нативні картки/кнопки підтвердження, цей нативний UI є основним +шляхом для агента. Агент також не повинен дублювати просту команду чату +`/approve`, якщо результат інструмента не вказує, що підтвердження через чат недоступні або +ручне підтвердження є єдиним шляхом, що залишився. Загальна модель: -- політика виконання на хості все ще визначає, чи потрібне підтвердження exec -- `approvals.exec` керує пересиланням запитів на підтвердження до інших чат-цілей -- `channels..execApprovals` керує тим, чи виступає цей канал як власний клієнт підтвердження +- політика виконання на хості все одно вирішує, чи потрібне підтвердження exec +- `approvals.exec` керує пересиланням запитів на підтвердження до інших цілей чату +- `channels..execApprovals` керує тим, чи діє цей канал як нативний клієнт підтвердження -Власні клієнти підтвердження автоматично вмикають доставлення спочатку в DM, коли виконуються всі ці умови: +Нативні клієнти підтвердження автоматично вмикають доставку спочатку в DM, коли всі наведені умови істинні: -- канал підтримує власне доставлення підтверджень -- approver можна розгорнути з явних `execApprovals.approvers` або з - документованих резервних джерел цього каналу -- `channels..execApprovals.enabled` не задано або дорівнює `"auto"` +- канал підтримує нативну доставку підтверджень +- тих, хто може схвалювати, можна визначити з явних `execApprovals.approvers` або з + задокументованих резервних джерел цього каналу +- `channels..execApprovals.enabled` не задано або має значення `"auto"` -Установіть `enabled: false`, щоб явно вимкнути власний клієнт підтвердження. Установіть `enabled: true`, щоб примусово -увімкнути його, коли approver розгортаються. Публічне доставлення до початкового чату залишається явним через +Установіть `enabled: false`, щоб явно вимкнути нативний клієнт підтвердження. Установіть `enabled: true`, щоб +примусово ввімкнути його, коли список тих, хто може схвалювати, вдається визначити. Публічна доставка до початкового чату й надалі вмикається явно через `channels..execApprovals.target`. -FAQ: [Чому для підтверджень exec у чаті існують дві конфігурації?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals) +FAQ: [Чому для підтверджень exec у чаті є дві конфігурації?](/help/faq#why-are-there-two-exec-approval-configs-for-chat-approvals) - Discord: `channels.discord.execApprovals.*` - Slack: `channels.slack.execApprovals.*` - Telegram: `channels.telegram.execApprovals.*` -Ці власні клієнти підтвердження додають маршрутизацію DM і необов’язковий fanout до каналу поверх спільного +Ці нативні клієнти підтвердження додають маршрутизацію в DM і необов’язковий fanout у каналі поверх спільного потоку `/approve` у тому самому чаті та спільних кнопок підтвердження. Спільна поведінка: -- Slack, Matrix, Microsoft Teams та подібні чати з підтримкою доставлення використовують звичайну модель автентифікації каналу +- Slack, Matrix, Microsoft Teams і подібні чати з підтримкою доставки використовують звичайну модель автентифікації каналу для `/approve` у тому самому чаті -- коли власний клієнт підтвердження вмикається автоматично, типовою власною ціллю доставлення є DM approver -- для Discord і Telegram лише розгорнуті approver можуть дозволяти або відхиляти -- approver Discord можуть бути явними (`execApprovals.approvers`) або виводитися з `commands.ownerAllowFrom` -- approver Telegram можуть бути явними (`execApprovals.approvers`) або виводитися з наявної конфігурації owner (`allowFrom`, плюс `defaultTo` для direct-message, де це підтримується) -- approver Slack можуть бути явними (`execApprovals.approvers`) або виводитися з `commands.ownerAllowFrom` -- власні кнопки Slack зберігають тип ідентифікатора підтвердження, тож ідентифікатори `plugin:` можуть розгортати підтвердження Plugin - без другого локального резервного шару Slack -- власна маршрутизація Matrix для DM/каналу та скорочення реакціями обробляють як підтвердження exec, так і Plugin; - авторизація Plugin все ще походить з `channels.matrix.dm.allowFrom` -- запитувач не зобов’язаний бути approver -- початковий чат може схвалити напряму через `/approve`, коли цей чат уже підтримує команди та відповіді -- власні кнопки підтвердження Discord маршрутизують за типом ідентифікатора підтвердження: ідентифікатори `plugin:` одразу переходять - до підтверджень Plugin, усе інше переходить до підтверджень exec -- власні кнопки підтвердження Telegram використовують той самий обмежений резервний перехід від exec до Plugin, що й `/approve` -- коли власний `target` вмикає доставлення до початкового чату, запити на підтвердження містять текст команди +- коли нативний клієнт підтвердження вмикається автоматично, типовою ціллю нативної доставки є DM тих, хто схвалює +- для Discord і Telegram лише визначені ті, хто може схвалювати, можуть схвалювати або відхиляти +- для Discord список тих, хто може схвалювати, може бути явним (`execApprovals.approvers`) або виводитися з `commands.ownerAllowFrom` +- для Telegram список тих, хто може схвалювати, може бути явним (`execApprovals.approvers`) або виводитися з наявної конфігурації owner (`allowFrom`, а також `defaultTo` для direct-message, де це підтримується) +- для Slack список тих, хто може схвалювати, може бути явним (`execApprovals.approvers`) або виводитися з `commands.ownerAllowFrom` +- нативні кнопки Slack зберігають тип id підтвердження, тому id `plugin:` можуть розв’язувати підтвердження Plugin + без другого локального для Slack резервного шару +- нативна маршрутизація DM/каналу в Matrix і скорочення через реакції обробляють як підтвердження exec, так і Plugin; + авторизація Plugin, як і раніше, надходить із `channels.matrix.dm.allowFrom` +- запитувач не зобов’язаний бути серед тих, хто може схвалювати +- початковий чат може підтвердити запит безпосередньо через `/approve`, якщо цей чат уже підтримує команди та відповіді +- нативні кнопки підтвердження Discord маршрутизуються за типом id підтвердження: id `plugin:` одразу спрямовуються + до підтверджень Plugin, усе інше — до підтверджень exec +- нативні кнопки підтвердження Telegram дотримуються того самого обмеженого резервного переходу від exec до Plugin, що й `/approve` +- коли нативний `target` вмикає доставку в початковий чат, запити на підтвердження містять текст команди - активні підтвердження exec типово спливають через 30 хвилин - якщо жоден UI оператора або налаштований клієнт підтвердження не може прийняти запит, запит переходить до `askFallback` -Для Telegram типовим є DM approver (`target: "dm"`). Ви можете перемкнутися на `channel` або `both`, якщо +Для Telegram типовим є надсилання в DM тих, хто схвалює (`target: "dm"`). Ви можете перемкнути на `channel` або `both`, якщо хочете, щоб запити на підтвердження також з’являлися в початковому чаті/темі Telegram. Для тем форуму Telegram -OpenClaw зберігає тему для запиту на підтвердження та follow-up після підтвердження. +OpenClaw зберігає тему для запиту на підтвердження і подальшого повідомлення після підтвердження. -Дивіться: +Див. також: - [Discord](/channels/discord) - [Telegram](/channels/telegram) @@ -556,7 +566,7 @@ __OC_I18N_900009__ - Режим Unix socket `0600`, токен зберігається в `exec-approvals.json`. - Перевірка peer з тим самим UID. -- Challenge/response (nonce + HMAC token + hash запиту) + короткий TTL. +- Challenge/response (nonce + HMAC token + request hash) + короткий TTL. ## Системні події @@ -566,36 +576,45 @@ __OC_I18N_900009__ - `Exec finished` - `Exec denied` -Вони публікуються в сесії агента після того, як вузол повідомляє про подію. -Підтвердження exec на gateway-host видають ті самі події життєвого циклу, коли команда завершується (і за потреби, коли виконується довше за поріг). -Exec, що керуються підтвердженням, повторно використовують ідентифікатор підтвердження як `runId` у цих повідомленнях для зручного зіставлення. +Вони публікуються в сеансі агента після того, як node повідомляє про подію. +Підтвердження exec на gateway host генерують ті самі події життєвого циклу, коли команда завершується (і, за потреби, коли виконується довше за поріг). +Exec із підтвердженням повторно використовують id підтвердження як `runId` у цих повідомленнях для зручного співвіднесення. -## Поведінка у разі відхиленого підтвердження +## Поведінка при відхиленому підтвердженні Коли асинхронне підтвердження exec відхиляється, OpenClaw не дозволяє агенту повторно використовувати -вивід будь-якого попереднього запуску тієї самої команди в сесії. Причина відмови -передається з явною вказівкою, що вивід команди недоступний, що не дає -агенту стверджувати, що є новий вивід, або повторювати відхилену команду зі +вивід будь-якого попереднього запуску тієї самої команди в межах сеансу. Причина відхилення +передається разом із явною вказівкою, що жодного виводу команди немає, що не дає +агенту стверджувати, ніби є новий вивід, або повторювати відхилену команду зі застарілими результатами попереднього успішного запуску. ## Наслідки -- **full** — потужний режим; за можливості віддавайте перевагу allowlist. -- **ask** тримає вас у курсі, водночас дозволяючи швидко схвалювати. -- Окремі для кожного агента allowlist не дають підтвердженням одного агента просочуватися до інших. -- Підтвердження застосовуються лише до запитів на виконання на хості від **авторизованих відправників**. Неавторизовані відправники не можуть викликати `/exec`. -- `/exec security=full` — це зручний параметр рівня сесії для авторизованих операторів, який навмисно пропускає підтвердження. - Щоб жорстко заблокувати виконання на хості, установіть для security підтверджень значення `deny` або забороніть інструмент `exec` через політику інструментів. - -Пов’язане: - -- [Інструмент Exec](/uk/tools/exec) -- [Режим Elevated](/uk/tools/elevated) -- [Skills](/uk/tools/skills) +- **full** — це потужний режим; по можливості віддавайте перевагу allowlist. +- **ask** тримає вас у курсі, водночас зберігаючи швидке підтвердження. +- Окремі allowlist для кожного агента не дають підтвердженням одного агента «протікати» до інших. +- Підтвердження застосовуються лише до запитів host exec від **авторизованих відправників**. Неавторизовані відправники не можуть використовувати `/exec`. +- `/exec security=full` — це зручний параметр на рівні сеансу для авторизованих операторів, який за задумом пропускає підтвердження. Щоб жорстко заблокувати host exec, установіть для security у підтвердженнях значення `deny` або забороніть інструмент `exec` через політику інструментів. ## Пов’язане -- [Exec](/uk/tools/exec) — інструмент виконання shell-команд -- [Пісочниця](/uk/gateway/sandboxing) — режими пісочниці та доступ до робочого простору -- [Безпека](/uk/gateway/security) — модель безпеки та посилення захисту -- [Пісочниця vs політика інструментів vs Elevated](/uk/gateway/sandbox-vs-tool-policy-vs-elevated) — коли що використовувати + + + Інструмент виконання shell-команд. + + + Аварійний шлях, який також пропускає підтвердження. + + + Режими пісочниці та доступ до робочого простору. + + + Модель безпеки та посилення захисту. + + + Коли варто використовувати кожен із цих механізмів. + + + Поведінка автодозволу на основі Skills. + +