Naar hoofdinhoud gaan

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

De Control UI is een kleine Vite + Lit single-page app die door de Gateway wordt aangeboden:
  • standaard: http://<host>:18789/
  • optioneel prefix: stel gateway.controlUi.basePath in (bijv. /openclaw)
Deze communiceert rechtstreeks met de Gateway WebSocket op dezelfde poort.

Snel openen (lokaal)

Als de Gateway op dezelfde computer draait, open dan: Als de pagina niet laadt, start dan eerst de Gateway: openclaw gateway. Auth wordt tijdens de WebSocket-handshake geleverd via:
  • connect.params.auth.token
  • connect.params.auth.password
  • Tailscale Serve-identiteitsheaders wanneer gateway.auth.allowTailscale: true
  • trusted-proxy-identiteitsheaders wanneer gateway.auth.mode: "trusted-proxy"
Het instellingenpaneel van het dashboard bewaart een token voor de huidige browsertabsessie en de geselecteerde Gateway-URL; wachtwoorden worden niet bewaard. Onboarding genereert meestal een Gateway-token voor shared-secret-auth bij de eerste verbinding, maar wachtwoordauth werkt ook wanneer gateway.auth.mode "password" is.

Apparaat koppelen (eerste verbinding)

Wanneer je vanaf een nieuwe browser of nieuw apparaat verbinding maakt met de Control UI, vereist de Gateway meestal een eenmalige koppelingsgoedkeuring. Dit is een beveiligingsmaatregel om ongeautoriseerde toegang te voorkomen. Wat je ziet: “disconnected (1008): pairing required”
1

Openstaande verzoeken weergeven

openclaw devices list
2

Goedkeuren op verzoek-ID

openclaw devices approve <requestId>
Als de browser opnieuw probeert te koppelen met gewijzigde auth-details (rol/scopes/openbare sleutel), wordt het vorige openstaande verzoek vervangen en wordt er een nieuwe requestId gemaakt. Voer openclaw devices list opnieuw uit vóór goedkeuring. Als de browser al is gekoppeld en je deze wijzigt van leestoegang naar schrijf-/admintoegang, wordt dit behandeld als een goedkeuringsupgrade, niet als een stille herverbinding. OpenClaw houdt de oude goedkeuring actief, blokkeert de bredere herverbinding en vraagt je de nieuwe scopeset expliciet goed te keuren. Na goedkeuring wordt het apparaat onthouden en is hergoedkeuring niet nodig, tenzij je het intrekt met openclaw devices revoke --device <id> --role <role>. Zie Devices CLI voor tokenrotatie en intrekking.
  • Rechtstreekse local loopback-browserverbindingen (127.0.0.1 / localhost) worden automatisch goedgekeurd.
  • Tailscale Serve kan de koppelingsronde overslaan voor Control UI-operatorsessies wanneer gateway.auth.allowTailscale: true, de Tailscale-identiteit wordt geverifieerd en de browser zijn apparaatidentiteit presenteert.
  • Rechtstreekse Tailnet-binds, LAN-browserverbindingen en browserprofielen zonder apparaatidentiteit vereisen nog steeds expliciete goedkeuring.
  • Elk browserprofiel genereert een unieke apparaat-ID, dus wisselen van browser of browsergegevens wissen vereist opnieuw koppelen.

Persoonlijke identiteit (browserlokaal)

De Control UI ondersteunt een persoonlijke identiteit per browser (weergavenaam en avatar) die aan uitgaande berichten wordt gekoppeld voor attributie in gedeelde sessies. Deze staat in browseropslag, is beperkt tot het huidige browserprofiel en wordt niet gesynchroniseerd naar andere apparaten of server-side bewaard buiten de normale metadata voor transcript-auteurschap op berichten die je daadwerkelijk verzendt. Sitegegevens wissen of van browser wisselen zet deze terug naar leeg. Hetzelfde browserlokale patroon geldt voor de avatar-override van de assistant. Geüploade assistant-avatars leggen de door de Gateway opgeloste identiteit alleen over de lokale browser heen en gaan nooit heen en weer via config.patch. Het gedeelde configuratieveld ui.assistant.avatar blijft beschikbaar voor niet-UI-clients die het veld rechtstreeks schrijven (zoals gescripte gateways of aangepaste dashboards).

Runtime-configuratie-endpoint

De Control UI haalt zijn runtime-instellingen op uit /__openclaw/control-ui-config.json. Dat endpoint wordt afgeschermd door dezelfde Gateway-auth als de rest van het HTTP-oppervlak: niet-geauthenticeerde browsers kunnen het niet ophalen, en een succesvolle fetch vereist een al geldig Gateway-token/wachtwoord, Tailscale Serve-identiteit of een trusted-proxy-identiteit.

Taalondersteuning

De Control UI kan zichzelf bij de eerste laadactie lokaliseren op basis van je browserlocale. Om dit later te overschrijven, open je Overview -> Gateway Access -> Language. De locale-kiezer staat in de Gateway Access-kaart, niet onder Appearance.
  • Ondersteunde locales: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
  • Niet-Engelse vertalingen worden lazy-loaded in de browser.
  • De geselecteerde locale wordt opgeslagen in browseropslag en hergebruikt bij toekomstige bezoeken.
  • Ontbrekende vertaalsleutels vallen terug op Engels.
Docs-vertalingen worden gegenereerd voor dezelfde niet-Engelse localeset, maar de ingebouwde Mintlify-taalkiezer van de docs-site is beperkt tot de localecodes die Mintlify accepteert. Thaise (th) en Perzische (fa) docs worden nog steeds gegenereerd in de publish-repo; ze verschijnen mogelijk pas in die kiezer wanneer Mintlify die codes ondersteunt.

Weergavethema’s

Het Appearance-paneel behoudt de ingebouwde thema’s Claw, Knot en Dash, plus één browserlokaal tweakcn-importslot. Om een thema te importeren, open je tweakcn editor, kies of maak je een thema, klik je op Share en plak je de gekopieerde themalink in Appearance. De importer accepteert ook https://tweakcn.com/r/themes/<id>-register-URL’s, editor-URL’s zoals https://tweakcn.com/editor/theme?theme=amethyst-haze, relatieve /themes/<id>-paden, ruwe thema-ID’s en standaardthemanamen zoals amethyst-haze. Geïmporteerde thema’s worden alleen opgeslagen in het huidige browserprofiel. Ze worden niet naar Gateway-configuratie geschreven en synchroniseren niet tussen apparaten. Het geïmporteerde thema vervangen werkt het ene lokale slot bij; het wissen schakelt het actieve thema terug naar Claw als het geïmporteerde thema geselecteerd was.

Wat het kan doen (vandaag)

  • Chat met het model via Gateway WS (chat.history, chat.send, chat.abort, chat.inject).
  • Vernieuwingen van de chatgeschiedenis vragen een begrensd recent venster op met tekstlimieten per bericht, zodat grote sessies de browser niet dwingen een volledige transcript-payload te renderen voordat de chat bruikbaar wordt.
  • Praat via browser-realtime sessies. OpenAI gebruikt rechtstreekse WebRTC, Google Live gebruikt een beperkt eenmalig browsertoken via WebSocket, en backend-only realtime spraak-plugins gebruiken het Gateway-relaytransport. Client-eigendom providersessies starten met talk.client.create; Gateway-relaysessies starten met talk.session.create. De relay houdt providercredentials op de Gateway terwijl de browser microfoon-PCM streamt via talk.session.appendAudio en openclaw_agent_consult-providertoolcalls doorstuurt via talk.client.toolCall voor Gateway-beleid en het grotere geconfigureerde OpenClaw-model.
  • Stream toolcalls + live tooluitvoerkaarten in Chat (agent-events).
  • Kanalen: ingebouwde plus gebundelde/externe Plugin-kanalenstatus, QR-login en configuratie per kanaal (channels.status, web.login.*, config.patch).
  • Vernieuwingen van kanaalprobes houden de vorige snapshot zichtbaar terwijl trage providercontroles worden afgerond, en deelsnapshots worden gelabeld wanneer een probe of audit zijn UI-budget overschrijdt.
  • Instanties: aanwezigheidslijst + vernieuwen (system-presence).
  • Sessies: standaard geconfigureerde-agent-sessies weergeven, terugvallen vanaf verouderde niet-geconfigureerde agentsessiesleutels, en model-/thinking-/fast-/verbose-/trace-/reasoning-overrides per sessie toepassen (sessions.list, sessions.patch).
  • Dreams: Dreaming-status, in-/uitschakelknop en Dream Diary-lezer (doctor.memory.status, doctor.memory.dreamDiary, config.patch).
  • Cron-taken: weergeven/toevoegen/bewerken/uitvoeren/inschakelen/uitschakelen + uitvoeringsgeschiedenis (cron.*).
  • Skills: status, inschakelen/uitschakelen, installeren, API-sleutelupdates (skills.*).
  • Nodes: lijst + caps (node.list).
  • Exec-goedkeuringen: Gateway- of Node-allowlists bewerken + vraagbeleid voor exec host=gateway/node (exec.approvals.*).
  • ~/.openclaw/openclaw.json bekijken/bewerken (config.get, config.set).
  • Toepassen + opnieuw starten met validatie (config.apply) en de laatst actieve sessie wekken.
  • Schrijfacties bevatten een base-hash guard om te voorkomen dat gelijktijdige bewerkingen worden overschreven.
  • Schrijfacties (config.set/config.apply/config.patch) preflighten actieve SecretRef-resolutie voor refs in de ingediende configuratiepayload; niet-opgeloste actieve ingediende refs worden vóór schrijven geweigerd.
  • Schema + formulierweergave (config.schema / config.schema.lookup, inclusief veld title / description, gematchte UI-hints, directe kind-samenvattingen, docs-metadata op geneste object-/wildcard-/array-/composition-nodes, plus Plugin- + kanaalschema’s wanneer beschikbaar); Raw JSON-editor is alleen beschikbaar wanneer de snapshot een veilige raw round-trip heeft.
  • Als een snapshot niet veilig raw-tekst kan round-trippen, dwingt Control UI Form-modus af en schakelt Raw-modus uit voor die snapshot.
  • Raw JSON-editor “Reset to saved” behoudt de raw-geschreven vorm (opmaak, opmerkingen, $include-layout) in plaats van een afgevlakte snapshot opnieuw te renderen, zodat externe bewerkingen een reset overleven wanneer de snapshot veilig kan round-trippen.
  • Gestructureerde SecretRef-objectwaarden worden alleen-lezen gerenderd in formuliertekstinvoeren om onbedoelde object-naar-string-corruptie te voorkomen.
  • Debug: status-/health-/models-snapshots + eventlog + handmatige RPC-calls (status, health, models.list).
  • Het eventlog bevat Control UI-verversings-/RPC-timings, trage chat-/config-render-timings en browserresponsiviteitsitems voor lange animatieframes of lange taken wanneer de browser die PerformanceObserver-entrytypes beschikbaar stelt.
  • Logs: live tail van Gateway-bestandslogs met filter/export (logs.tail).
  • Update: voer een package-/git-update + herstart uit (update.run) met een herstartrapport, en poll daarna update.status na herverbinding om de draaiende Gateway-versie te verifiëren.
  • Voor geïsoleerde taken is de standaardbezorging een samenvatting aankondigen. Je kunt overschakelen naar geen als je internal-only runs wilt.
  • Kanaal-/doelvelden verschijnen wanneer aankondigen is geselecteerd.
  • Webhook-modus gebruikt delivery.mode = "webhook" met delivery.to ingesteld op een geldige HTTP(S)-Webhook-URL.
  • Voor hoofdsessietaken zijn Webhook- en geen-bezorgingsmodi beschikbaar.
  • Geavanceerde bewerkingsknoppen omvatten verwijderen-na-uitvoering, agent-override wissen, exacte/stagger-opties voor Cron, agentmodel-/thinking-overrides en best-effort-bezorgingsschakelaars.
  • Formuliervalidatie is inline met fouten op veldniveau; ongeldige waarden schakelen de bewaarknop uit totdat ze zijn gecorrigeerd.
  • Stel cron.webhookToken in om een speciale bearer-token te verzenden; indien weggelaten wordt de Webhook zonder auth-header verzonden.
  • Verouderde fallback: opgeslagen legacy-taken met notify: true kunnen nog steeds cron.webhook gebruiken totdat ze zijn gemigreerd.

Chatgedrag

  • chat.send is niet-blokkerend: het bevestigt direct met { runId, status: "started" } en de reactie streamt via chat-gebeurtenissen.
  • Chat-uploads accepteren afbeeldingen plus niet-videobestanden. Afbeeldingen behouden het native afbeeldingspad; andere bestanden worden opgeslagen als beheerde media en in de geschiedenis weergegeven als bijlagelinks.
  • Opnieuw verzenden met dezelfde idempotencyKey retourneert { status: "in_flight" } zolang het draait, en { status: "ok" } na voltooiing.
  • chat.history-reacties zijn begrensd in grootte voor UI-veiligheid. Wanneer transcriptitems te groot zijn, kan Gateway lange tekstvelden inkorten, zware metadatablokken weglaten en te grote berichten vervangen door een plaatshouder ([chat.history omitted: message too large]).
  • Door de assistent gegenereerde afbeeldingen worden bewaard als beheerde mediareferenties en teruggeleverd via geauthenticeerde Gateway-media-URL’s, zodat herladen niet afhankelijk is van ruwe base64-afbeeldingspayloads die in de chatgeschiedenisreactie blijven staan.
  • Bij het renderen van chat.history verwijdert de Control UI inline directivetags die alleen voor weergave zijn uit zichtbare assistenttekst (bijvoorbeeld [[reply_to_*]] en [[audio_as_voice]]), XML-payloads van toolaanroepen in platte tekst (inclusief <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> en afgekorte toolaanroepblokken), en gelekte ASCII-/volledige-breedte modelbesturingstokens, en laat assistentitems weg waarvan de volledige zichtbare tekst alleen het exacte stille token NO_REPLY / no_reply of het Heartbeat-bevestigingstoken HEARTBEAT_OK is.
  • Tijdens een actieve verzending en de laatste geschiedenisverversing houdt de chatweergave lokale optimistische gebruikers-/assistentberichten zichtbaar als chat.history kort een oudere momentopname retourneert; het canonieke transcript vervangt die lokale berichten zodra de Gateway-geschiedenis is bijgewerkt.
  • Live chat-gebeurtenissen zijn afleverstatus, terwijl chat.history opnieuw wordt opgebouwd vanuit het duurzame sessietranscript. Na tool-final-gebeurtenissen laadt de Control UI de geschiedenis opnieuw en voegt alleen een kleine optimistische staart samen; de transcriptgrens is gedocumenteerd in WebChat.
  • chat.inject voegt een assistentnotitie toe aan het sessietranscript en zendt een chat-gebeurtenis uit voor alleen-UI-updates (geen agentrun, geen kanaalaflevering).
  • De chatkop toont het agentfilter vóór de sessiekiezer, en de sessiekiezer is beperkt tot de geselecteerde agent. Wisselen van agent toont alleen sessies die aan die agent zijn gekoppeld en valt terug op de hoofdsessie van die agent wanneer die nog geen opgeslagen dashboardsessies heeft.
  • Op desktopbreedtes blijven chatbedieningen op één compacte rij en klappen ze in tijdens het omlaag scrollen door het transcript; omhoog scrollen, terugkeren naar de bovenkant of de onderkant bereiken herstelt de bedieningen.
  • Opeenvolgende dubbele berichten met alleen tekst worden weergegeven als één ballon met een tellerbadge. Berichten met afbeeldingen, bijlagen, tooluitvoer of canvasvoorbeelden blijven niet-ingeklapt.
  • De model- en denkkiezers in de chatkop patchen de actieve sessie direct via sessions.patch; het zijn blijvende sessie-overschrijvingen, geen verzendopties voor slechts één beurt.
  • /new typen in de Control UI maakt dezelfde nieuwe dashboardsessie als Nieuwe chat aan en schakelt daarnaar over. /reset typen behoudt de expliciete reset op dezelfde plaats van de Gateway voor de huidige sessie.
  • De chatmodelkiezer vraagt de geconfigureerde modelweergave van de Gateway op. Als agents.defaults.models aanwezig is, stuurt die allowlist de kiezer aan. Anders toont de kiezer expliciete models.providers.*.models-items plus providers met bruikbare authenticatie. De volledige catalogus blijft beschikbaar via de debug-RPC models.list met view: "all".
  • Wanneer recente Gateway-sessiegebruiksrapporten huidige contexttokens bevatten, toont het chatcomposergebied een compacte indicator voor contextgebruik. Deze schakelt over naar waarschuwingstijl bij hoge contextdruk en toont, bij aanbevolen Compaction-niveaus, een compacte knop die het normale sessie-Compaction-pad uitvoert. Verouderde tokenmomentopnamen worden verborgen totdat de Gateway opnieuw recent gebruik rapporteert.
De praatmodus gebruikt een geregistreerde realtime spraakprovider. Configureer OpenAI met talk.realtime.provider: "openai" plus talk.realtime.providers.openai.apiKey, of configureer Google met talk.realtime.provider: "google" plus talk.realtime.providers.google.apiKey. De browser ontvangt nooit een standaard API-sleutel van de provider. OpenAI ontvangt een ephemeral Realtime-clientgeheim voor WebRTC. Google Live ontvangt een eenmalig beperkt Live API-authenticatietoken voor een browser-WebSocket-sessie, waarbij instructies en tooldeclaraties door de Gateway in het token zijn vastgezet. Providers die alleen een realtime backendbrug aanbieden, lopen via het Gateway-relaytransport, zodat referenties en vendorsockets server-side blijven terwijl browseraudio via geauthenticeerde Gateway-RPC’s beweegt. De Realtime-sessieprompt wordt door de Gateway samengesteld; talk.client.create accepteert geen door de aanroeper aangeleverde instructie-overschrijvingen.In de Chat-composer is de praatbediening de golfknop naast de microfoonknop voor dicteren. Wanneer Praten start, toont de statusrij van de composer Connecting Talk..., daarna Talk live terwijl audio is verbonden, of Asking OpenClaw... terwijl een realtime toolaanroep het geconfigureerde grotere model raadpleegt via talk.client.toolCall.Live rooktest voor maintainers: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts verifieert de OpenAI browser-WebRTC-SDP-uitwisseling, de Google Live browser-WebSocket-instelling met beperkt token, en de Gateway-relaybrowseradapter met nep-microfoonmedia. De opdracht drukt alleen providerstatus af en logt geen geheimen.
  • Klik op Stop (roept chat.abort aan).
  • Terwijl een run actief is, worden normale vervolgberichten in de wachtrij geplaatst. Klik op Sturen op een bericht in de wachtrij om dat vervolgbericht in de lopende beurt te injecteren.
  • Typ /stop (of losse afbreekfrasen zoals stop, stop action, stop run, stop openclaw, please stop) om buiten de normale band om af te breken.
  • chat.abort ondersteunt { sessionKey } (geen runId) om alle actieve runs voor die sessie af te breken.
  • Wanneer een run wordt afgebroken, kan gedeeltelijke assistenttekst nog steeds in de UI worden getoond.
  • Gateway bewaart afgebroken gedeeltelijke assistenttekst in de transcriptgeschiedenis wanneer gebufferde uitvoer bestaat.
  • Bewaarde items bevatten afbreekmetadata zodat transcriptconsumenten gedeeltelijke afbreekuitvoer kunnen onderscheiden van normale voltooiingsuitvoer.

PWA-installatie en webpush

De Control UI levert een manifest.webmanifest en een serviceworker, zodat moderne browsers deze als zelfstandige PWA kunnen installeren. Web Push laat de Gateway de geïnstalleerde PWA wekken met meldingen, zelfs wanneer het tabblad of browservenster niet open is.
OppervlakWat het doet
ui/public/manifest.webmanifestPWA-manifest. Browsers bieden “App installeren” zodra het bereikbaar is.
ui/public/sw.jsServiceworker die push-gebeurtenissen en meldingsklikken afhandelt.
push/vapid-keys.json (onder de OpenClaw-statusmap)Automatisch gegenereerd VAPID-sleutelpaar dat wordt gebruikt om Web Push-payloads te ondertekenen.
push/web-push-subscriptions.jsonBewaarde browserabonnementseindpunten.
Overschrijf het VAPID-sleutelpaar via omgevingsvariabelen op het Gateway-proces wanneer je sleutels wilt vastzetten (voor multi-host-implementaties, geheimrotatie of tests):
  • OPENCLAW_VAPID_PUBLIC_KEY
  • OPENCLAW_VAPID_PRIVATE_KEY
  • OPENCLAW_VAPID_SUBJECT (standaard mailto:openclaw@localhost)
De Control UI gebruikt deze scope-begrensde Gateway-methoden om browserabonnementen te registreren en te testen:
  • push.web.vapidPublicKey — haalt de actieve openbare VAPID-sleutel op.
  • push.web.subscribe — registreert een endpoint plus keys.p256dh/keys.auth.
  • push.web.unsubscribe — verwijdert een geregistreerd eindpunt.
  • push.web.test — stuurt een testmelding naar het abonnement van de aanroeper.
Web Push is onafhankelijk van het iOS APNS-relaypad (zie Configuratie voor relay-ondersteunde push) en de bestaande methode push.test, die gericht zijn op native mobiele koppeling.

Gehoste embeds

Assistentberichten kunnen gehoste webinhoud inline renderen met de shortcode [embed ...]. Het iframe-sandboxbeleid wordt beheerd door gateway.controlUi.embedSandbox:
Schakelt scriptuitvoering binnen gehoste embeds uit.
Voorbeeld:
{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
Gebruik trusted alleen wanneer het ingesloten document werkelijk same-origin-gedrag nodig heeft. Voor de meeste door agents gegenereerde games en interactieve canvassen is scripts de veiligere keuze.
Absolute externe http(s)-embed-URL’s blijven standaard geblokkeerd. Als je bewust wilt dat [embed url="https://..."] pagina’s van derden laadt, stel dan gateway.controlUi.allowExternalEmbedUrls: true in.

Breedte van chatberichten

Gegroepeerde chatberichten gebruiken een leesbare standaard maximale breedte. Implementaties met brede monitoren kunnen dit overschrijven zonder gebundelde CSS te patchen door gateway.controlUi.chatMessageMaxWidth in te stellen:
{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}
De waarde wordt gevalideerd voordat deze de browser bereikt. Ondersteunde waarden omvatten gewone lengtes en percentages zoals 960px of 82%, plus begrensde breedte-expressies min(...), max(...), clamp(...), calc(...) en fit-content(...).

Tailnet-toegang (aanbevolen)

Houd de Gateway op loopback en laat Tailscale Serve deze proxyen met HTTPS:
openclaw gateway --tailscale serve
Open:
  • https://<magicdns>/ (of je geconfigureerde gateway.controlUi.basePath)
Standaard kunnen Control UI-/WebSocket Serve-verzoeken authenticeren via Tailscale-identiteitsheaders (tailscale-user-login) wanneer gateway.auth.allowTailscale true is. OpenClaw verifieert de identiteit door het x-forwarded-for-adres op te lossen met tailscale whois en het te vergelijken met de header, en accepteert deze alleen wanneer het verzoek loopback raakt met de x-forwarded-*-headers van Tailscale. Voor Control UI-operatorsessies met browserapparaatidentiteit slaat dit geverifieerde Serve-pad ook de retourstap voor apparaatkoppeling over; browsers zonder apparaat en verbindingen met noderol volgen nog steeds de normale apparaatcontroles. Stel gateway.auth.allowTailscale: false in als je expliciete gedeelde-geheime referenties wilt vereisen, zelfs voor Serve-verkeer. Gebruik daarna gateway.auth.mode: "token" of "password".Voor dat asynchrone Serve-identiteitspad worden mislukte authenticatiepogingen voor hetzelfde client-IP en dezelfde authenticatiescope geserialiseerd voordat rate-limit-schrijfbewerkingen plaatsvinden. Gelijktijdige foutieve nieuwe pogingen vanuit dezelfde browser kunnen daarom retry later tonen bij het tweede verzoek in plaats van twee gewone mismatches die parallel racen.
Tokenloze Serve-authenticatie gaat ervan uit dat de gatewayhost vertrouwd is. Als niet-vertrouwde lokale code op die host kan draaien, vereis dan token-/wachtwoordauthenticatie.

Onveilige HTTP

Als je het dashboard opent via gewone HTTP (http://<lan-ip> of http://<tailscale-ip>), draait de browser in een niet-beveiligde context en blokkeert hij WebCrypto. Standaard blokkeert OpenClaw Control UI-verbindingen zonder apparaatidentiteit. Gedocumenteerde uitzonderingen:
  • alleen-localhost onveilige HTTP-compatibiliteit met gateway.controlUi.allowInsecureAuth=true
  • succesvolle operator-Control UI-authenticatie via gateway.auth.mode: "trusted-proxy"
  • noodoptie gateway.controlUi.dangerouslyDisableDeviceAuth=true
Aanbevolen oplossing: gebruik HTTPS (Tailscale Serve) of open de UI lokaal:
  • https://<magicdns>/ (Serve)
  • http://127.0.0.1:18789/ (op de Gateway-host)
{
  gateway: {
    controlUi: { allowInsecureAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
allowInsecureAuth is alleen een lokale compatibiliteitsschakelaar:
  • Hiermee kunnen localhost-Control UI-sessies doorgaan zonder apparaatidentiteit in niet-beveiligde HTTP-contexten.
  • Deze omzeilt geen koppelingscontroles.
  • Deze versoepelt geen vereisten voor apparaatidentiteit op afstand (niet-localhost).
{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
dangerouslyDisableDeviceAuth schakelt apparaatidentiteitscontroles van de Control UI uit en is een ernstige beveiligingsverlaging. Zet dit snel terug na noodgebruik.
  • Succesvolle vertrouwde-proxy-authenticatie kan operator-Control UI-sessies zonder apparaatidentiteit toelaten.
  • Dit geldt niet voor Control UI-sessies met een node-rol.
  • local loopback reverse proxies op dezelfde host voldoen nog steeds niet aan vertrouwde-proxy-authenticatie; zie Vertrouwde-proxy-authenticatie.
Zie Tailscale voor richtlijnen voor HTTPS-configuratie.

Contentbeveiligingsbeleid

De Control UI wordt geleverd met een strikt img-src-beleid: alleen assets met same-origin, data:-URL’s en lokaal gegenereerde blob:-URL’s zijn toegestaan. Externe http(s)- en protocolrelatieve afbeeldings-URL’s worden door de browser geweigerd en veroorzaken geen netwerkverzoeken. Wat dit in de praktijk betekent:
  • Avatars en afbeeldingen die onder relatieve paden worden geserveerd (bijvoorbeeld /avatars/<id>) worden nog steeds weergegeven, inclusief geauthenticeerde avatarroutes die de UI ophaalt en omzet naar lokale blob:-URL’s.
  • Inline data:image/...-URL’s worden nog steeds weergegeven (handig voor payloads binnen het protocol).
  • Lokale blob:-URL’s die door de Control UI zijn gemaakt, worden nog steeds weergegeven.
  • Externe avatar-URL’s die door kanaalmetadata worden uitgegeven, worden bij de avatarhelpers van de Control UI verwijderd en vervangen door het ingebouwde logo/de ingebouwde badge, zodat een gecompromitteerd of kwaadaardig kanaal geen willekeurige externe afbeeldingsverzoeken vanuit de browser van een operator kan afdwingen.
Je hoeft niets te wijzigen om dit gedrag te krijgen: het staat altijd aan en is niet configureerbaar.

Authenticatie voor avatarroute

Wanneer Gateway-authenticatie is geconfigureerd, vereist het avatar-eindpunt van de Control UI hetzelfde Gateway-token als de rest van de API:
  • GET /avatar/<agentId> retourneert de avatarafbeelding alleen aan geauthenticeerde aanroepers. GET /avatar/<agentId>?meta=1 retourneert de avatarmetadata onder dezelfde regel.
  • Niet-geauthenticeerde verzoeken naar beide routes worden geweigerd (net als bij de verwante assistant-media-route). Dit voorkomt dat de avatarroute agentidentiteit lekt op hosts die verder beschermd zijn.
  • De Control UI stuurt zelf het Gateway-token door als bearer-header bij het ophalen van avatars en gebruikt geauthenticeerde blob-URL’s zodat de afbeelding nog steeds in dashboards wordt weergegeven.
Als je Gateway-authenticatie uitschakelt (niet aanbevolen op gedeelde hosts), wordt de avatarroute ook niet-geauthenticeerd, in lijn met de rest van de Gateway.

Authenticatie voor assistant-mediaroute

Wanneer Gateway-authenticatie is geconfigureerd, gebruiken lokale-mediavoorvertoningen van de assistant een route in twee stappen:
  • GET /__openclaw__/assistant-media?meta=1&source=<path> vereist de normale Control UI-operatorauthenticatie. De browser verzendt het Gateway-token als bearer-header bij het controleren van beschikbaarheid.
  • Succesvolle metadataresponses bevatten een kortlevend mediaTicket dat is beperkt tot dat exacte bronpad.
  • Door de browser weergegeven URL’s voor afbeeldingen, audio, video en documenten gebruiken mediaTicket=<ticket> in plaats van het actieve Gateway-token of wachtwoord. Het ticket verloopt snel en kan geen andere bron autoriseren.
Hierdoor blijft normale mediaweergave compatibel met browsereigen media-elementen zonder herbruikbare Gateway-referenties in zichtbare media-URL’s te plaatsen.

De UI bouwen

De Gateway serveert statische bestanden vanuit dist/control-ui. Bouw ze met:
pnpm ui:build
Optionele absolute basis (wanneer je vaste asset-URL’s wilt):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
Voor lokale ontwikkeling (aparte ontwikkelserver):
pnpm ui:dev
Wijs de UI daarna naar je Gateway-WS-URL (bijv. ws://127.0.0.1:18789).

Debuggen/testen: ontwikkelserver + externe Gateway

De Control UI bestaat uit statische bestanden; het WebSocket-doel is configureerbaar en kan verschillen van de HTTP-origin. Dit is handig wanneer je de Vite-ontwikkelserver lokaal wilt gebruiken, maar de Gateway ergens anders draait.
1

Start de UI-ontwikkelserver

pnpm ui:dev
2

Openen met gatewayUrl

http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
Optionele eenmalige authenticatie (indien nodig):
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
  • gatewayUrl wordt na het laden opgeslagen in localStorage en uit de URL verwijderd.
  • Als je een volledig ws://- of wss://-eindpunt via gatewayUrl doorgeeft, URL-codeer dan de gatewayUrl-waarde zodat de browser de querystring correct parseert.
  • token moet waar mogelijk via het URL-fragment (#token=...) worden doorgegeven. Fragmenten worden niet naar de server verzonden, wat lekken via verzoeklogs en Referer voorkomt. Verouderde ?token=-queryparameters worden nog steeds één keer geïmporteerd voor compatibiliteit, maar alleen als fallback, en worden direct na bootstrap verwijderd.
  • password wordt alleen in het geheugen bewaard.
  • Wanneer gatewayUrl is ingesteld, valt de UI niet terug op referenties uit configuratie of omgeving. Geef token (of password) expliciet op. Ontbrekende expliciete referenties zijn een fout.
  • Gebruik wss:// wanneer de Gateway achter TLS staat (Tailscale Serve, HTTPS-proxy, enz.).
  • gatewayUrl wordt alleen geaccepteerd in een venster op topniveau (niet embedded) om clickjacking te voorkomen.
  • Niet-loopback Control UI-deployments moeten gateway.controlUi.allowedOrigins expliciet instellen (volledige origins). Dit omvat externe ontwikkelopstellingen.
  • Bij het opstarten kan de Gateway lokale origins zoals http://localhost:<port> en http://127.0.0.1:<port> vullen op basis van de effectieve runtime-bind en poort, maar externe browser-origins hebben nog steeds expliciete vermeldingen nodig.
  • Gebruik gateway.controlUi.allowedOrigins: ["*"] niet, behalve voor strikt gecontroleerde lokale tests. Het betekent dat elke browser-origin wordt toegestaan, niet “match de host die ik gebruik.”
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true schakelt fallbackmodus voor Host-header-origin in, maar dit is een gevaarlijke beveiligingsmodus.
Voorbeeld:
{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}
Details voor externe-toegangsconfiguratie: Externe toegang.

Gerelateerd