diff --git a/docs/uk/web/control-ui.md b/docs/uk/web/control-ui.md index 486c7a14c..a1cc0058f 100644 --- a/docs/uk/web/control-ui.md +++ b/docs/uk/web/control-ui.md @@ -1,55 +1,55 @@ --- read_when: - Ви хочете керувати Gateway з браузера - - Ви хочете доступ через Tailnet без SSH-тунелів -summary: UI керування Gateway у браузері (чат, вузли, конфігурація) -title: UI Control + - Ви хочете доступ до Tailnet без SSH-тунелів +summary: Вебінтерфейс керування для Gateway (чат, вузли, конфігурація) +title: Інтерфейс керування x-i18n: - generated_at: "2026-04-23T23:09:16Z" + generated_at: "2026-04-24T01:39:17Z" model: gpt-5.4 provider: openai - source_hash: 63d96fb31328ac820b55231d618df96d10e26567213f6732628d65d5c0a89f31 + source_hash: 931a87479844fc5c06f2c373d3e7447c140bf6d17a5614197209e7a5f3f896bd source_path: web/control-ui.md workflow: 15 --- -UI Control — це невеликий односторінковий застосунок **Vite + Lit**, який обслуговується Gateway: +Інтерфейс керування — це невеликий односторінковий застосунок **Vite + Lit**, який обслуговується Gateway: -- типово: `http://:18789/` -- необов’язковий префікс: установіть `gateway.controlUi.basePath` (наприклад, `/openclaw`) +- за замовчуванням: `http://:18789/` +- необов’язковий префікс: встановіть `gateway.controlUi.basePath` (наприклад, `/openclaw`) -Він взаємодіє **безпосередньо з Gateway WebSocket** на тому самому порту. +Він взаємодіє **безпосередньо з WebSocket Gateway** на тому самому порту. ## Швидке відкриття (локально) -Якщо Gateway працює на тому самому комп’ютері, відкрийте: +Якщо Gateway запущено на тому самому комп’ютері, відкрийте: - [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (або [http://localhost:18789/](http://localhost:18789/)) Якщо сторінка не завантажується, спочатку запустіть Gateway: `openclaw gateway`. -Auth передається під час handshake WebSocket через: +Автентифікація передається під час WebSocket-handshake через: - `connect.params.auth.token` - `connect.params.auth.password` -- заголовки ідентичності Tailscale Serve, коли `gateway.auth.allowTailscale: true` -- заголовки ідентичності trusted-proxy, коли `gateway.auth.mode: "trusted-proxy"` +- заголовки ідентифікації Tailscale Serve, коли `gateway.auth.allowTailscale: true` +- заголовки ідентифікації trusted-proxy, коли `gateway.auth.mode: "trusted-proxy"` -Панель налаштувань dashboard зберігає токен для поточної сесії вкладки браузера -та вибраного URL gateway; паролі не зберігаються. Onboarding зазвичай -генерує токен gateway для auth зі спільним секретом під час першого підключення, але -auth за паролем теж працює, коли `gateway.auth.mode` дорівнює `"password"`. +Панель налаштувань інформаційної панелі зберігає токен для поточної сесії вкладки браузера +та вибрану URL-адресу gateway; паролі не зберігаються. Під час первинного налаштування зазвичай +генерується токен gateway для автентифікації зі спільним секретом при першому підключенні, але +автентифікація паролем також працює, коли `gateway.auth.mode` має значення `"password"`. ## Сполучення пристрою (перше підключення) -Коли ви підключаєтеся до UI Control з нового браузера або пристрою, Gateway -вимагає **одноразове схвалення сполучення** — навіть якщо ви перебуваєте в тому самому Tailnet +Коли ви підключаєтеся до Інтерфейсу керування з нового браузера або пристрою, Gateway +вимагає **одноразове підтвердження сполучення** — навіть якщо ви перебуваєте в тій самій Tailnet з `gateway.auth.allowTailscale: true`. Це захід безпеки для запобігання несанкціонованому доступу. **Що ви побачите:** "disconnected (1008): pairing required" -**Щоб схвалити пристрій:** +**Щоб підтвердити пристрій:** ```bash # List pending requests @@ -59,125 +59,126 @@ openclaw devices list openclaw devices approve ``` -Якщо браузер повторює спробу сполучення зі зміненими деталями auth (роль/scope/public -key), попередній запит у черзі замінюється, і створюється новий `requestId`. -Перед схваленням повторно запустіть `openclaw devices list`. +Якщо браузер повторно намагається виконати сполучення зі зміненими даними автентифікації (роль/області доступу/публічний +ключ), попередній запит у стані очікування замінюється, і створюється новий `requestId`. +Перед підтвердженням знову виконайте `openclaw devices list`. -Якщо браузер уже сполучений і ви змінюєте його з доступу лише для читання на -доступ для запису/адміністратора, це вважається підвищенням схвалення, а не -тихим перепідключенням. OpenClaw зберігає старе схвалення активним, блокує ширше перепідключення -і просить вас явно схвалити новий набір scope. +Якщо браузер уже сполучений і ви змінюєте його доступ із читання на +доступ запису/адміністратора, це розглядається як підвищення рівня підтвердження, а не як тихе +повторне підключення. OpenClaw залишає попереднє підтвердження активним, блокує ширше повторне підключення +і просить вас явно підтвердити новий набір областей доступу. -Після схвалення пристрій запам’ятовується і не вимагатиме повторного схвалення, якщо +Після підтвердження пристрій запам’ятовується і не потребуватиме повторного підтвердження, якщо ви не відкличете його через `openclaw devices revoke --device --role `. Див. [CLI Devices](/uk/cli/devices) для ротації токенів і відкликання. **Примітки:** -- Прямі локальні loopback-підключення браузера (`127.0.0.1` / `localhost`) - автоматично схвалюються. -- Підключення браузера через Tailnet і LAN все одно потребують явного схвалення, навіть коли - вони походять з тієї самої машини. -- Кожен профіль браузера генерує унікальний id пристрою, тож зміна браузера або +- Прямі локальні браузерні підключення через local loopback (`127.0.0.1` / `localhost`) + підтверджуються автоматично. +- Підключення браузера через Tailnet і LAN однаково вимагають явного підтвердження, навіть якщо + вони ініційовані з тієї самої машини. +- Кожен профіль браузера генерує унікальний ідентифікатор пристрою, тому зміна браузера або очищення даних браузера вимагатиме повторного сполучення. ## Особиста ідентичність (локально в браузері) -UI Control підтримує особисту ідентичність для кожного браузера (відображуване ім’я та +Інтерфейс керування підтримує особисту ідентичність для кожного браузера (відображуване ім’я та аватар), яка додається до вихідних повідомлень для атрибуції в спільних сесіях. Вона -зберігається у сховищі браузера, обмежена поточним профілем браузера і не -синхронізується з іншими пристроями та не зберігається на сервері, окрім звичайних -метаданих авторства в transcript для повідомлень, які ви фактично надсилаєте. Очищення даних сайту або -зміна браузера скидає її до порожнього стану. +зберігається в сховищі браузера, прив’язана до поточного профілю браузера і не +синхронізується з іншими пристроями та не зберігається на сервері поза звичайними +метаданими авторства в стенограмі повідомлень, які ви фактично надсилаєте. Очищення даних сайту або +зміна браузера скидає її до порожнього значення. -## Endpoint runtime-конфігурації +## Кінцева точка конфігурації runtime -UI Control отримує свої налаштування runtime з -`/__openclaw/control-ui-config.json`. Цей endpoint захищено тим самим -auth gateway, що й решту HTTP-surface: неавтентифіковані браузери не можуть -отримати його, а успішне отримання вимагає або вже дійсного токена/пароля gateway, -ідентичності Tailscale Serve або ідентичності trusted-proxy. +Інтерфейс керування отримує свої налаштування runtime з +`/__openclaw/control-ui-config.json`. Ця кінцева точка захищена тією самою +автентифікацією gateway, що й решта HTTP-поверхні: неавтентифіковані браузери не можуть +отримати її, а успішне отримання вимагає або вже дійсний токен/пароль gateway, +ідентичність Tailscale Serve, або ідентичність trusted-proxy. ## Підтримка мов -UI Control може локалізуватися під час першого завантаження на основі локалі вашого браузера. -Щоб перевизначити це пізніше, відкрийте **Overview -> Gateway Access -> Language**. Перемикач -локалі розміщено в картці Gateway Access, а не в розділі Appearance. +Інтерфейс керування може локалізуватися під час першого завантаження відповідно до локалі вашого браузера. +Щоб змінити це пізніше, відкрийте **Overview -> Gateway Access -> Language**. Перемикач +локалі розташовано в картці Gateway Access, а не в розділі Appearance. - Підтримувані локалі: `en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `tr`, `uk`, `id`, `pl`, `th` - Неанглійські переклади ліниво завантажуються в браузері. -- Вибрана локаль зберігається в сховищі браузера та повторно використовується під час майбутніх відвідувань. +- Вибрана локаль зберігається в сховищі браузера і використовується повторно під час майбутніх відвідувань. - Відсутні ключі перекладу повертаються до англійської. -## Що він може робити (сьогодні) +## Що він уміє робити (зараз) -- Чат із моделлю через Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`) -- Потокове передавання викликів інструментів + картки live-виводу інструментів у Chat (події агента) -- Канали: вбудовані плюс bundled/external plugin-канали, статус, вхід через QR та конфігурація для кожного каналу (`channels.status`, `web.login.*`, `config.patch`) +- Спілкуватися з моделлю через Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`) +- Передавати виклики інструментів + картки живого виводу інструментів у Chat (події агента) +- Канали: статус вбудованих, а також bundled/external plugin каналів, QR-вхід і конфігурація для кожного каналу (`channels.status`, `web.login.*`, `config.patch`) - Екземпляри: список присутності + оновлення (`system-presence`) -- Сесії: список + перевизначення model/thinking/fast/verbose/trace/reasoning для кожної сесії (`sessions.list`, `sessions.patch`) +- Сесії: список + перевизначення моделі/мислення/швидкого режиму/детального режиму/трасування/міркування для кожної сесії (`sessions.list`, `sessions.patch`) - Dreams: статус Dreaming, перемикач увімкнення/вимкнення та читач Dream Diary (`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`) -- Cron jobs: список/додавання/редагування/запуск/увімкнення/вимкнення + історія запусків (`cron.*`) -- Skills: статус, увімкнення/вимкнення, установлення, оновлення API-ключа (`skills.*`) -- Вузли: список + caps (`node.list`) -- Погодження exec: редагування allowlist gateway або node + політика ask для `exec host=gateway/node` (`exec.approvals.*`) +- Завдання Cron: список/додавання/редагування/запуск/увімкнення/вимкнення + історія запусків (`cron.*`) +- Skills: статус, увімкнення/вимкнення, встановлення, оновлення API-ключів (`skills.*`) +- Вузли: список + можливості (`node.list`) +- Підтвердження exec: редагування списків дозволів gateway або вузла + політика запитів для `exec host=gateway/node` (`exec.approvals.*`) - Конфігурація: перегляд/редагування `~/.openclaw/openclaw.json` (`config.get`, `config.set`) -- Конфігурація: застосування + перезапуск із перевіркою (`config.apply`) і пробудження останньої активної сесії -- Записи конфігурації включають захист base-hash, щоб запобігти перезапису одночасних редагувань -- Записи конфігурації (`config.set`/`config.apply`/`config.patch`) також попередньо перевіряють активне розв’язання SecretRef для ref у надісланому payload конфігурації; нерозв’язані активні надіслані ref відхиляються до запису -- Schema конфігурації + рендеринг форми (`config.schema` / `config.schema.lookup`, - включно з полями `title` / `description`, зіставленими підказками UI, підсумками безпосередніх дочірніх елементів, - метаданими документації на вкладених вузлах object/wildcard/array/composition, - а також schema plugin + channel, коли вони доступні); редактор Raw JSON - доступний лише тоді, коли snapshot має безпечний raw round-trip -- Якщо snapshot не може безпечно виконати raw round-trip, UI Control примусово вмикає режим Form і вимикає режим Raw для цього snapshot -- Редактор Raw JSON з дією "Reset to saved" зберігає форму, написану в raw (форматування, коментарі, макет `$include`), замість повторного рендерингу сплющеного snapshot, тож зовнішні редагування виживають після скидання, коли snapshot може безпечно виконати raw round-trip -- Структуровані значення об’єктів SecretRef відображаються лише для читання в текстових полях форми, щоб запобігти випадковому пошкодженню через перетворення object у string -- Налагодження: snapshot статусу/health/models + журнал подій + ручні RPC-виклики (`status`, `health`, `models.list`) -- Журнали: live-tail файлових журналів gateway із фільтром/експортом (`logs.tail`) -- Оновлення: запуск оновлення package/git + перезапуск (`update.run`) зі звітом про перезапуск +- Конфігурація: застосування + перезапуск із валідацією (`config.apply`) і пробудження останньої активної сесії +- Записи конфігурації включають захист base-hash, щоб запобігти перезапису паралельних змін +- Записи конфігурації (`config.set`/`config.apply`/`config.patch`) також попередньо перевіряють активне розв’язання SecretRef для посилань у надісланому корисному навантаженні конфігурації; нерозв’язані активні надіслані посилання відхиляються до запису +- Схема конфігурації + рендеринг форм (`config.schema` / `config.schema.lookup`, + включно з полями `title` / `description`, відповідними підказками UI, негайними + зведеннями дочірніх елементів, метаданими документації для вузлів nested object/wildcard/array/composition, + а також схемами plugin і каналів, коли вони доступні); редактор Raw JSON + доступний лише тоді, коли знімок має безпечний raw round-trip +- Якщо знімок не може безпечно пройти raw round-trip, Інтерфейс керування примусово вмикає режим Form і вимикає режим Raw для цього знімка +- У редакторі Raw JSON дія "Reset to saved" зберігає форму, створену в raw (форматування, коментарі, структуру `$include`), замість повторного рендерингу сплощеного знімка, тож зовнішні редагування зберігаються під час скидання, коли знімок може безпечно пройти round-trip +- Структуровані значення об’єктів SecretRef відображаються в текстових полях форми лише для читання, щоб запобігти випадковому пошкодженню під час перетворення об’єкта на рядок +- Налагодження: знімки status/health/models + журнал подій + ручні RPC-виклики (`status`, `health`, `models.list`) +- Журнали: live tail журнальних файлів gateway із фільтрацією/експортом (`logs.tail`) +- Оновлення: запуск оновлення пакета/git + перезапуск (`update.run`) зі звітом про перезапуск -Примітки до панелі Cron jobs: +Примітки до панелі завдань Cron: -- Для ізольованих завдань доставка типово виконується як підсумок announce. Ви можете перемкнути на none, якщо хочете запускати лише внутрішні прогони. -- Поля channel/target з’являються, коли вибрано announce. -- Режим Webhook використовує `delivery.mode = "webhook"` із `delivery.to`, установленим на коректний URL Webhook HTTP(S). -- Для завдань main-session доступні режими доставки webhook і none. -- Розширені елементи керування редагуванням включають delete-after-run, очищення перевизначення агента, точні/stagger-параметри cron, - перевизначення model/thinking агента та перемикачі доставки best-effort. -- Перевірка форми виконується inline з помилками на рівні полів; недійсні значення вимикають кнопку збереження, доки їх не буде виправлено. -- Установіть `cron.webhookToken`, щоб надсилати окремий bearer token; якщо його не вказано, webhook надсилається без заголовка auth. -- Застарілий fallback: збережені застарілі завдання з `notify: true` все ще можуть використовувати `cron.webhook`, доки їх не буде мігровано. +- Для ізольованих завдань доставка за замовчуванням налаштована на оголошення підсумку. Ви можете перемкнути на none, якщо хочете лише внутрішні запуски. +- Поля каналу/цілі з’являються, коли вибрано announce. +- Режим Webhook використовує `delivery.mode = "webhook"` із `delivery.to`, встановленим на дійсну URL-адресу HTTP(S) Webhook. +- Для завдань основної сесії доступні режими доставки webhook і none. +- Розширені елементи керування редагуванням включають delete-after-run, очищення перевизначення агента, точні/зміщені параметри cron, + перевизначення моделі/мислення агента та перемикачі доставки best-effort. +- Валідація форми виконується вбудовано з помилками на рівні полів; недійсні значення вимикають кнопку збереження, доки їх не буде виправлено. +- Встановіть `cron.webhookToken`, щоб надсилати окремий bearer token; якщо його не вказано, webhook надсилається без заголовка автентифікації. +- Застарілий резервний варіант: збережені застарілі завдання з `notify: true` усе ще можуть використовувати `cron.webhook`, доки їх не буде мігровано. ## Поведінка чату -- `chat.send` є **неблокувальним**: він одразу підтверджує через `{ runId, status: "started" }`, а відповідь передається потоком через події `chat`. -- Повторне надсилання з тим самим `idempotencyKey` повертає `{ status: "in_flight" }` під час виконання і `{ status: "ok" }` після завершення. -- Відповіді `chat.history` обмежені за розміром для безпеки UI. Коли записи transcript занадто великі, Gateway може обрізати довгі текстові поля, пропускати важкі блоки метаданих і замінювати надто великі повідомлення placeholder-ом (`[chat.history omitted: message too large]`). -- Зображення assistant/generated зберігаються як керовані посилання на медіа і віддаються назад через автентифіковані URL медіа Gateway, тож перезавантаження не залежить від того, чи зберігається сирий base64-payload зображення у відповіді `chat.history`. -- `chat.history` також прибирає inline-теги директив, призначені лише для відображення, з видимого тексту assistant (наприклад, `[[reply_to_*]]` і `[[audio_as_voice]]`), plain-text XML-payload викликів інструментів (включно з `...`, `...`, `...`, `...` і обрізаними блоками викликів інструментів), а також витеклі ASCII/full-width токени керування моделлю, і пропускає записи assistant, у яких весь видимий текст — це лише точний silent token `NO_REPLY` / `no_reply`. -- `chat.inject` додає assistant note до transcript сесії та транслює подію `chat` для оновлень лише UI (без запуску агента, без доставки каналом). -- Pickers моделі та мислення в заголовку чату негайно patch-ять активну сесію через `sessions.patch`; це постійні перевизначення сесії, а не параметри надсилання лише на один хід. +- `chat.send` є **неблокувальним**: він негайно підтверджує через `{ runId, status: "started" }`, а відповідь передається потоком через події `chat`. +- Повторне надсилання з тим самим `idempotencyKey` повертає `{ status: "in_flight" }` під час виконання та `{ status: "ok" }` після завершення. +- Відповіді `chat.history` обмежені за розміром для безпеки UI. Коли записи стенограми надто великі, Gateway може обрізати довгі текстові поля, пропускати великі блоки метаданих і замінювати надто великі повідомлення заповнювачем (`[chat.history omitted: message too large]`). +- Зображення assistant/generated зберігаються як керовані посилання на медіа й повертаються через автентифіковані URL-адреси медіа Gateway, тому перезавантаження не залежать від того, чи збережуться в історії чату необроблені корисні навантаження зображень base64. +- `chat.history` також прибирає з видимого тексту assistant вбудовані теги директив лише для відображення (наприклад, `[[reply_to_*]]` і `[[audio_as_voice]]`), XML-корисні навантаження викликів інструментів у форматі plain-text (зокрема `...`, `...`, `...`, `...` і обрізані блоки викликів інструментів), а також витеклі ASCII/full-width токени керування моделлю, і пропускає записи assistant, увесь видимий текст яких складається лише з точного тихого токена `NO_REPLY` / `no_reply`. +- `chat.inject` додає примітку assistant до стенограми сесії та транслює подію `chat` для оновлень лише в UI (без запуску агента, без доставки в канал). +- Перемикачі моделі та мислення в заголовку чату негайно змінюють активну сесію через `sessions.patch`; це сталі перевизначення сесії, а не параметри надсилання лише на один хід. - Зупинка: - Натисніть **Stop** (викликає `chat.abort`) - - Введіть `/stop` (або окремі фрази переривання, як-от `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop`), щоб перервати поза смугою - - `chat.abort` підтримує `{ sessionKey }` (без `runId`) для переривання всіх активних запусків для цієї сесії -- Часткове збереження при перериванні: - - Коли запуск переривається, частковий текст assistant усе ще може показуватися в UI - - Gateway зберігає частковий текст assistant, перерваний під час виконання, в історії transcript, якщо існує буферизований вивід - - Збережені записи включають метадані переривання, щоб споживачі transcript могли відрізнити часткові записи після переривання від звичайного завершеного виводу + - Поки запуск активний, звичайні подальші повідомлення ставляться в чергу. Натисніть **Steer** на повідомленні в черзі, щоб вставити це подальше повідомлення в поточний хід. + - Введіть `/stop` (або окремі фрази скасування, як-от `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop`), щоб перервати поза смугою + - `chat.abort` підтримує `{ sessionKey }` (без `runId`) для переривання всіх активних запусків цієї сесії +- Часткове збереження після переривання: + - Коли запуск перервано, частковий текст assistant усе ще може відображатися в UI + - Gateway зберігає частковий текст assistant у стенограмі, якщо існує буферизований вивід + - Збережені записи містять метадані переривання, щоб споживачі стенограми могли відрізнити часткові результати переривання від звичайного завершеного виводу ## Hosted embeds -Повідомлення assistant можуть вбудовано рендерити hosted web-content через shortcode `[embed ...]`. -Політика sandbox iframe контролюється через +Повідомлення assistant можуть вбудовано відображати hosted web content за допомогою shortcode `[embed ...]`. +Політика sandbox для iframe керується параметром `gateway.controlUi.embedSandbox`: -- `strict`: вимикає виконання скриптів усередині hosted embed -- `scripts`: дозволяє інтерактивні embed, зберігаючи ізоляцію origin; це - значення за замовчуванням і зазвичай достатнє для самодостатніх браузерних ігор/віджетів -- `trusted`: додає `allow-same-origin` поверх `allow-scripts` для same-site - документів, яким навмисно потрібні сильніші привілеї +- `strict`: вимикає виконання скриптів усередині hosted embeds +- `scripts`: дозволяє інтерактивні embeds, зберігаючи ізоляцію походження; це + значення за замовчуванням, і його зазвичай достатньо для самодостатніх browser games/widgets +- `trusted`: додає `allow-same-origin` на додачу до `allow-scripts` для same-site + документів, яким навмисно потрібні ширші привілеї Приклад: @@ -191,19 +192,19 @@ UI Control може локалізуватися під час першого з } ``` -Використовуйте `trusted` лише тоді, коли вбудованому документу справді потрібна same-origin -поведінка. Для більшості згенерованих агентом ігор та інтерактивних canvas `scripts` — +Використовуйте `trusted` лише тоді, коли вбудованому документу справді потрібна +поведінка same-origin. Для більшості згенерованих агентом ігор та інтерактивних полотен `scripts` — безпечніший вибір. -Абсолютні зовнішні URL embed `http(s)` типово залишаються заблокованими. Якщо ви -свідомо хочете, щоб `[embed url="https://..."]` завантажував сторонні сторінки, установіть +Абсолютні зовнішні URL-адреси embed `http(s)` за замовчуванням залишаються заблокованими. Якщо ви +свідомо хочете, щоб `[embed url="https://..."]` завантажував сторонні сторінки, встановіть `gateway.controlUi.allowExternalEmbedUrls: true`. ## Доступ через Tailnet (рекомендовано) ### Інтегрований Tailscale Serve (бажано) -Залишайте Gateway на loopback і дозвольте Tailscale Serve проксіювати його через HTTPS: +Тримайте Gateway на loopback і дозвольте Tailscale Serve проксувати його через HTTPS: ```bash openclaw gateway --tailscale serve @@ -213,19 +214,20 @@ openclaw gateway --tailscale serve - `https:///` (або ваш налаштований `gateway.controlUi.basePath`) -За замовчуванням запити Control UI/WebSocket Serve можуть автентифікуватися через заголовки ідентичності Tailscale -(`tailscale-user-login`), коли `gateway.auth.allowTailscale` дорівнює `true`. OpenClaw -перевіряє ідентичність, розв’язуючи адресу `x-forwarded-for` через -`tailscale whois` і зіставляючи її із заголовком, та приймає це лише тоді, коли -запит потрапляє на loopback із заголовками `x-forwarded-*` від Tailscale. Установіть +За замовчуванням запити Serve до Інтерфейсу керування/WebSocket можуть автентифікуватися через заголовки ідентичності Tailscale +(`tailscale-user-login`), коли `gateway.auth.allowTailscale` має значення `true`. OpenClaw +перевіряє ідентичність, визначаючи адресу `x-forwarded-for` через +`tailscale whois` і зіставляючи її із заголовком, і приймає такі запити лише тоді, коли +запит потрапляє на loopback із заголовками Tailscale `x-forwarded-*`. Встановіть `gateway.auth.allowTailscale: false`, якщо хочете вимагати явні облікові дані зі спільним секретом -навіть для Serve-трафіку. Тоді використовуйте `gateway.auth.mode: "token"` або +навіть для трафіку Serve. Тоді використовуйте `gateway.auth.mode: "token"` або `"password"`. -Для цього асинхронного шляху ідентичності Serve невдалі спроби auth для того самого IP клієнта -та auth scope серіалізуються до записів rate-limit. Тому одночасні хибні повторні спроби -з того самого браузера можуть показати `retry later` на другому запиті замість двох звичайних невідповідностей, що змагаються паралельно. -Безтокеновий Serve auth припускає, що host gateway є довіреним. Якщо на цьому host -може виконуватися недовірений локальний код, вимагайте auth за токеном/паролем. +Для цього асинхронного шляху ідентичності Serve невдалі спроби автентифікації для тієї самої IP-адреси клієнта +та області автентифікації серіалізуються перед записами до обмеження частоти. Тому одночасні хибні повторні спроби +з того самого браузера можуть показувати `retry later` у другому запиті +замість двох звичайних невідповідностей, що паралельно змагаються. +Автентифікація Serve без токена припускає, що хост gateway є довіреним. Якщо на цьому хості +може виконуватися недовірений локальний код, вимагайте автентифікацію токеном/паролем. ### Прив’язка до tailnet + токен @@ -237,25 +239,25 @@ openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)" - `http://:18789/` (або ваш налаштований `gateway.controlUi.basePath`) -Вставте відповідний спільний секрет у налаштуваннях UI (він надсилається як +Вставте відповідний спільний секрет у налаштування UI (він надсилається як `connect.params.auth.token` або `connect.params.auth.password`). ## Незахищений HTTP -Якщо ви відкриваєте dashboard через звичайний HTTP (`http://` або `http://`), +Якщо ви відкриваєте інформаційну панель через звичайний HTTP (`http://` або `http://`), браузер працює в **незахищеному контексті** й блокує WebCrypto. За замовчуванням -OpenClaw **блокує** підключення UI Control без ідентичності пристрою. +OpenClaw **блокує** підключення Інтерфейсу керування без ідентичності пристрою. Задокументовані винятки: -- сумісність із незахищеним HTTP лише для localhost з `gateway.controlUi.allowInsecureAuth=true` -- успішний auth оператора UI Control через `gateway.auth.mode: "trusted-proxy"` -- аварійний режим `gateway.controlUi.dangerouslyDisableDeviceAuth=true` +- сумісність незахищеного HTTP лише для localhost з `gateway.controlUi.allowInsecureAuth=true` +- успішна автентифікація оператора Інтерфейсу керування через `gateway.auth.mode: "trusted-proxy"` +- аварійний варіант `gateway.controlUi.dangerouslyDisableDeviceAuth=true` -**Рекомендоване виправлення:** використовуйте HTTPS (Tailscale Serve) або відкривайте UI локально: +**Рекомендоване виправлення:** використовуйте HTTPS (Tailscale Serve) або відкрийте UI локально: - `https:///` (Serve) -- `http://127.0.0.1:18789/` (на host gateway) +- `http://127.0.0.1:18789/` (на хості gateway) **Поведінка перемикача insecure-auth:** @@ -271,8 +273,8 @@ OpenClaw **блокує** підключення UI Control без іденти `allowInsecureAuth` — це лише локальний перемикач сумісності: -- Він дозволяє сесіям UI Control на localhost продовжуватися без ідентичності пристрою в - незахищених HTTP-контекстах. +- Він дозволяє сесіям Інтерфейсу керування на localhost продовжувати роботу без ідентичності пристрою + у незахищених HTTP-контекстах. - Він не обходить перевірки сполучення. - Він не послаблює вимоги до ідентичності віддалених пристроїв (не localhost). @@ -288,44 +290,44 @@ OpenClaw **блокує** підключення UI Control без іденти } ``` -`dangerouslyDisableDeviceAuth` вимикає перевірки ідентичності пристрою для UI Control і є -серйозним погіршенням безпеки. Поверніть налаштування назад одразу після аварійного використання. +`dangerouslyDisableDeviceAuth` вимикає перевірки ідентичності пристрою в Інтерфейсі керування і є +серйозним зниженням рівня безпеки. Після аварійного використання швидко поверніть попереднє значення. Примітка щодо trusted-proxy: -- успішний auth через trusted-proxy може допускати **операторські** сесії UI Control без +- успішна автентифікація trusted-proxy може допускати **операторські** сесії Інтерфейсу керування без ідентичності пристрою -- це **не** поширюється на сесії UI Control із роллю node -- reverse proxy на loopback того самого host усе одно не задовольняють auth trusted-proxy; див. - [Trusted Proxy Auth](/uk/gateway/trusted-proxy-auth) +- це **не** поширюється на сесії Інтерфейсу керування з роллю вузла +- reverse proxy через loopback на тому самому хості все одно не задовольняють автентифікацію trusted-proxy; див. + [Автентифікація Trusted Proxy](/uk/gateway/trusted-proxy-auth) -Див. [Tailscale](/uk/gateway/tailscale) для порад із налаштування HTTPS. +Див. [Tailscale](/uk/gateway/tailscale) для інструкцій із налаштування HTTPS. -## Content Security Policy +## Політика безпеки вмісту -UI Control постачається зі строгим правилом `img-src`: дозволені лише ресурси **same-origin** і URL `data:`. Віддалені URL `http(s)` і URL з відносним до протоколу записом відхиляються браузером і не створюють мережевих запитів. +Інтерфейс керування постачається зі суворою політикою `img-src`: дозволені лише ресурси **того самого походження** та URL `data:`. Віддалені URL `http(s)` і URL з відносним протоколом відхиляються браузером і не ініціюють мережевих запитів. Що це означає на практиці: -- Аватари й зображення, що обслуговуються за відносними шляхами (наприклад, `/avatars/`), усе ще рендеряться. -- Inline URL `data:image/...` усе ще рендеряться (це корисно для payload у межах протоколу). -- Віддалені URL аватарів, які надходять із метаданих каналів, видаляються helper-ами аватарів UI Control і замінюються вбудованим logo/badge, тож скомпрометований або зловмисний канал не може примусити браузер оператора виконувати довільні віддалені запити на зображення. +- Аватари та зображення, що обслуговуються за відносними шляхами (наприклад `/avatars/`), як і раніше відображаються. +- Вбудовані URL `data:image/...` як і раніше відображаються (це корисно для корисних навантажень усередині протоколу). +- Віддалені URL аватарів, що надходять із метаданих каналу, видаляються в допоміжних функціях аватарів Інтерфейсу керування і замінюються вбудованим логотипом/значком, тому скомпрометований або зловмисний канал не може змусити браузер оператора виконувати довільні віддалені запити зображень. -Щоб отримати цю поведінку, нічого змінювати не потрібно — вона завжди ввімкнена й не налаштовується. +Щоб отримати таку поведінку, нічого змінювати не потрібно — вона завжди ввімкнена і не налаштовується. -## Auth маршруту avatar +## Автентифікація маршруту аватара -Коли налаштовано auth gateway, endpoint аватарів UI Control вимагає той самий токен gateway, що й решта API: +Коли налаштовано автентифікацію gateway, кінцева точка аватара Інтерфейсу керування вимагає той самий токен gateway, що й решта API: -- `GET /avatar/` повертає зображення аватара лише автентифікованим викликам. `GET /avatar/?meta=1` повертає метадані аватара за тим самим правилом. -- Неавтентифіковані запити до обох маршрутів відхиляються (аналогічно до сусіднього маршруту assistant-media). Це запобігає витоку ідентичності агента через маршрут avatar на host, які загалом захищені. -- Сам UI Control пересилає токен gateway як bearer-заголовок під час отримання аватарів і використовує автентифіковані blob URL, тому зображення все одно рендериться в dashboard. +- `GET /avatar/` повертає зображення аватара лише автентифікованим викликачам. `GET /avatar/?meta=1` повертає метадані аватара за тим самим правилом. +- Неавтентифіковані запити до будь-якого з цих маршрутів відхиляються (так само, як і до сусіднього маршруту assistant-media). Це запобігає витоку ідентичності агента через маршрут аватара на хостах, які інакше захищені. +- Сам Інтерфейс керування пересилає токен gateway як bearer-заголовок під час отримання аватарів і використовує автентифіковані blob URL, тож зображення все одно відображається в інформаційних панелях. -Якщо ви вимкнете auth gateway (не рекомендовано на спільних host), маршрут avatar також стане неавтентифікованим — відповідно до решти gateway. +Якщо ви вимкнете автентифікацію gateway (не рекомендується на спільних хостах), маршрут аватара також стане неавтентифікованим, відповідно до решти gateway. ## Збирання UI -Gateway обслуговує статичні файли з `dist/control-ui`. Зберіть їх командою: +Gateway обслуговує статичні файли з `dist/control-ui`. Зберіть їх за допомогою: ```bash pnpm ui:build @@ -343,22 +345,22 @@ OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build pnpm ui:dev ``` -Потім вкажіть UI на URL WS вашого Gateway (наприклад, `ws://127.0.0.1:18789`). +Потім вкажіть у UI URL вашого Gateway WS (наприклад, `ws://127.0.0.1:18789`). ## Налагодження/тестування: dev server + віддалений Gateway -UI Control — це статичні файли; ціль WebSocket налаштовується і може -відрізнятися від HTTP origin. Це зручно, коли ви хочете локальний Vite dev server, -але Gateway працює в іншому місці. +Інтерфейс керування — це статичні файли; ціль WebSocket налаштовується і може +відрізнятися від HTTP-походження. Це зручно, коли ви хочете мати dev server Vite +локально, але Gateway працює деінде. 1. Запустіть dev server UI: `pnpm ui:dev` -2. Відкрийте URL на кшталт: +2. Відкрийте URL такого вигляду: ```text http://localhost:5173/?gatewayUrl=ws://:18789 ``` -Необов’язковий одноразовий auth (за потреби): +Необов’язкова одноразова автентифікація (за потреби): ```text http://localhost:5173/?gatewayUrl=wss://:18789#token= @@ -366,19 +368,20 @@ http://localhost:5173/?gatewayUrl=wss://:18789#token=:18789#token=