docs/docs/uk/web/control-ui.md
2026-05-04 09:22:38 +00:00

51 KiB
Raw Blame History

read_when sidebarTitle summary title x-i18n
Ви хочете керувати Gateway із браузера
Вам потрібен доступ до Tailnet без SSH-тунелів
Control UI Браузерний інтерфейс керування для Gateway (чат, вузли, конфігурація) Інтерфейс керування
generated_at model provider source_hash source_path workflow
2026-05-04T09:20:47Z gpt-5.5 openai 4b68b5203b369de6a3354a7e7442ee38ee790875b2d7054b0c8ec997098fd9de web/control-ui.md 16

Control UI — це невеликий односторінковий застосунок Vite + Lit, який обслуговує Gateway:

  • типово: http://<host>:18789/
  • необов’язковий префікс: задайте gateway.controlUi.basePath (наприклад, /openclaw)

Він взаємодіє напряму з Gateway WebSocket на тому самому порту.

Швидке відкриття (локально)

Якщо Gateway запущено на тому самому комп’ютері, відкрийте:

Якщо сторінка не завантажується, спершу запустіть Gateway: openclaw gateway.

Автентифікація передається під час WebSocket-рукостискання через:

  • connect.params.auth.token
  • connect.params.auth.password
  • заголовки ідентичності Tailscale Serve, коли gateway.auth.allowTailscale: true
  • заголовки ідентичності довіреного проксі, коли gateway.auth.mode: "trusted-proxy"

Панель налаштувань дашборда зберігає токен для поточної сесії вкладки браузера й вибраної URL-адреси gateway; паролі не зберігаються. Онбординг зазвичай генерує gateway-токен для автентифікації зі спільним секретом під час першого підключення, але автентифікація паролем також працює, коли gateway.auth.mode має значення "password".

Сполучення пристрою (перше підключення)

Коли ви підключаєтеся до Control UI з нового браузера або пристрою, Gateway зазвичай вимагає одноразового схвалення сполучення. Це захід безпеки для запобігання несанкціонованому доступу.

Що ви побачите: "disconnected (1008): pairing required"

```bash openclaw devices list ``` ```bash openclaw devices approve ```

Якщо браузер повторює спробу сполучення зі зміненими даними автентифікації (роль/області доступу/публічний ключ), попередній запит, що очікує, замінюється, і створюється новий requestId. Перед схваленням повторно виконайте openclaw devices list.

Якщо браузер уже сполучено і ви змінюєте доступ із читання на запис/admin, це вважається підвищенням схвалення, а не тихим повторним підключенням. OpenClaw залишає старе схвалення активним, блокує повторне підключення з ширшими правами та просить вас явно схвалити новий набір областей доступу.

Після схвалення пристрій запам’ятовується і не потребуватиме повторного схвалення, якщо ви не відкличете його за допомогою openclaw devices revoke --device <id> --role <role>. Див. CLI пристроїв щодо ротації та відкликання токенів.

- Прямі браузерні підключення через local loopback (`127.0.0.1` / `localhost`) схвалюються автоматично. - Tailscale Serve може пропускати цикл сполучення для операторських сесій Control UI, коли `gateway.auth.allowTailscale: true`, ідентичність Tailscale підтверджено, а браузер надає ідентичність свого пристрою. - Прямі прив’язки Tailnet, браузерні підключення з LAN і профілі браузера без ідентичності пристрою все одно потребують явного схвалення. - Кожен профіль браузера генерує унікальний ID пристрою, тому перемикання браузерів або очищення даних браузера вимагатиме повторного сполучення.

Особиста ідентичність (локальна для браузера)

Control UI підтримує персональну ідентичність для кожного браузера (відображуване ім’я та аватар), яка додається до вихідних повідомлень для атрибуції у спільних сесіях. Вона зберігається в сховищі браузера, обмежена поточним профілем браузера, не синхронізується з іншими пристроями і не зберігається на сервері, окрім звичайних метаданих авторства транскрипту для повідомлень, які ви фактично надсилаєте. Очищення даних сайту або перемикання браузерів скидає її до порожнього стану.

Та сама локальна для браузера схема застосовується до перевизначення аватара асистента. Завантажені аватари асистента накладаються на визначену gateway ідентичність лише в локальному браузері й ніколи не проходять туди й назад через config.patch. Спільне поле конфігурації ui.assistant.avatar все ще доступне для клієнтів не з UI, які записують поле напряму (наприклад, скриптові gateway або власні дашборди).

Кінцева точка runtime-конфігурації

Control UI отримує свої runtime-налаштування з /__openclaw/control-ui-config.json. Цю кінцеву точку захищено тією самою автентифікацією gateway, що й решту HTTP-поверхні: неавтентифіковані браузери не можуть її отримати, а успішне отримання потребує або вже дійсного gateway-токена/пароля, або ідентичності Tailscale Serve, або ідентичності довіреного проксі.

Підтримка мов

Control UI може локалізуватися під час першого завантаження на основі локалі вашого браузера. Щоб змінити це пізніше, відкрийте Огляд -> Доступ до Gateway -> Мова. Вибір локалі розміщено на картці Доступ до Gateway, а не в розділі Вигляд.

  • Підтримувані локалі: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
  • Неанглійські переклади ліниво завантажуються в браузері.
  • Вибрана локаль зберігається в сховищі браузера й повторно використовується під час майбутніх відвідувань.
  • Відсутні ключі перекладу повертаються до англійської.

Переклади документації генеруються для того самого набору неанглійських локалей, але вбудований перемикач мов сайту документації Mintlify обмежений кодами локалей, які приймає Mintlify. Документація тайською (th) і перською (fa) все ще генерується в publish-репозиторії; вона може не з’являтися в цьому перемикачі, доки Mintlify не підтримуватиме ці коди.

Теми вигляду

Панель Вигляд зберігає вбудовані теми Claw, Knot і Dash, а також один локальний для браузера слот імпорту tweakcn. Щоб імпортувати тему, відкрийте редактор tweakcn, виберіть або створіть тему, натисніть Поширити і вставте скопійоване посилання на тему у Вигляд. Імпортер також приймає URL-адреси реєстру https://tweakcn.com/r/themes/<id>, URL-адреси редактора на кшталт https://tweakcn.com/editor/theme?theme=amethyst-haze, відносні шляхи /themes/<id>, сирі ID тем і типові назви тем, як-от amethyst-haze.

Імпортовані теми зберігаються лише в поточному профілі браузера. Вони не записуються в конфігурацію gateway і не синхронізуються між пристроями. Заміна імпортованої теми оновлює один локальний слот; очищення перемикає активну тему назад на Claw, якщо було вибрано імпортовану тему.

Що він може робити (сьогодні)

- Спілкуватися з моделлю через Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`). - Розмовляти через браузерні realtime-сесії. OpenAI використовує прямий WebRTC, Google Live використовує обмежений одноразовий браузерний токен через WebSocket, а голосові realtime plugins, що працюють лише на backend, використовують relay-транспорт Gateway. Relay зберігає облікові дані провайдера на Gateway, поки браузер транслює мікрофонний PCM через RPC `talk.realtime.relay*` і надсилає виклики інструмента `openclaw_agent_consult` назад через `chat.send` для більшої налаштованої моделі OpenClaw. - Потоково передавати виклики інструментів і live-картки виводу інструментів у Chat (події агента). - Канали: статус вбудованих і bundled/external plugin-каналів, QR-вхід і конфігурація для кожного каналу (`channels.status`, `web.login.*`, `config.patch`). - Екземпляри: список присутності + оновлення (`system-presence`). - Сесії: список + перевизначення моделі/thinking/fast/verbose/trace/reasoning для кожної сесії (`sessions.list`, `sessions.patch`). - Dreams: статус dreaming, перемикач увімкнення/вимкнення та читач Dream Diary (`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`). - Завдання Cron: список/додавання/редагування/запуск/увімкнення/вимкнення + історія запусків (`cron.*`). - Skills: статус, увімкнення/вимкнення, встановлення, оновлення API-ключів (`skills.*`). - Nodes: список + caps (`node.list`). - Схвалення exec: редагування allowlist gateway або node + політика запитів для `exec host=gateway/node` (`exec.approvals.*`). - Перегляд/редагування `~/.openclaw/openclaw.json` (`config.get`, `config.set`). - Застосування + перезапуск із валідацією (`config.apply`) і пробудження останньої активної сесії. - Записи містять захист base-hash, щоб запобігти перезапису паралельних редагувань. - Записи (`config.set`/`config.apply`/`config.patch`) попередньо перевіряють розв’язання активних SecretRef для refs у надісланому payload конфігурації; нерозв’язані активні надіслані refs відхиляються до запису. - Schema + рендеринг форми (`config.schema` / `config.schema.lookup`, зокрема поля `title` / `description`, відповідні підказки UI, зведення безпосередніх дочірніх елементів, метадані документації на вкладених object/wildcard/array/composition nodes, а також plugin + channel schemas, коли доступні); редактор Raw JSON доступний лише тоді, коли snapshot має безпечний сирий round-trip. - Якщо snapshot не може безпечно виконати raw text round-trip, Control UI примусово вмикає режим Form і вимикає режим Raw для цього snapshot. - Редактор Raw JSON "Reset to saved" зберігає raw-authored форму (форматування, коментарі, структуру `$include`) замість повторного рендерингу сплющеного snapshot, тож зовнішні редагування переживають reset, коли snapshot може безпечно виконати round-trip. - Структуровані значення об’єктів SecretRef відображаються лише для читання в текстових полях форми, щоб запобігти випадковому пошкодженню object-to-string. - Debug: snapshot статусу/здоров’я/моделей + журнал подій + ручні RPC-виклики (`status`, `health`, `models.list`). - Журнал подій містить часи refresh/RPC Control UI, а також записи чутливості браузера для довгих кадрів анімації або довгих завдань, коли браузер надає ці типи записів PerformanceObserver. - Logs: live tail файлових журналів gateway із фільтром/експортом (`logs.tail`). - Update: запуск оновлення package/git + перезапуск (`update.run`) зі звітом про перезапуск, потім опитування `update.status` після повторного підключення, щоб перевірити версію запущеного gateway. - Для ізольованих завдань доставлення типово оголошує зведення. Ви можете перемкнути на none, якщо потрібні лише внутрішні запуски. - Поля каналу/цілі з’являються, коли вибрано announce. - Режим Webhook використовує `delivery.mode = "webhook"` з `delivery.to`, встановленим на дійсну HTTP(S) webhook URL-адресу. - Для завдань main-session доступні режими доставлення webhook і none. - Розширені елементи керування редагуванням містять delete-after-run, clear agent override, точні/stagger параметри cron, перевизначення agent model/thinking і best-effort перемикачі доставлення. - Валідація форми вбудована з помилками на рівні поля; недійсні значення вимикають кнопку збереження, доки їх не виправлено. - Задайте `cron.webhookToken`, щоб надсилати окремий bearer token; якщо пропущено, webhook надсилається без заголовка auth. - Застарілий fallback: збережені legacy-завдання з `notify: true` все ще можуть використовувати `cron.webhook`, доки їх не мігровано.

Поведінка Chat

- `chat.send` є **неблокувальним**: він одразу підтверджує отримання через `{ runId, status: "started" }`, а відповідь передається потоком через події `chat`. - Завантаження в чат приймають зображення та невідеофайли. Зображення зберігають нативний шлях до зображення; інші файли зберігаються як керовані медіа й показуються в історії як посилання на вкладення. - Повторне надсилання з тим самим `idempotencyKey` повертає `{ status: "in_flight" }` під час виконання та `{ status: "ok" }` після завершення. - Відповіді `chat.history` мають обмеження розміру для безпеки UI. Коли записи стенограми завеликі, Gateway може обрізати довгі текстові поля, пропускати важкі блоки метаданих і замінювати завеликі повідомлення заповнювачем (`[chat.history omitted: message too large]`). - Зображення помічника/згенеровані зображення зберігаються як керовані посилання на медіа й повертаються через автентифіковані медіа-URL Gateway, тож перезавантаження не залежать від того, чи залишаються сирі base64-навантаження зображень у відповіді історії чату. - `chat.history` також прибирає з видимого тексту помічника лише-для-відображення вбудовані теги директив (наприклад `reply_to_*` і `audio_as_voice`), plain-text XML-навантаження викликів інструментів (зокрема `...`, `...`, `...`, `...` і обрізані блоки викликів інструментів), а також витоки ASCII/повноширинних керувальних токенів моделі, і пропускає записи помічника, весь видимий текст яких є лише точним тихим токеном `NO_REPLY` / `no_reply`. - Під час активного надсилання та фінального оновлення історії подання чату зберігає видимими локальні оптимістичні повідомлення користувача/помічника, якщо `chat.history` ненадовго повертає старіший знімок; канонічна стенограма замінює ці локальні повідомлення, щойно історія Gateway наздоганяє. - Живі події `chat` є станом доставлення, тоді як `chat.history` перебудовується з довговічної стенограми сесії. Після фінальних подій інструментів Control UI перезавантажує історію й об’єднує лише невеликий оптимістичний хвіст; межу стенограми задокументовано у [WebChat](/uk/web/webchat). - `chat.inject` додає нотатку помічника до стенограми сесії та транслює подію `chat` для оновлень лише UI (без запуску агента й без доставлення каналом). - Заголовок чату показує фільтр агента перед вибирачем сесії, а вибирач сесії обмежується вибраним агентом. Перемикання агентів показує лише сесії, пов’язані з цим агентом, і повертається до головної сесії цього агента, якщо в нього ще немає збережених сесій панелі керування. - На настільних ширинах елементи керування чатом залишаються в одному компактному рядку й згортаються під час прокручування стенограми вниз; прокручування вгору, повернення на початок або досягнення низу відновлює елементи керування. - Послідовні дублікати лише текстових повідомлень відображаються як одна бульбашка з лічильником. Повідомлення, що містять зображення, вкладення, вивід інструментів або попередні перегляди canvas, не згортаються. - Вибирачі моделі й мислення в заголовку чату негайно оновлюють активну сесію через `sessions.patch`; це сталі перевизначення сесії, а не параметри надсилання лише на один хід. - Введення `/new` у Control UI створює й перемикає на таку саму нову сесію панелі керування, як New Chat. Введення `/reset` зберігає явне скидання Gateway на місці для поточної сесії. - Вибирач моделі чату запитує налаштоване подання моделей Gateway. Якщо наявний `agents.defaults.models`, цей список дозволених моделей керує вибирачем. Інакше вибирач показує явні записи `models.providers.*.models` плюс провайдерів із придатною автентифікацією. Повний каталог залишається доступним через налагоджувальний RPC `models.list` з `view: "all"`. - Коли свіжі звіти використання сесії Gateway показують високий тиск контексту, область композитора чату показує повідомлення про контекст і, на рекомендованих рівнях Compaction, компактну кнопку, що запускає звичайний шлях Compaction сесії. Застарілі знімки токенів приховуються, доки Gateway знову не повідомить свіже використання. Режим розмови використовує зареєстрованого realtime-провайдера голосу. Налаштуйте OpenAI через `talk.provider: "openai"` плюс `talk.providers.openai.apiKey`, або налаштуйте Google через `talk.provider: "google"` плюс `talk.providers.google.apiKey`; конфігурацію realtime-провайдера Voice Call усе ще можна повторно використати як резервну. Браузер ніколи не отримує стандартний API-ключ провайдера. OpenAI отримує ефемерний секрет клієнта Realtime для WebRTC. Google Live отримує одноразовий обмежений auth-токен Live API для браузерної WebSocket-сесії, з інструкціями та деклараціями інструментів, зафіксованими в токені Gateway. Провайдери, що надають лише backend realtime bridge, працюють через relay-транспорт Gateway, тож облікові дані й vendor-сокети залишаються на сервері, тоді як браузерне аудіо рухається через автентифіковані RPC Gateway. Промпт Realtime-сесії збирає Gateway; `talk.realtime.session` не приймає перевизначень інструкцій, наданих викликачем.
У композиторі Chat елемент керування Talk — це кнопка з хвилями поруч із кнопкою диктування мікрофоном. Коли Talk запускається, рядок стану композитора показує `Connecting Talk...`, потім `Talk live`, поки аудіо під’єднане, або `Asking OpenClaw...`, поки realtime-виклик інструмента консультується з налаштованою більшою моделлю через `chat.send`.

Maintainer live smoke: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts` перевіряє OpenAI browser WebRTC SDP exchange, Google Live constrained-token browser WebSocket setup і Gateway relay browser adapter із фальшивим медіа мікрофона. Команда друкує лише стан провайдера й не логує секрети.
- Натисніть **Зупинити** (викликає `chat.abort`). - Поки запуск активний, звичайні подальші повідомлення стають у чергу. Натисніть **Скерувати** на повідомленні в черзі, щоб вставити це подальше повідомлення в поточний хід. - Введіть `/stop` (або окремі фрази переривання, як-от `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop`), щоб перервати поза основним потоком. - `chat.abort` підтримує `{ sessionKey }` (без `runId`), щоб перервати всі активні запуски для цієї сесії. - Коли запуск перервано, частковий текст помічника все ще може показуватися в UI. - Gateway зберігає перерваний частковий текст помічника в історії стенограми, коли є буферизований вивід. - Збережені записи містять метадані переривання, щоб споживачі стенограми могли відрізняти перервані часткові дані від звичайного виводу завершення.

Встановлення PWA та web push

Control UI постачається з manifest.webmanifest і service worker, тому сучасні браузери можуть встановлювати його як окрему PWA. Web Push дає Gateway змогу будити встановлену PWA сповіщеннями, навіть коли вкладка або вікно браузера не відкриті.

Поверхня Що робить
ui/public/manifest.webmanifest Маніфест PWA. Браузери пропонують "Install app", щойно він доступний.
ui/public/sw.js Service worker, що обробляє події push і кліки сповіщень.
push/vapid-keys.json (у каталозі стану OpenClaw) Автоматично згенерована пара ключів VAPID, що використовується для підписування навантажень Web Push.
push/web-push-subscriptions.json Збережені endpoint-и підписок браузера.

Перевизначте пару ключів VAPID через змінні середовища в процесі Gateway, коли потрібно зафіксувати ключі (для multi-host розгортань, ротації секретів або тестів):

  • OPENCLAW_VAPID_PUBLIC_KEY
  • OPENCLAW_VAPID_PRIVATE_KEY
  • OPENCLAW_VAPID_SUBJECT (за замовчуванням mailto:openclaw@localhost)

Control UI використовує ці scope-gated методи Gateway для реєстрації та тестування браузерних підписок:

  • push.web.vapidPublicKey — отримує активний публічний ключ VAPID.
  • push.web.subscribe — реєструє endpoint плюс keys.p256dh/keys.auth.
  • push.web.unsubscribe — видаляє зареєстрований endpoint.
  • push.web.test — надсилає тестове сповіщення до підписки викликача.
Web Push незалежний від шляху ретрансляції iOS APNS (див. [Конфігурація](/uk/gateway/configuration) для push із підтримкою ретрансляції) і наявного методу `push.test`, які націлені на нативне mobile pairing.

Розміщені вбудовування

Повідомлення помічника можуть відображати розміщений вебвміст inline за допомогою shortcode [embed ...]. Політика sandbox для iframe керується gateway.controlUi.embedSandbox:

Вимикає виконання скриптів усередині розміщених вбудовувань. Дозволяє інтерактивні вбудовування, зберігаючи ізоляцію origin; це значення за замовчуванням і зазвичай його достатньо для автономних браузерних ігор/віджетів. Додає `allow-same-origin` поверх `allow-scripts` для same-site документів, яким навмисно потрібні сильніші привілеї.

Приклад:

{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
Використовуйте `trusted` лише тоді, коли вбудований документ справді потребує same-origin поведінки. Для більшості згенерованих агентом ігор та інтерактивних canvas `scripts` є безпечнішим вибором.

Абсолютні зовнішні http(s) URL вбудовувань залишаються заблокованими за замовчуванням. Якщо ви навмисно хочете, щоб [embed url="https://..."] завантажував сторонні сторінки, встановіть gateway.controlUi.allowExternalEmbedUrls: true.

Ширина повідомлень чату

Згруповані повідомлення чату використовують читабельну стандартну максимальну ширину. Розгортання на широких моніторах можуть перевизначити її без патчення bundled CSS, встановивши gateway.controlUi.chatMessageMaxWidth:

{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}

Значення перевіряється перед тим, як потрапити до браузера. Підтримувані значення включають прості довжини й відсотки, як-от 960px або 82%, а також обмежені вирази ширини min(...), max(...), clamp(...), calc(...) і fit-content(...).

Доступ через tailnet (рекомендовано)

Тримайте Gateway на loopback і дозвольте Tailscale Serve проксувати його через HTTPS:
```bash
openclaw gateway --tailscale serve
```

Відкрийте:

- `https://<magicdns>/` (або налаштований `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. Для операторських сесій Control UI з ідентичністю браузерного пристрою цей перевірений шлях Serve також пропускає round trip device-pairing; браузери без пристрою й з’єднання node-role все ще проходять звичайні перевірки пристрою. Встановіть `gateway.auth.allowTailscale: false`, якщо хочете вимагати явні облікові дані shared-secret навіть для трафіку Serve. Потім використовуйте `gateway.auth.mode: "token"` або `"password"`.

Для цього асинхронного шляху ідентичності Serve невдалі спроби автентифікації для тієї самої IP-адреси клієнта й auth scope серіалізуються перед записами rate-limit. Тому одночасні хибні повторні спроби з того самого браузера можуть показати `retry later` на другому запиті замість двох звичайних невідповідностей, що змагаються паралельно.

<Warning>
Tokenless Serve auth припускає, що хост gateway є довіреним. Якщо на цьому хості може виконуватися недовірений локальний код, вимагайте token/password auth.
</Warning>
```bash openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)" ```
Потім відкрийте:

- `http://<tailscale-ip>:18789/` (або налаштований `gateway.controlUi.basePath`)

Вставте відповідний спільний секрет у налаштування UI (надсилається як `connect.params.auth.token` або `connect.params.auth.password`).

Незахищений HTTP

Якщо ви відкриваєте панель керування через звичайний HTTP (http://<lan-ip> або http://<tailscale-ip>), браузер працює в незахищеному контексті та блокує WebCrypto. За замовчуванням OpenClaw блокує підключення Control UI без ідентичності пристрою.

Задокументовані винятки:

  • сумісність незахищеного HTTP лише для localhost із gateway.controlUi.allowInsecureAuth=true
  • успішна автентифікація оператора Control UI через gateway.auth.mode: "trusted-proxy"
  • аварійний режим gateway.controlUi.dangerouslyDisableDeviceAuth=true

Рекомендоване виправлення: використовуйте HTTPS (Tailscale Serve) або відкрийте UI локально:

  • https://<magicdns>/ (Serve)
  • http://127.0.0.1:18789/ (на хості Gateway)
```json5 { gateway: { controlUi: { allowInsecureAuth: true }, bind: "tailnet", auth: { mode: "token", token: "replace-me" }, }, } ```
`allowInsecureAuth` — це лише локальний перемикач сумісності:

- Він дозволяє сесіям Control UI на localhost продовжувати роботу без ідентичності пристрою в незахищених HTTP-контекстах.
- Він не обходить перевірки сполучення.
- Він не послаблює вимоги до ідентичності віддалених (не localhost) пристроїв.
```json5 { gateway: { controlUi: { dangerouslyDisableDeviceAuth: true }, bind: "tailnet", auth: { mode: "token", token: "replace-me" }, }, } ```
<Warning>
`dangerouslyDisableDeviceAuth` вимикає перевірки ідентичності пристрою Control UI і є серйозним зниженням рівня безпеки. Швидко поверніть попередні налаштування після аварійного використання.
</Warning>
- Успішна автентифікація trusted-proxy може допускати **операторські** сесії Control UI без ідентичності пристрою. - Це **не** поширюється на сесії Control UI з роллю node. - Зворотні проксі loopback на тому самому хості все одно не задовольняють автентифікацію trusted-proxy; див. [Автентифікація довіреного проксі](/uk/gateway/trusted-proxy-auth).

Див. Tailscale, щоб отримати рекомендації з налаштування HTTPS.

Політика безпеки вмісту

Control UI постачається зі строгою політикою img-src: дозволені лише ресурси з того самого origin, URL-адреси data: і локально створені URL-адреси blob:. Віддалені URL-адреси зображень http(s) і URL-адреси без протоколу відхиляються браузером і не спричиняють мережевих запитів.

Що це означає на практиці:

  • Аватари й зображення, що обслуговуються за відносними шляхами (наприклад /avatars/<id>), усе одно відображаються, зокрема автентифіковані маршрути аватарів, які UI отримує та перетворює на локальні URL-адреси blob:.
  • Вбудовані URL-адреси data:image/... усе одно відображаються (корисно для payload у межах протоколу).
  • Локальні URL-адреси blob:, створені Control UI, усе одно відображаються.
  • Віддалені URL-адреси аватарів, які передаються метаданими каналу, вилучаються допоміжними функціями аватарів Control UI і замінюються вбудованим логотипом/значком, тому скомпрометований або шкідливий канал не може змусити браузер оператора виконувати довільні віддалені запити зображень.

Вам не потрібно нічого змінювати, щоб отримати таку поведінку — вона завжди ввімкнена й не налаштовується.

Автентифікація маршруту аватара

Коли автентифікацію Gateway налаштовано, endpoint аватарів Control UI вимагає той самий токен Gateway, що й решта API:

  • GET /avatar/<agentId> повертає зображення аватара лише автентифікованим викликачам. GET /avatar/<agentId>?meta=1 повертає метадані аватара за тим самим правилом.
  • Неавтентифіковані запити до будь-якого з цих маршрутів відхиляються (відповідно до сусіднього маршруту assistant-media). Це запобігає витоку ідентичності агента через маршрут аватара на хостах, які інакше захищені.
  • Сам Control UI пересилає токен Gateway як bearer-заголовок під час отримання аватарів і використовує автентифіковані URL-адреси blob, щоб зображення все одно відображалося на панелях керування.

Якщо ви вимкнете автентифікацію Gateway (не рекомендовано на спільних хостах), маршрут аватара також стане неавтентифікованим, відповідно до решти Gateway.

Автентифікація маршруту медіа асистента

Коли автентифікацію Gateway налаштовано, локальні медіапопередні перегляди асистента використовують двоетапний маршрут:

  • GET /__openclaw__/assistant-media?meta=1&source=<path> вимагає звичайної операторської автентифікації Control UI. Браузер надсилає токен Gateway як bearer-заголовок під час перевірки доступності.
  • Успішні відповіді з метаданими містять короткочасний mediaTicket, обмежений саме цим шляхом джерела.
  • URL-адреси зображень, аудіо, відео та документів, що відображаються браузером, використовують mediaTicket=<ticket> замість активного токена або пароля Gateway. Квиток швидко спливає та не може авторизувати інше джерело.

Це зберігає сумісність звичайного рендерингу медіа з нативними медіаелементами браузера, не розміщуючи багаторазові облікові дані Gateway у видимих URL-адресах медіа.

Збирання UI

Gateway обслуговує статичні файли з dist/control-ui. Зберіть їх за допомогою:

pnpm ui:build

Необов’язкова абсолютна база (коли потрібні фіксовані URL-адреси ресурсів):

OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build

Для локальної розробки (окремий dev-сервер):

pnpm ui:dev

Потім спрямуйте UI на вашу URL-адресу Gateway WS (наприклад ws://127.0.0.1:18789).

Налагодження/тестування: dev-сервер + віддалений Gateway

Control UI — це статичні файли; ціль WebSocket налаштовується й може відрізнятися від HTTP origin. Це зручно, коли ви хочете локально використовувати dev-сервер Vite, але Gateway працює деінде.

```bash pnpm ui:dev ``` ```text http://localhost:5173/?gatewayUrl=ws%3A%2F%2F%3A18789 ```
Необов’язкова одноразова автентифікація (за потреби):

```text
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
```
- `gatewayUrl` зберігається в localStorage після завантаження й видаляється з URL. - Якщо ви передаєте повний endpoint `ws://` або `wss://` через `gatewayUrl`, закодуйте значення `gatewayUrl` для URL, щоб браузер правильно розібрав рядок запиту. - `token` слід передавати через фрагмент URL (`#token=...`) whenever possible. Фрагменти не надсилаються на сервер, що запобігає витоку через журнали запитів і Referer. Застарілі параметри запиту `?token=` усе ще імпортуються один раз для сумісності, але лише як fallback, і видаляються одразу після bootstrap. - `password` зберігається лише в пам’яті. - Коли `gatewayUrl` задано, UI не повертається до облікових даних із конфігурації або середовища. Надайте `token` (або `password`) явно. Відсутність явних облікових даних є помилкою. - Використовуйте `wss://`, коли Gateway розташований за TLS (Tailscale Serve, HTTPS-проксі тощо). - `gatewayUrl` приймається лише у вікні верхнього рівня (не вбудованому), щоб запобігти clickjacking. - Розгортання Control UI не через loopback повинні явно задавати `gateway.controlUi.allowedOrigins` (повні origins). Це включає віддалені dev-налаштування. - Запуск Gateway може засівати локальні origins, як-от `http://localhost:` і `http://127.0.0.1:`, з ефективних runtime bind і порту, але віддалені браузерні origins усе одно потребують явних записів. - Не використовуйте `gateway.controlUi.allowedOrigins: ["*"]`, крім ретельно контрольованого локального тестування. Це означає дозволити будь-який origin браузера, а не «зіставити з будь-яким хостом, який я використовую». - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` вмикає режим fallback origin за заголовком Host, але це небезпечний режим безпеки.

Приклад:

{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}

Докладні відомості про налаштування віддаленого доступу: Віддалений доступ.

Пов’язане