Interfaz de control (navegador)
La interfaz de control es una pequeña aplicación de una sola página Vite + Lit servida por el Gateway:- predeterminado:
http://<host>:18789/ - prefijo opcional: configura
gateway.controlUi.basePath(por ejemplo/openclaw)
Apertura rápida (local)
Si el Gateway se está ejecutando en el mismo equipo, abre: Si la página no carga, inicia primero el Gateway:openclaw gateway.
La autenticación se proporciona durante el handshake del WebSocket mediante:
connect.params.auth.tokenconnect.params.auth.password- encabezados de identidad de Tailscale Serve cuando
gateway.auth.allowTailscale: true - encabezados de identidad de proxy de confianza cuando
gateway.auth.mode: "trusted-proxy"
gateway.auth.mode es "password".
Emparejamiento de dispositivos (primera conexión)
Cuando te conectas a la interfaz de control desde un navegador o dispositivo nuevo, el Gateway requiere una aprobación de emparejamiento de una sola vez, incluso si estás en la misma Tailnet congateway.auth.allowTailscale: true. Esta es una medida de seguridad para evitar
accesos no autorizados.
Lo que verás: “disconnected (1008): pairing required”
Para aprobar el dispositivo:
requestId.
Vuelve a ejecutar openclaw devices list antes de aprobar.
Una vez aprobado, el dispositivo se recuerda y no requerirá una nueva aprobación a menos
que lo revoques con openclaw devices revoke --device <id> --role <role>. Consulta
CLI de Devices para rotación de tokens y revocación.
Notas:
- Las conexiones directas del navegador local por loopback (
127.0.0.1/localhost) se aprueban automáticamente. - Las conexiones del navegador por Tailnet y LAN siguen requiriendo aprobación explícita, incluso cuando se originan desde la misma máquina.
- Cada perfil del navegador genera un ID de dispositivo único, por lo que cambiar de navegador o borrar los datos del navegador requerirá volver a emparejar.
Compatibilidad de idiomas
La interfaz de control puede localizarse en la primera carga según la configuración regional de tu navegador, y puedes sobrescribirla más tarde desde el selector de idioma de la tarjeta Access.- Configuraciones regionales admitidas:
en,zh-CN,zh-TW,pt-BR,de,es - Las traducciones que no están en inglés se cargan de forma diferida en el navegador.
- La configuración regional seleccionada se guarda en el almacenamiento del navegador y se reutiliza en futuras visitas.
- Las claves de traducción faltantes vuelven al inglés.
Qué puede hacer (hoy)
- Chatear con el modelo mediante el WS del Gateway (
chat.history,chat.send,chat.abort,chat.inject) - Transmitir llamadas a herramientas + tarjetas de salida de herramientas en vivo en el chat (eventos del agente)
- Canales: estado, inicio de sesión por QR y configuración por canal de canales integrados y de plugins incluidos/externos (
channels.status,web.login.*,config.patch) - Instancias: lista de presencia + actualización (
system-presence) - Sesiones: lista + sobrescrituras por sesión de modelo/razonamiento/rápido/detallado/reasoning (
sessions.list,sessions.patch) - Trabajos cron: listar/agregar/editar/ejecutar/habilitar/deshabilitar + historial de ejecuciones (
cron.*) - Skills: estado, habilitar/deshabilitar, instalar, actualizaciones de claves de API (
skills.*) - Nodos: lista + capacidades (
node.list) - Aprobaciones de Exec: editar listas de permitidos del gateway o nodo + política ask para
exec host=gateway/node(exec.approvals.*) - Configuración: ver/editar
~/.openclaw/openclaw.json(config.get,config.set) - Configuración: aplicar + reiniciar con validación (
config.apply) y activar la última sesión activa - Las escrituras de configuración incluyen una protección de hash base para evitar sobrescribir ediciones concurrentes
- Las escrituras de configuración (
config.set/config.apply/config.patch) también validan previamente la resolución activa de SecretRef para referencias en la carga útil de configuración enviada; las referencias activas enviadas no resueltas se rechazan antes de la escritura - Esquema de configuración + renderizado de formularios (
config.schema/config.schema.lookup, incluidostitle/descriptionde campos, sugerencias de UI coincidentes, resúmenes inmediatos de elementos secundarios, metadatos de documentación en nodos anidados de objeto/comodín/arreglo/composición, además de esquemas de plugins y canales cuando están disponibles); el editor JSON sin formato está disponible solo cuando la instantánea tiene un round-trip seguro del texto sin formato - Si una instantánea no puede hacer round-trip seguro del texto sin formato, la interfaz de control fuerza el modo Form y desactiva el modo Raw para esa instantánea
- Los valores de objeto SecretRef estructurados se renderizan como solo lectura en las entradas de texto del formulario para evitar corrupción accidental de objeto a cadena
- Depuración: instantáneas de estado/health/models + registro de eventos + llamadas RPC manuales (
status,health,models.list) - Registros: tail en vivo de los archivos de registro del gateway con filtro/exportación (
logs.tail) - Actualización: ejecutar una actualización de paquete/git + reinicio (
update.run) con un informe de reinicio
- Para trabajos aislados, la entrega usa de forma predeterminada resumen anunciado. Puedes cambiar a none si quieres ejecuciones solo internas.
- Los campos de canal/destino aparecen cuando se selecciona announce.
- El modo webhook usa
delivery.mode = "webhook"condelivery.toestablecido en una URL de webhook HTTP(S) válida. - Para trabajos de sesión principal, están disponibles los modos de entrega webhook y none.
- Los controles de edición avanzada incluyen delete-after-run, borrar la sobrescritura del agente, opciones de exact/stagger de cron, sobrescrituras de modelo/razonamiento del agente y alternancias de entrega best-effort.
- La validación del formulario es en línea con errores a nivel de campo; los valores no válidos desactivan el botón de guardar hasta corregirlos.
- Configura
cron.webhookTokenpara enviar un token bearer dedicado; si se omite, el webhook se envía sin encabezado de autenticación. - Alternativa obsoleta: los trabajos heredados almacenados con
notify: truetodavía pueden usarcron.webhookhasta que se migren.
Comportamiento del chat
chat.sendes no bloqueante: reconoce inmediatamente con{ runId, status: "started" }y la respuesta se transmite mediante eventoschat.- Volver a enviar con la misma
idempotencyKeydevuelve{ status: "in_flight" }mientras se está ejecutando, y{ status: "ok" }tras completarse. - Las respuestas de
chat.historytienen tamaño limitado por seguridad de la UI. Cuando las entradas de la transcripción son demasiado grandes, Gateway puede truncar campos de texto largos, omitir bloques pesados de metadatos y reemplazar mensajes sobredimensionados por un marcador ([chat.history omitted: message too large]). chat.historytambién elimina de la vista el texto visible del asistente de etiquetas inline de directivas solo para visualización (por ejemplo[[reply_to_*]]y[[audio_as_voice]]), cargas XML de llamadas a herramientas en texto plano (incluidas<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>y bloques truncados de llamadas a herramientas), y tokens de control del modelo filtrados en ASCII/ancho completo, y omite entradas del asistente cuyo texto visible completo sea solo el token silencioso exactoNO_REPLY/no_reply.chat.injectagrega una nota del asistente a la transcripción de la sesión y emite un eventochatpara actualizaciones solo de la UI (sin ejecución del agente, sin entrega al canal).- Los selectores de modelo y razonamiento del encabezado del chat aplican parches inmediatamente a la sesión activa mediante
sessions.patch; son sobrescrituras persistentes de la sesión, no opciones de envío para un solo turno. - Detener:
- Haz clic en Stop (llama a
chat.abort) - Escribe
/stop(o frases de aborto independientes comostop,stop action,stop run,stop openclaw,please stop) para abortar fuera de banda chat.abortadmite{ sessionKey }(sinrunId) para abortar todas las ejecuciones activas de esa sesión
- Haz clic en Stop (llama a
- Conservación parcial de abortos:
- Cuando se aborta una ejecución, el texto parcial del asistente todavía puede mostrarse en la UI
- Gateway conserva el texto parcial abortado del asistente en el historial de la transcripción cuando existe salida en buffer
- Las entradas conservadas incluyen metadatos de aborto para que los consumidores de la transcripción puedan distinguir las partes abortadas de la salida completada normalmente
Acceso por Tailnet (recomendado)
Tailscale Serve integrado (preferido)
Mantén el Gateway en loopback y deja que Tailscale Serve lo proxifique con HTTPS:https://<magicdns>/(o tugateway.controlUi.basePathconfigurado)
tailscale-user-login) cuando gateway.auth.allowTailscale es true. OpenClaw
verifica la identidad resolviendo la dirección x-forwarded-for con
tailscale whois y comparándola con el encabezado, y solo acepta esto cuando la
solicitud llega a loopback con los encabezados x-forwarded-* de Tailscale. Configura
gateway.auth.allowTailscale: false si quieres exigir credenciales explícitas de secreto compartido
incluso para tráfico de Serve. Entonces usa gateway.auth.mode: "token" o
"password".
Para esa ruta asíncrona de identidad de Serve, los intentos fallidos de autenticación del mismo IP
de cliente y ámbito de autenticación se serializan antes de las escrituras del límite de tasa. Por lo tanto,
los reintentos malos concurrentes desde el mismo navegador pueden mostrar retry later en la segunda solicitud
en lugar de dos discrepancias simples compitiendo en paralelo.
La autenticación de Serve sin token asume que el host del gateway es de confianza. Si puede ejecutarse
código local no confiable en ese host, exige autenticación por token/contraseña.
Bind a tailnet + token
http://<tailscale-ip>:18789/(o tugateway.controlUi.basePathconfigurado)
connect.params.auth.token o connect.params.auth.password).
HTTP inseguro
Si abres el dashboard mediante HTTP simple (http://<lan-ip> o http://<tailscale-ip>),
el navegador se ejecuta en un contexto no seguro y bloquea WebCrypto. De forma predeterminada,
OpenClaw bloquea las conexiones de la interfaz de control sin identidad de dispositivo.
Excepciones documentadas:
- compatibilidad con HTTP inseguro solo localhost con
gateway.controlUi.allowInsecureAuth=true - autenticación correcta del operador de la interfaz de control mediante
gateway.auth.mode: "trusted-proxy" - solución de emergencia
gateway.controlUi.dangerouslyDisableDeviceAuth=true
https://<magicdns>/(Serve)http://127.0.0.1:18789/(en el host del gateway)
allowInsecureAuth es solo una alternancia local de compatibilidad:
- Permite que las sesiones de la interfaz de control de localhost continúen sin identidad de dispositivo en contextos HTTP no seguros.
- No omite las comprobaciones de emparejamiento.
- No relaja los requisitos remotos (no localhost) de identidad del dispositivo.
dangerouslyDisableDeviceAuth desactiva las comprobaciones de identidad de dispositivo de la interfaz de control y supone una
grave degradación de seguridad. Reviértelo rápidamente después del uso de emergencia.
Nota sobre proxy de confianza:
- una autenticación correcta mediante trusted-proxy puede admitir sesiones de operador de la interfaz de control sin identidad de dispositivo
- esto no se extiende a las sesiones de la interfaz de control con rol de nodo
- los proxies inversos loopback del mismo host siguen sin satisfacer la autenticación trusted-proxy; consulta Autenticación Trusted Proxy
Compilación de la UI
El Gateway sirve archivos estáticos desdedist/control-ui. Compílalos con:
ws://127.0.0.1:18789).
Depuración/pruebas: servidor de desarrollo + Gateway remoto
La interfaz de control son archivos estáticos; el objetivo del WebSocket es configurable y puede ser distinto del origen HTTP. Esto es útil cuando quieres el servidor de desarrollo de Vite localmente pero el Gateway se ejecuta en otro lugar.- Inicia el servidor de desarrollo de la UI:
pnpm ui:dev - Abre una URL como:
gatewayUrlse almacena enlocalStoragedespués de la carga y se elimina de la URL.tokendebe pasarse mediante el fragmento de la URL (#token=...) siempre que sea posible. Los fragmentos no se envían al servidor, lo que evita filtraciones en registros de solicitudes y Referer. Los parámetros heredados de consulta?token=todavía se importan una vez por compatibilidad, pero solo como alternativa, y se eliminan inmediatamente después del bootstrap.passwordse conserva solo en memoria.- Cuando
gatewayUrlestá configurado, la UI no recurre a credenciales de configuración ni de entorno. Proporcionatoken(opassword) explícitamente. La ausencia de credenciales explícitas es un error. - Usa
wss://cuando el Gateway esté detrás de TLS (Tailscale Serve, proxy HTTPS, etc.). gatewayUrlsolo se acepta en una ventana de nivel superior (no incrustada) para evitar clickjacking.- Las implementaciones de la interfaz de control que no son loopback deben configurar
gateway.controlUi.allowedOriginsexplícitamente (orígenes completos). Esto incluye configuraciones remotas de desarrollo. - No uses
gateway.controlUi.allowedOrigins: ["*"]salvo en pruebas locales estrictamente controladas. Significa permitir cualquier origen del navegador, no “hacer coincidir cualquier host que esté usando”. gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=truehabilita el modo alternativo de origen basado en encabezado Host, pero es un modo de seguridad peligroso.
Relacionado
- Dashboard — dashboard del gateway
- WebChat — interfaz de chat basada en navegador
- TUI — interfaz de usuario de terminal
- Health Checks — monitorización del estado del gateway