Web interfaces
Steuerungsoberfläche
Die Control UI ist eine kleine Vite + Lit-Single-Page-App, die vom Gateway bereitgestellt wird:
- Standard:
http://<host>:18789/ - optionales Präfix:
gateway.controlUi.basePathfestlegen (z. B./openclaw)
Sie kommuniziert direkt mit dem Gateway WebSocket auf demselben Port.
Schnell öffnen (lokal)
Wenn das Gateway auf demselben Computer läuft, öffnen Sie:
Wenn die Seite nicht geladen wird, starten Sie zuerst das Gateway: openclaw gateway.
Die Authentifizierung wird während des WebSocket-Handshakes bereitgestellt über:
connect.params.auth.tokenconnect.params.auth.password- Tailscale Serve-Identitätsheader, wenn
gateway.auth.allowTailscale: true - Trusted-Proxy-Identitätsheader, wenn
gateway.auth.mode: "trusted-proxy"
Das Einstellungsfeld des Dashboards behält ein Token für die aktuelle Browser-Tab-Sitzung und die ausgewählte Gateway-URL; Passwörter werden nicht dauerhaft gespeichert. Das Onboarding erzeugt beim ersten Verbindungsaufbau üblicherweise ein Gateway-Token für Shared-Secret-Authentifizierung, aber Passwortauthentifizierung funktioniert ebenfalls, wenn gateway.auth.mode "password" ist.
Geräte-Pairing (erste Verbindung)
Wenn Sie über einen neuen Browser oder ein neues Gerät eine Verbindung zur Control UI herstellen, verlangt das Gateway üblicherweise eine einmalige Pairing-Genehmigung. Dies ist eine Sicherheitsmaßnahme, um unbefugten Zugriff zu verhindern.
Was Sie sehen werden: „disconnected (1008): pairing required“
Ausstehende Anfragen auflisten
openclaw devices list
Per Anfrage-ID genehmigen
openclaw devices approve <requestId>
Wenn der Browser das Pairing mit geänderten Authentifizierungsdetails (Rolle/Bereiche/öffentlicher Schlüssel) erneut versucht, wird die vorherige ausstehende Anfrage ersetzt und eine neue requestId erstellt. Führen Sie vor der Genehmigung erneut openclaw devices list aus.
Wenn der Browser bereits gekoppelt ist und Sie ihn von Lesezugriff auf Schreib-/Adminzugriff ändern, wird dies als Genehmigungs-Upgrade behandelt, nicht als stille Wiederverbindung. OpenClaw hält die alte Genehmigung aktiv, blockiert die umfassendere Wiederverbindung und fordert Sie auf, den neuen Bereichssatz ausdrücklich zu genehmigen.
Nach der Genehmigung wird das Gerät gespeichert und erfordert keine erneute Genehmigung, es sei denn, Sie widerrufen es mit openclaw devices revoke --device <id> --role <role>. Siehe Geräte-CLI für Token-Rotation und Widerruf.
Persönliche Identität (browserlokal)
Die Control UI unterstützt eine browserbezogene persönliche Identität (Anzeigename und Avatar), die ausgehenden Nachrichten zur Zuordnung in gemeinsamen Sitzungen angehängt wird. Sie liegt im Browser-Speicher, ist auf das aktuelle Browserprofil beschränkt und wird weder mit anderen Geräten synchronisiert noch serverseitig über die normalen Transcript-Autorenschaftsmetadaten der Nachrichten hinaus gespeichert, die Sie tatsächlich senden. Das Löschen von Websitedaten oder ein Browserwechsel setzt sie auf leer zurück.
Dasselbe browserlokale Muster gilt für die Überschreibung des Assistenten-Avatars. Hochgeladene Assistenten-Avatare überlagern die vom Gateway aufgelöste Identität nur im lokalen Browser und durchlaufen niemals config.patch. Das gemeinsame Konfigurationsfeld ui.assistant.avatar bleibt für Nicht-UI-Clients verfügbar, die das Feld direkt schreiben (z. B. skriptgesteuerte Gateways oder benutzerdefinierte Dashboards).
Runtime-Konfigurationsendpunkt
Die Control UI ruft ihre Runtime-Einstellungen von /__openclaw/control-ui-config.json ab. Dieser Endpunkt wird durch dieselbe Gateway-Authentifizierung geschützt wie der Rest der HTTP-Oberfläche: Nicht authentifizierte Browser können ihn nicht abrufen, und ein erfolgreicher Abruf erfordert entweder ein bereits gültiges Gateway-Token/Passwort, eine Tailscale Serve-Identität oder eine Trusted-Proxy-Identität.
Sprachunterstützung
Die Control UI kann sich beim ersten Laden anhand Ihrer Browser-Locale lokalisieren. Um dies später zu überschreiben, öffnen Sie Übersicht -> Gateway-Zugriff -> Sprache. Die Locale-Auswahl befindet sich in der Karte „Gateway-Zugriff“, nicht unter „Darstellung“.
- Unterstützte Locales:
en,zh-CN,zh-TW,pt-BR,de,es,ja-JP,ko,fr,ar,it,tr,uk,id,pl,th,vi,nl,fa - Nicht-englische Übersetzungen werden im Browser per Lazy Loading geladen.
- Die ausgewählte Locale wird im Browser-Speicher gespeichert und bei künftigen Besuchen wiederverwendet.
- Fehlende Übersetzungsschlüssel fallen auf Englisch zurück.
Dokumentationsübersetzungen werden für denselben nicht-englischen Locale-Satz generiert, aber die integrierte Mintlify-Sprachauswahl der Dokumentationswebsite ist auf die von Mintlify akzeptierten Locale-Codes beschränkt. Thailändische (th) und persische (fa) Dokumentation wird weiterhin im Veröffentlichungs-Repo generiert; sie erscheint möglicherweise erst dann in dieser Auswahl, wenn Mintlify diese Codes unterstützt.
Darstellungsthemes
Das Darstellungsfeld behält die integrierten Themes Claw, Knot und Dash sowie einen browserlokalen tweakcn-Import-Slot. Um ein Theme zu importieren, öffnen Sie den tweakcn-Editor, wählen oder erstellen Sie ein Theme, klicken Sie auf Teilen, und fügen Sie den kopierten Theme-Link in „Darstellung“ ein. Der Importer akzeptiert außerdem https://tweakcn.com/r/themes/<id>-Registry-URLs, Editor-URLs wie https://tweakcn.com/editor/theme?theme=amethyst-haze, relative /themes/<id>-Pfade, rohe Theme-IDs und Standard-Theme-Namen wie amethyst-haze.
Importierte Themes werden nur im aktuellen Browserprofil gespeichert. Sie werden nicht in die Gateway-Konfiguration geschrieben und nicht geräteübergreifend synchronisiert. Das Ersetzen des importierten Themes aktualisiert den einen lokalen Slot; das Löschen schaltet das aktive Theme zurück auf Claw, wenn das importierte Theme ausgewählt war.
Was sie kann (heute)
Chat und Talk
- Chatten Sie mit dem Modell über Gateway WS (
chat.history,chat.send,chat.abort,chat.inject). - Chatverlaufs-Aktualisierungen fordern ein begrenztes aktuelles Fenster mit Textobergrenzen pro Nachricht an, damit große Sitzungen den Browser nicht zwingen, eine vollständige Transcript-Nutzlast zu rendern, bevor der Chat nutzbar wird.
- Sprechen Sie über Browser-Echtzeitsitzungen. OpenAI verwendet direktes WebRTC, Google Live verwendet ein eingeschränktes einmalig nutzbares Browser-Token über WebSocket, und rein backendseitige Echtzeit-Sprach-Plugins verwenden den Gateway-Relay-Transport. Client-eigene Provider-Sitzungen starten mit
talk.client.create; Gateway-Relay-Sitzungen starten mittalk.session.create. Das Relay hält Provider-Anmeldedaten auf dem Gateway, während der Browser Mikrofon-PCM übertalk.session.appendAudiostreamt undopenclaw_agent_consult-Provider-Toolaufrufe übertalk.client.toolCallfür Gateway-Richtlinien und das größere konfigurierte OpenClaw-Modell weiterleitet. - Streamen Sie Toolaufrufe und Live-Tool-Ausgabekarten im Chat (Agent-Ereignisse).
Kanäle, Instanzen, Sitzungen, Träume
- Kanäle: Status integrierter sowie gebündelter/externer Plugin-Kanäle, QR-Login und kanalbezogene Konfiguration (
channels.status,web.login.*,config.patch). - Kanal-Probe-Aktualisierungen halten den vorherigen Snapshot sichtbar, während langsame Provider-Prüfungen abgeschlossen werden, und Teilsnapshots werden gekennzeichnet, wenn eine Probe oder Prüfung ihr UI-Budget überschreitet.
- Instanzen: Präsenzliste und Aktualisierung (
system-presence). - Sitzungen: Liste und sitzungsbezogene Überschreibungen für Modell/Denken/Schnell/Ausführlich/Trace/Reasoning (
sessions.list,sessions.patch). - Träume: Dreaming-Status, Aktivieren/Deaktivieren-Schalter und Traumtagebuch-Leser (
doctor.memory.status,doctor.memory.dreamDiary,config.patch).
Cron, Skills, Nodes, Exec-Genehmigungen
- Cron-Jobs: auflisten/hinzufügen/bearbeiten/ausführen/aktivieren/deaktivieren und Ausführungsverlauf (
cron.*). - Skills: Status, aktivieren/deaktivieren, installieren, API-Schlüssel aktualisieren (
skills.*). - Nodes: Liste und Capabilities (
node.list). - Exec-Genehmigungen: Gateway- oder Node-Allowlists und Abfragerichtlinie für
exec host=gateway/nodebearbeiten (exec.approvals.*).
Konfiguration
~/.openclaw/openclaw.jsonanzeigen/bearbeiten (config.get,config.set).- Mit Validierung anwenden und neu starten (
config.apply) sowie die zuletzt aktive Sitzung aufwecken. - Schreibvorgänge enthalten einen Base-Hash-Schutz, um das Überschreiben gleichzeitiger Bearbeitungen zu verhindern.
- Schreibvorgänge (
config.set/config.apply/config.patch) prüfen vorab die aktive SecretRef-Auflösung für Refs in der übermittelten Konfigurationsnutzlast; nicht aufgelöste aktive übermittelte Refs werden vor dem Schreiben abgelehnt. - Schema- und Formular-Rendering (
config.schema/config.schema.lookup, einschließlich Feldtitle/description, passender UI-Hinweise, Zusammenfassungen direkter untergeordneter Elemente, Dokumentationsmetadaten auf verschachtelten Objekt-/Wildcard-/Array-/Kompositionsknoten sowie Plugin- und Kanalschemata, sofern verfügbar); der Raw-JSON-Editor ist nur verfügbar, wenn der Snapshot einen sicheren Raw-Roundtrip hat. - Wenn ein Snapshot Raw-Text nicht sicher im Roundtrip verarbeiten kann, erzwingt die Control UI den Formularmodus und deaktiviert den Raw-Modus für diesen Snapshot.
- „Auf gespeichert zurücksetzen“ im Raw-JSON-Editor bewahrt die roh verfasste Form (Formatierung, Kommentare,
$include-Layout), anstatt einen abgeflachten Snapshot neu zu rendern, sodass externe Bearbeitungen einen Reset überstehen, wenn der Snapshot sicher einen Roundtrip durchführen kann. - Strukturierte SecretRef-Objektwerte werden in Formular-Texteingaben schreibgeschützt gerendert, um versehentliche Objekt-zu-String-Beschädigung zu verhindern.
Debug, Protokolle, Aktualisierung
- Debug: Status-/Health-/Modell-Snapshots sowie Ereignisprotokoll und manuelle RPC-Aufrufe (
status,health,models.list). - Das Ereignisprotokoll enthält Control UI-Aktualisierungs-/RPC-Zeiten, langsame Chat-/Konfigurations-Renderzeiten und Einträge zur Browser-Reaktionsfähigkeit für lange Animationsframes oder lange Tasks, wenn der Browser diese PerformanceObserver-Eintragstypen bereitstellt.
- Protokolle: Live-Tail von Gateway-Dateiprotokollen mit Filter/Export (
logs.tail). - Aktualisierung: Paket-/Git-Aktualisierung ausführen und neu starten (
update.run) mit einem Neustartbericht, dann nach der Wiederverbindungupdate.statusabfragen, um die laufende Gateway-Version zu verifizieren.
Hinweise zum Cron-Jobs-Feld
- Für isolierte Jobs ist die Zustellung standardmäßig auf Ankündigungszusammenfassung gesetzt. Sie können auf „keine“ umstellen, wenn Sie nur interne Ausführungen wünschen.
- Kanal-/Zielfelder werden angezeigt, wenn „Ankündigen“ ausgewählt ist.
- Webhook-Modus verwendet
delivery.mode = "webhook"mitdelivery.to, das auf eine gültige HTTP(S)-Webhook-URL gesetzt ist. - Für Hauptsitzungs-Jobs sind die Zustellmodi Webhook und „keine“ verfügbar.
- Erweiterte Bearbeitungssteuerelemente umfassen Löschen-nach-Ausführung, Agent-Überschreibung löschen, Cron-Exakt-/Versatzoptionen, Agent-Modell-/Denk-Überschreibungen und Best-Effort-Zustellungsschalter.
- Die Formularvalidierung erfolgt inline mit Fehlern auf Feldebene; ungültige Werte deaktivieren die Speichern-Schaltfläche, bis sie korrigiert sind.
- Setzen Sie
cron.webhookToken, um ein dediziertes Bearer-Token zu senden; wenn es ausgelassen wird, wird der Webhook ohne Authentifizierungsheader gesendet. - Veralteter Fallback: gespeicherte Legacy-Jobs mit
notify: truekönnen weiterhincron.webhookverwenden, bis sie migriert wurden.
Chatverhalten
Sende- und Verlaufssemantik
chat.sendist nicht blockierend: Es bestätigt sofort mit{ runId, status: "started" }, und die Antwort wird überchat-Ereignisse gestreamt.- Chat-Uploads akzeptieren Bilder sowie Nicht-Video-Dateien. Bilder behalten den nativen Bildpfad; andere Dateien werden als verwaltete Medien gespeichert und im Verlauf als Anhangslinks angezeigt.
- Erneutes Senden mit demselben
idempotencyKeygibt während der Ausführung{ status: "in_flight" }und nach Abschluss{ status: "ok" }zurück. chat.history-Antworten sind zur UI-Sicherheit größenbegrenzt. Wenn Transkripteinträge zu groß sind, kann der Gateway lange Textfelder kürzen, umfangreiche Metadatenblöcke auslassen und übergroße Nachrichten durch einen Platzhalter ([chat.history omitted: message too large]) ersetzen.- Vom Assistant generierte Bilder werden als verwaltete Medienreferenzen persistiert und über authentifizierte Gateway-Medien-URLs wieder ausgeliefert, sodass Neuladevorgänge nicht davon abhängen, dass rohe base64-Bilddaten in der Chat-Verlaufsantwort verbleiben.
- Beim Rendern von
chat.historyentfernt die Control UI nur für die Anzeige bestimmte Inline-Direktiv-Tags aus sichtbarem Assistant-Text (zum Beispiel[[reply_to_*]]und[[audio_as_voice]]), Nur-Text-XML-Nutzlasten von Tool-Aufrufen (einschließlich<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>und gekürzter Tool-Aufrufblöcke) sowie durchgesickerte ASCII-/Vollbreiten-Modellsteuerungstoken und lässt Assistant-Einträge aus, deren gesamter sichtbarer Text nur das exakte stille TokenNO_REPLY/no_replyoder das Heartbeat-BestätigungstokenHEARTBEAT_OKist. - Während eines aktiven Sendevorgangs und der abschließenden Verlaufsaktualisierung hält die Chat-Ansicht lokale optimistische Benutzer-/Assistant-Nachrichten sichtbar, wenn
chat.historykurzzeitig einen älteren Snapshot zurückgibt; das kanonische Transkript ersetzt diese lokalen Nachrichten, sobald der Gateway-Verlauf aufgeholt hat. - Live-
chat-Ereignisse sind Zustellstatus, währendchat.historyaus dem dauerhaften Sitzungstranskript neu aufgebaut wird. Nach Tool-Abschlussereignissen lädt die Control UI den Verlauf neu und führt nur ein kleines optimistisches Ende zusammen; die Transkriptgrenze ist in WebChat dokumentiert. chat.injecthängt eine Assistant-Notiz an das Sitzungstranskript an und sendet einchat-Ereignis für reine UI-Aktualisierungen (kein Agentenlauf, keine Kanalzustellung).- Der Chat-Header zeigt den Agentenfilter vor der Sitzungsauswahl, und die Sitzungsauswahl ist auf den ausgewählten Agenten beschränkt. Beim Wechseln von Agenten werden nur Sitzungen angezeigt, die diesem Agenten zugeordnet sind; falls noch keine gespeicherten Dashboard-Sitzungen vorhanden sind, wird auf die Hauptsitzung dieses Agenten zurückgegriffen.
- Auf Desktop-Breiten bleiben Chat-Steuerelemente in einer kompakten Zeile und werden beim Herunterscrollen im Transkript eingeklappt; nach oben scrollen, zur Oberkante zurückkehren oder das Ende erreichen stellt die Steuerelemente wieder her.
- Aufeinanderfolgende doppelte reine Textnachrichten werden als eine Sprechblase mit Zähler-Badge gerendert. Nachrichten mit Bildern, Anhängen, Tool-Ausgaben oder Canvas-Vorschauen bleiben nicht eingeklappt.
- Die Modell- und Thinking-Auswahlfelder im Chat-Header patchen die aktive Sitzung sofort über
sessions.patch; sie sind persistente Sitzungsüberschreibungen, keine Sendeoptionen nur für einen einzelnen Turn. - Die Eingabe von
/newin der Control UI erstellt dieselbe neue Dashboard-Sitzung wie Neuer Chat und wechselt dorthin. Die Eingabe von/resetbehält den expliziten In-Place-Reset des Gateways für die aktuelle Sitzung bei. - Die Chat-Modellauswahl fordert die konfigurierte Modellansicht des Gateways an. Wenn
agents.defaults.modelsvorhanden ist, steuert diese Allowlist die Auswahl. Andernfalls zeigt die Auswahl explizitemodels.providers.*.models-Einträge plus Provider mit nutzbarer Authentifizierung. Der vollständige Katalog bleibt über den Debug-models.list-RPC mitview: "all"verfügbar. - Wenn aktuelle Gateway-Sitzungsnutzungsberichte hohen Kontextdruck anzeigen, zeigt der Chat-Composer-Bereich einen Kontexthinweis und bei empfohlenen Compaction-Stufen eine kompakte Schaltfläche, die den normalen Sitzung-Compaction-Pfad ausführt. Veraltete Token-Snapshots werden ausgeblendet, bis der Gateway wieder aktuelle Nutzung meldet.
Sprechmodus (Browser-Echtzeit)
Der Sprechmodus verwendet einen registrierten Echtzeit-Sprach-Provider. Konfigurieren Sie OpenAI mit talk.realtime.provider: "openai" plus talk.realtime.providers.openai.apiKey, oder konfigurieren Sie Google mit talk.realtime.provider: "google" plus talk.realtime.providers.google.apiKey. Der Browser erhält niemals einen normalen Provider-API-Schlüssel. OpenAI erhält ein kurzlebiges Realtime-Client-Secret für WebRTC. Google Live erhält ein einmalig verwendbares eingeschränktes Live-API-Auth-Token für eine Browser-WebSocket-Sitzung, wobei Anweisungen und Tool-Deklarationen vom Gateway im Token gesperrt werden. Provider, die nur eine Backend-Echtzeit-Bridge bereitstellen, laufen über den Gateway-Relay-Transport, sodass Zugangsdaten und Anbieter-Sockets serverseitig bleiben, während Browser-Audio über authentifizierte Gateway-RPCs läuft. Der Realtime-Sitzungsprompt wird vom Gateway zusammengesetzt; talk.client.create akzeptiert keine vom Aufrufer bereitgestellten Anweisungsüberschreibungen.
Im Chat-Composer ist die Sprechsteuerung die Wellen-Schaltfläche neben der Mikrofon-Diktat-Schaltfläche. Wenn Sprechen startet, zeigt die Composer-Statuszeile Connecting Talk..., danach Talk live, während Audio verbunden ist, oder Asking OpenClaw..., während ein Echtzeit-Tool-Aufruf über talk.client.toolCall das konfigurierte größere Modell konsultiert.
Maintainer-Live-Smoke: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts verifiziert den OpenAI-Browser-WebRTC-SDP-Austausch, die Einrichtung eines Google-Live-Browser-WebSocket mit eingeschränktem Token und den Gateway-Relay-Browseradapter mit gefälschten Mikrofonmedien. Der Befehl gibt nur den Provider-Status aus und protokolliert keine Secrets.
Stoppen und Abbrechen
- Klicken Sie auf Stop (ruft
chat.abortauf). - Während ein Lauf aktiv ist, werden normale Folgeanfragen in die Warteschlange gestellt. Klicken Sie bei einer wartenden Nachricht auf Steer, um diese Folgeanfrage in den laufenden Turn einzuspeisen.
- Geben Sie
/stopein (oder eigenständige Abbruchphrasen wiestop,stop action,stop run,stop openclaw,please stop), um out-of-band abzubrechen. chat.abortunterstützt{ sessionKey }(ohnerunId), um alle aktiven Läufe für diese Sitzung abzubrechen.
Beibehaltung von Abbruch-Teilinhalten
- Wenn ein Lauf abgebrochen wird, kann partieller Assistant-Text weiterhin in der UI angezeigt werden.
- Der Gateway persistiert abgebrochenen partiellen Assistant-Text im Transkriptverlauf, wenn gepufferte Ausgabe vorhanden ist.
- Persistierte Einträge enthalten Abbruchmetadaten, damit Transkriptverbraucher Abbruch-Teilinhalte von normaler Abschlussausgabe unterscheiden können.
PWA-Installation und Web Push
Die Control UI liefert ein manifest.webmanifest und einen Service Worker aus, sodass moderne Browser sie als eigenständige PWA installieren können. Web Push ermöglicht dem Gateway, die installierte PWA mit Benachrichtigungen zu wecken, auch wenn der Tab oder das Browserfenster nicht geöffnet ist.
| Oberfläche | Funktion |
|---|---|
ui/public/manifest.webmanifest |
PWA-Manifest. Browser bieten „App installieren“ an, sobald es erreichbar ist. |
ui/public/sw.js |
Service Worker, der push-Ereignisse und Benachrichtigungsklicks verarbeitet. |
push/vapid-keys.json (unter dem OpenClaw-State-Verzeichnis) |
Automatisch generiertes VAPID-Schlüsselpaar zum Signieren von Web-Push-Nutzlasten. |
push/web-push-subscriptions.json |
Persistierte Browser-Subscription-Endpunkte. |
Überschreiben Sie das VAPID-Schlüsselpaar über Umgebungsvariablen im Gateway-Prozess, wenn Sie Schlüssel fest pinnen möchten (für Multi-Host-Bereitstellungen, Secret-Rotation oder Tests):
OPENCLAW_VAPID_PUBLIC_KEYOPENCLAW_VAPID_PRIVATE_KEYOPENCLAW_VAPID_SUBJECT(standardmäßigmailto:openclaw@localhost)
Die Control UI verwendet diese bereichsbeschränkten Gateway-Methoden, um Browser-Subscriptions zu registrieren und zu testen:
push.web.vapidPublicKey— ruft den aktiven öffentlichen VAPID-Schlüssel ab.push.web.subscribe— registriert einenendpointpluskeys.p256dh/keys.auth.push.web.unsubscribe— entfernt einen registrierten Endpunkt.push.web.test— sendet eine Testbenachrichtigung an die Subscription des Aufrufers.
Gehostete Einbettungen
Assistant-Nachrichten können gehostete Webinhalte inline mit dem Shortcode [embed ...] rendern. Die iframe-Sandbox-Richtlinie wird durch gateway.controlUi.embedSandbox gesteuert:
strict
Deaktiviert die Skriptausführung in gehosteten Einbettungen.
scripts (default)
Erlaubt interaktive Einbettungen bei beibehaltener Origin-Isolation; dies ist die Standardeinstellung und reicht normalerweise für eigenständige Browser-Spiele/-Widgets aus.
trusted
Fügt allow-same-origin zusätzlich zu allow-scripts für Same-Site-Dokumente hinzu, die absichtlich stärkere Berechtigungen benötigen.
Beispiel:
{
gateway: {
controlUi: {
embedSandbox: "scripts",
},
},
}
Absolute externe http(s)-Einbettungs-URLs bleiben standardmäßig blockiert. Wenn Sie [embed url="https://..."] absichtlich zum Laden von Drittanbieter-Seiten verwenden möchten, setzen Sie gateway.controlUi.allowExternalEmbedUrls: true.
Breite von Chat-Nachrichten
Gruppierte Chat-Nachrichten verwenden standardmäßig eine gut lesbare maximale Breite. Bereitstellungen auf breiten Monitoren können sie überschreiben, ohne gebündeltes CSS zu patchen, indem gateway.controlUi.chatMessageMaxWidth gesetzt wird:
{
gateway: {
controlUi: {
chatMessageMaxWidth: "min(1280px, 82%)",
},
},
}
Der Wert wird validiert, bevor er den Browser erreicht. Unterstützte Werte umfassen einfache Längen und Prozentsätze wie 960px oder 82% sowie eingeschränkte Breiten-Ausdrücke mit min(...), max(...), clamp(...), calc(...) und fit-content(...).
Tailnet-Zugriff (empfohlen)
Integriertes Tailscale Serve (bevorzugt)
Lassen Sie den Gateway auf loopback und lassen Sie Tailscale Serve ihn per HTTPS proxyen:
openclaw gateway --tailscale serve
Öffnen Sie:
https://<magicdns>/(oder Ihr konfiguriertesgateway.controlUi.basePath)
Standardmäßig können Control-UI-/WebSocket-Serve-Anfragen über Tailscale-Identitätsheader (tailscale-user-login) authentifiziert werden, wenn gateway.auth.allowTailscale true ist. OpenClaw verifiziert die Identität, indem es die x-forwarded-for-Adresse mit tailscale whois auflöst und mit dem Header abgleicht, und akzeptiert diese nur, wenn die Anfrage loopback mit den x-forwarded-*-Headern von Tailscale erreicht. Für Control-UI-Bedienersitzungen mit Browser-Geräteidentität überspringt dieser verifizierte Serve-Pfad außerdem den Geräte-Pairing-Roundtrip; Browser ohne Gerät und Verbindungen mit Node-Rolle folgen weiterhin den normalen Geräteprüfungen. Setzen Sie gateway.auth.allowTailscale: false, wenn Sie selbst für Serve-Datenverkehr explizite Zugangsdaten mit Shared Secret verlangen möchten. Verwenden Sie dann gateway.auth.mode: "token" oder "password".
Für diesen asynchronen Serve-Identitätspfad werden fehlgeschlagene Authentifizierungsversuche für dieselbe Client-IP und denselben Authentifizierungsbereich vor Rate-Limit-Schreibvorgängen serialisiert. Gleichzeitige fehlerhafte Wiederholungen aus demselben Browser können daher bei der zweiten Anfrage retry later anzeigen, statt dass zwei einfache Nichtübereinstimmungen parallel konkurrieren.
An Tailnet binden + Token
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
Öffnen Sie dann:
http://<tailscale-ip>:18789/(oder Ihr konfiguriertesgateway.controlUi.basePath)
Fügen Sie das passende gemeinsame Geheimnis in die UI-Einstellungen ein (gesendet als connect.params.auth.token oder connect.params.auth.password).
Unsicheres HTTP
Wenn Sie das Dashboard über unverschlüsseltes HTTP öffnen (http://<lan-ip> oder http://<tailscale-ip>), läuft der Browser in einem nicht sicheren Kontext und blockiert WebCrypto. Standardmäßig blockiert OpenClaw Verbindungen zur Steuerungsoberfläche ohne Geräteidentität.
Dokumentierte Ausnahmen:
- Nur-localhost-Kompatibilität für unsicheres HTTP mit
gateway.controlUi.allowInsecureAuth=true - erfolgreiche Operator-Authentifizierung für die Steuerungsoberfläche über
gateway.auth.mode: "trusted-proxy" - Break-Glass-Option
gateway.controlUi.dangerouslyDisableDeviceAuth=true
Empfohlene Lösung: Verwenden Sie HTTPS (Tailscale Serve) oder öffnen Sie die UI lokal:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(auf dem Gateway-Host)
Verhalten des Umschalters für unsichere Authentifizierung
{
gateway: {
controlUi: { allowInsecureAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
allowInsecureAuth ist nur ein lokaler Kompatibilitätsumschalter:
- Er erlaubt localhost-Sitzungen der Steuerungsoberfläche, in nicht sicheren HTTP-Kontexten ohne Geräteidentität fortzufahren.
- Er umgeht keine Pairing-Prüfungen.
- Er lockert keine Anforderungen an die Geräteidentität für entfernte Verbindungen (nicht localhost).
Nur für Break-Glass
{
gateway: {
controlUi: { dangerouslyDisableDeviceAuth: true },
bind: "tailnet",
auth: { mode: "token", token: "replace-me" },
},
}
Hinweis zu Trusted Proxy
- Erfolgreiche Trusted-Proxy-Authentifizierung kann Operator-Sitzungen der Steuerungsoberfläche ohne Geräteidentität zulassen.
- Dies gilt nicht für node-role-Sitzungen der Steuerungsoberfläche.
- Same-host-loopback-Reverse-Proxys erfüllen trusted-proxy-Authentifizierung weiterhin nicht; siehe Trusted-Proxy-Authentifizierung.
Siehe Tailscale für Hinweise zur HTTPS-Einrichtung.
Content-Security-Policy
Die Steuerungsoberfläche wird mit einer strikten img-src-Richtlinie ausgeliefert: Nur Assets mit gleichem Ursprung, data:-URLs und lokal erzeugte blob:-URLs sind erlaubt. Entfernte http(s)- und protokollrelative Bild-URLs werden vom Browser abgelehnt und lösen keine Netzwerkabrufe aus.
Was das in der Praxis bedeutet:
- Avatare und Bilder, die unter relativen Pfaden bereitgestellt werden (zum Beispiel
/avatars/<id>), werden weiterhin gerendert, einschließlich authentifizierter Avatar-Routen, die die UI abruft und in lokaleblob:-URLs umwandelt. - Inline-
data:image/...-URLs werden weiterhin gerendert (nützlich für Payloads innerhalb des Protokolls). - Lokale
blob:-URLs, die von der Steuerungsoberfläche erstellt wurden, werden weiterhin gerendert. - Entfernte Avatar-URLs, die von Kanal-Metadaten ausgegeben werden, werden in den Avatar-Helfern der Steuerungsoberfläche entfernt und durch das integrierte Logo/Badge ersetzt, sodass ein kompromittierter oder bösartiger Kanal keine beliebigen entfernten Bildabrufe aus dem Browser eines Operators erzwingen kann.
Sie müssen nichts ändern, um dieses Verhalten zu erhalten — es ist immer aktiviert und nicht konfigurierbar.
Authentifizierung der Avatar-Route
Wenn Gateway-Authentifizierung konfiguriert ist, verlangt der Avatar-Endpunkt der Steuerungsoberfläche dasselbe Gateway-Token wie der Rest der API:
GET /avatar/<agentId>gibt das Avatar-Bild nur an authentifizierte Aufrufer zurück.GET /avatar/<agentId>?meta=1gibt die Avatar-Metadaten nach derselben Regel zurück.- Nicht authentifizierte Anfragen an eine der beiden Routen werden abgelehnt (entsprechend der benachbarten Assistant-Media-Route). Dadurch wird verhindert, dass die Avatar-Route auf Hosts, die ansonsten geschützt sind, die Agent-Identität preisgibt.
- Die Steuerungsoberfläche selbst leitet das Gateway-Token beim Abrufen von Avataren als Bearer-Header weiter und verwendet authentifizierte Blob-URLs, sodass das Bild weiterhin in Dashboards gerendert wird.
Wenn Sie Gateway-Authentifizierung deaktivieren (auf gemeinsam genutzten Hosts nicht empfohlen), wird auch die Avatar-Route nicht authentifiziert, entsprechend dem Rest des Gateway.
Authentifizierung der Assistant-Media-Route
Wenn Gateway-Authentifizierung konfiguriert ist, verwenden lokale Medienvorschauen des Assistenten eine zweistufige Route:
GET /__openclaw__/assistant-media?meta=1&source=<path>erfordert die normale Operator-Authentifizierung der Steuerungsoberfläche. Der Browser sendet beim Prüfen der Verfügbarkeit das Gateway-Token als Bearer-Header.- Erfolgreiche Metadatenantworten enthalten ein kurzlebiges
mediaTicket, das auf genau diesen Quellpfad beschränkt ist. - Vom Browser gerenderte Bild-, Audio-, Video- und Dokument-URLs verwenden
mediaTicket=<ticket>statt des aktiven Gateway-Tokens oder Passworts. Das Ticket läuft schnell ab und kann keine andere Quelle autorisieren.
Dadurch bleibt normales Medienrendering mit nativen Browser-Medienelementen kompatibel, ohne wiederverwendbare Gateway-Zugangsdaten in sichtbare Medien-URLs zu setzen.
UI erstellen
Das Gateway stellt statische Dateien aus dist/control-ui bereit. Erstellen Sie sie mit:
pnpm ui:build
Optionale absolute Basis (wenn Sie feste Asset-URLs wünschen):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
Für lokale Entwicklung (separater Entwicklungsserver):
pnpm ui:dev
Richten Sie die UI dann auf Ihre Gateway-WS-URL aus (z. B. ws://127.0.0.1:18789).
Debugging/Testen: Entwicklungsserver + entferntes Gateway
Die Steuerungsoberfläche besteht aus statischen Dateien; das WebSocket-Ziel ist konfigurierbar und kann vom HTTP-Ursprung abweichen. Das ist praktisch, wenn Sie den Vite-Entwicklungsserver lokal verwenden möchten, das Gateway aber anderswo läuft.
UI-Entwicklungsserver starten
pnpm ui:dev
Mit gatewayUrl öffnen
http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
Optionale einmalige Authentifizierung (falls erforderlich):
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
Hinweise
gatewayUrlwird nach dem Laden in localStorage gespeichert und aus der URL entfernt.- Wenn Sie einen vollständigen
ws://- oderwss://-Endpunkt übergatewayUrlübergeben, URL-kodieren Sie dengatewayUrl-Wert, damit der Browser die Query-Zeichenfolge korrekt parst. tokensollte nach Möglichkeit über das URL-Fragment (#token=...) übergeben werden. Fragmente werden nicht an den Server gesendet, wodurch Lecks in Anfrageprotokollen und Referern vermieden werden. Alte?token=-Query-Parameter werden aus Kompatibilitätsgründen weiterhin einmal importiert, aber nur als Fallback, und unmittelbar nach dem Bootstrap entfernt.passwordwird nur im Speicher gehalten.- Wenn
gatewayUrlgesetzt ist, fällt die UI nicht auf Konfigurations- oder Umgebungs-Zugangsdaten zurück. Geben Sietoken(oderpassword) explizit an. Fehlende explizite Zugangsdaten sind ein Fehler. - Verwenden Sie
wss://, wenn sich das Gateway hinter TLS befindet (Tailscale Serve, HTTPS-Proxy usw.). gatewayUrlwird nur in einem Top-Level-Fenster akzeptiert (nicht eingebettet), um Clickjacking zu verhindern.- Nicht-loopback-Bereitstellungen der Steuerungsoberfläche müssen
gateway.controlUi.allowedOriginsexplizit setzen (vollständige Ursprünge). Dies schließt entfernte Entwicklungssetups ein. - Der Gateway-Start kann lokale Ursprünge wie
http://localhost:<port>undhttp://127.0.0.1:<port>aus dem effektiven Laufzeit-Bind und -Port setzen, aber entfernte Browser-Ursprünge benötigen weiterhin explizite Einträge. - Verwenden Sie
gateway.controlUi.allowedOrigins: ["*"]nur für streng kontrollierte lokale Tests. Es bedeutet, jeden Browser-Ursprung zuzulassen, nicht „den Host abzugleichen, den ich gerade verwende“. gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=trueaktiviert den Fallback-Modus für Host-Header-Ursprünge, ist aber ein gefährlicher Sicherheitsmodus.
Beispiel:
{
gateway: {
controlUi: {
allowedOrigins: ["http://localhost:5173"],
},
},
}
Details zur Einrichtung des Fernzugriffs: Fernzugriff.
Verwandte Themen
- Dashboard — Gateway-Dashboard
- Health Checks — Gateway-Zustandsüberwachung
- TUI — Terminal-Benutzeroberfläche
- WebChat — browserbasierte Chat-Oberfläche