Protocolo de Gateway (WebSocket)
El protocolo WS de Gateway es el único plano de control + transporte de nodos para OpenClaw. Todos los clientes (CLI, interfaz web, app de macOS, nodos iOS/Android, nodos sin interfaz) se conectan por WebSocket y declaran su rol + alcance en el momento del handshake.Transporte
- WebSocket, tramas de texto con cargas útiles JSON.
- La primera trama debe ser una solicitud
connect.
Handshake (connect)
Gateway → Cliente (desafío previo a la conexión):
server, features, snapshot y policy son obligatorios según el esquema
(src/gateway/protocol/schema/frames.ts). canvasHostUrl es opcional. auth
informa el rol/alcances negociados cuando están disponibles, e incluye deviceToken
cuando el gateway emite uno.
Cuando no se emite ningún token de dispositivo, hello-ok.auth todavía puede informar los
permisos negociados:
hello-ok también incluye:
hello-ok.auth también puede incluir entradas de rol
adicionales acotadas en deviceTokens:
scopes: [] y cualquier token de operador transferido sigue acotado a la lista de permisos del operador
de arranque (operator.approvals, operator.read,
operator.talk.secrets, operator.write). Las comprobaciones de alcance de arranque siguen con prefijo de rol:
las entradas de operador solo satisfacen solicitudes de operador, y los roles que no son de operador
siguen necesitando alcances bajo el prefijo de su propio rol.
Ejemplo de nodo
Enmarcado
- Solicitud:
{type:"req", id, method, params} - Respuesta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Roles + alcances
Roles
operator= cliente del plano de control (CLI/UI/automatización).node= host de capacidades (camera/screen/canvas/system.run).
Alcances (operator)
Alcances comunes:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config con includeSecrets: true requiere operator.talk.secrets
(o operator.admin).
Los métodos RPC de Gateway registrados por Plugin pueden solicitar su propio alcance de operador, pero
los prefijos administrativos centrales reservados (config.*, exec.approvals.*, wizard.*,
update.*) siempre se resuelven como operator.admin.
El alcance del método es solo el primer filtro. Algunos comandos slash alcanzados mediante
chat.send aplican comprobaciones más estrictas a nivel de comando además de eso. Por ejemplo, las escrituras
persistentes de /config set y /config unset requieren operator.admin.
node.pair.approve también tiene una comprobación adicional de alcance en el momento de la aprobación además del
alcance base del método:
- solicitudes sin comando:
operator.pairing - solicitudes con comandos de nodo que no son
exec:operator.pairing+operator.write - solicitudes que incluyen
system.run,system.run.prepareosystem.which:operator.pairing+operator.admin
caps/commands/permissions (node)
Los nodos declaran reclamaciones de capacidad en el momento de conectarse:
caps: categorías de capacidad de alto nivel.commands: lista permitida de comandos para invocación.permissions: controles granulares (por ejemplo,screen.record,camera.capture).
Presencia
system-presencedevuelve entradas indexadas por identidad de dispositivo.- Las entradas de presencia incluyen
deviceId,rolesyscopespara que las UI puedan mostrar una sola fila por dispositivo incluso cuando se conecta tanto como operator como node.
Familias comunes de métodos RPC
Esta página no es un volcado completo generado, pero la superficie WS pública es más amplia que los ejemplos de handshake/autenticación anteriores. Estas son las principales familias de métodos que Gateway expone hoy.hello-ok.features.methods es una lista conservadora de descubrimiento construida a partir de
src/gateway/server-methods-list.ts más las exportaciones de métodos de plugins/canales cargados.
Trátela como descubrimiento de funciones, no como un volcado generado de cada helper invocable
implementado en src/gateway/server-methods/*.ts.
Sistema e identidad
healthdevuelve la instantánea de estado del gateway almacenada en caché o recién sondeada.statusdevuelve el resumen del gateway al estilo/status; los campos sensibles se incluyen solo para clientesoperatorcon alcance de administrador.gateway.identity.getdevuelve la identidad del dispositivo del gateway usada por los flujos de relay y emparejamiento.system-presencedevuelve la instantánea de presencia actual para los dispositivosoperator/nodeconectados.system-eventagrega un evento del sistema y puede actualizar/transmitir el contexto de presencia.last-heartbeatdevuelve el evento Heartbeat persistido más reciente.set-heartbeatsactiva o desactiva el procesamiento de Heartbeat en el gateway.
Modelos y uso
models.listdevuelve el catálogo de modelos permitido en tiempo de ejecución.usage.statusdevuelve resúmenes de ventanas de uso/restante de cuota del proveedor.usage.costdevuelve resúmenes agregados de uso de costo para un intervalo de fechas.doctor.memory.statusdevuelve la preparación de memoria vectorial/embeddings para el espacio de trabajo del agente predeterminado activo.sessions.usagedevuelve resúmenes de uso por sesión.sessions.usage.timeseriesdevuelve series temporales de uso para una sesión.sessions.usage.logsdevuelve entradas del registro de uso para una sesión.
Canales y helpers de inicio de sesión
channels.statusdevuelve resúmenes de estado de canales/plugins integrados + empaquetados.channels.logoutcierra la sesión de un canal/cuenta específicos cuando el canal admite cierre de sesión.web.login.startinicia un flujo de inicio de sesión por QR/web para el proveedor del canal web actual compatible con QR.web.login.waitespera a que ese flujo de inicio de sesión por QR/web finalice y arranca el canal si se completa con éxito.push.testenvía una notificación push APNs de prueba a un nodo iOS registrado.voicewake.getdevuelve los disparadores de palabras de activación almacenados.voicewake.setactualiza los disparadores de palabras de activación y transmite el cambio.
Mensajería y registros
sendes el RPC de entrega saliente directa para envíos dirigidos a canal/cuenta/hilo fuera del ejecutor de chat.logs.taildevuelve la cola del archivo de registros configurado del gateway con cursor/límite y controles de bytes máximos.
Talk y TTS
talk.configdevuelve la carga útil de configuración efectiva de Talk;includeSecretsrequiereoperator.talk.secrets(ooperator.admin).talk.modeestablece/transmite el estado actual del modo Talk para los clientes de WebChat/Control UI.talk.speaksintetiza voz a través del proveedor de voz activo de Talk.tts.statusdevuelve el estado de activación de TTS, el proveedor activo, los proveedores de respaldo y el estado de configuración del proveedor.tts.providersdevuelve el inventario visible de proveedores TTS.tts.enableytts.disableactivan y desactivan el estado de preferencias de TTS.tts.setProvideractualiza el proveedor TTS preferido.tts.convertejecuta una conversión puntual de texto a voz.
Secretos, configuración, actualización y asistente
secrets.reloadvuelve a resolver los SecretRef activos e intercambia el estado de secretos en tiempo de ejecución solo si todo se completa correctamente.secrets.resolveresuelve asignaciones de secretos dirigidas a comandos para un conjunto específico de comandos/objetivos.config.getdevuelve la instantánea y el hash de la configuración actual.config.setescribe una carga útil de configuración validada.config.patchfusiona una actualización parcial de la configuración.config.applyvalida y reemplaza la carga útil de configuración completa.config.schemadevuelve la carga útil del esquema de configuración en vivo usada por Control UI y las herramientas CLI: esquema,uiHints, versión y metadatos de generación, incluidos metadatos de esquema de plugins + canales cuando el entorno de ejecución puede cargarlos. El esquema incluye metadatos de campotitle/descriptionderivados de las mismas etiquetas y el mismo texto de ayuda usados por la UI, incluidas las ramas anidadas de composición de objetos, comodines, elementos de array yanyOf/oneOf/allOfcuando existe documentación de campo coincidente.config.schema.lookupdevuelve una carga útil de búsqueda acotada a ruta para una ruta de configuración: ruta normalizada, un nodo superficial del esquema,hint+hintPathcoincidentes y resúmenes inmediatos de hijos para la exploración detallada en UI/CLI.- Los nodos de esquema de búsqueda conservan la documentación orientada al usuario y los campos comunes de validación:
title,description,type,enum,const,format,pattern, límites numéricos/de cadenas/de arrays/de objetos y banderas booleanas comoadditionalProperties,deprecated,readOnly,writeOnly. - Los resúmenes de hijos exponen
key,pathnormalizada,type,required,hasChildren, además dehint/hintPathcoincidentes.
- Los nodos de esquema de búsqueda conservan la documentación orientada al usuario y los campos comunes de validación:
update.runejecuta el flujo de actualización del gateway y programa un reinicio solo cuando la propia actualización se completó correctamente.wizard.start,wizard.next,wizard.statusywizard.cancelexponen el asistente de incorporación a través de WS RPC.
Familias principales existentes
Agente y helpers de espacio de trabajo
agents.listdevuelve las entradas de agente configuradas.agents.create,agents.updateyagents.deleteadministran los registros de agentes y la conexión del espacio de trabajo.agents.files.list,agents.files.getyagents.files.setadministran los archivos del espacio de trabajo de arranque expuestos para un agente.agent.identity.getdevuelve la identidad efectiva del asistente para un agente o sesión.agent.waitespera a que una ejecución termine y devuelve la instantánea terminal cuando está disponible.
Control de sesión
sessions.listdevuelve el índice de sesión actual.sessions.subscribeysessions.unsubscribeactivan o desactivan las suscripciones a eventos de cambio de sesión para el cliente WS actual.sessions.messages.subscribeysessions.messages.unsubscribeactivan o desactivan las suscripciones a eventos de transcripción/mensaje para una sesión.sessions.previewdevuelve vistas previas acotadas de la transcripción para claves de sesión específicas.sessions.resolveresuelve o canonicaliza un destino de sesión.sessions.createcrea una nueva entrada de sesión.sessions.sendenvía un mensaje a una sesión existente.sessions.steeres la variante de interrumpir y redirigir para una sesión activa.sessions.abortaborta el trabajo activo de una sesión.sessions.patchactualiza metadatos/anulaciones de la sesión.sessions.reset,sessions.deleteysessions.compactrealizan tareas de mantenimiento de la sesión.sessions.getdevuelve la fila completa de la sesión almacenada.- la ejecución del chat sigue usando
chat.history,chat.send,chat.abortychat.inject. chat.historyestá normalizado para visualización para clientes UI: las etiquetas de directiva en línea se eliminan del texto visible, las cargas útiles XML de llamada de herramienta en texto plano (incluidas<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>y bloques de llamada de herramienta truncados) y los tokens de control del modelo filtrados en ASCII/ancho completo se eliminan, las filas del asistente compuestas únicamente por tokens silenciosos comoNO_REPLY/no_replyexactos se omiten, y las filas sobredimensionadas pueden reemplazarse por marcadores de posición.
Emparejamiento de dispositivos y tokens de dispositivo
device.pair.listdevuelve los dispositivos emparejados pendientes y aprobados.device.pair.approve,device.pair.rejectydevice.pair.removeadministran los registros de emparejamiento de dispositivos.device.token.rotaterota un token de dispositivo emparejado dentro de sus límites aprobados de rol y alcance.device.token.revokerevoca un token de dispositivo emparejado.
Emparejamiento de nodos, invocación y trabajo pendiente
node.pair.request,node.pair.list,node.pair.approve,node.pair.rejectynode.pair.verifycubren el emparejamiento de nodos y la verificación de arranque.node.listynode.describedevuelven el estado de nodos conocidos/conectados.node.renameactualiza una etiqueta de nodo emparejado.node.invokereenvía un comando a un nodo conectado.node.invoke.resultdevuelve el resultado de una solicitud de invocación.node.eventtransporta eventos originados en el nodo de vuelta al gateway.node.canvas.capability.refreshactualiza tokens acotados de capacidad de canvas.node.pending.pullynode.pending.ackson las API de cola para nodos conectados.node.pending.enqueueynode.pending.drainadministran trabajo pendiente duradero para nodos desconectados o fuera de línea.
Familias de aprobación
exec.approval.request,exec.approval.get,exec.approval.listyexec.approval.resolvecubren solicitudes puntuales de aprobación deexecmás la búsqueda/repetición de aprobaciones pendientes.exec.approval.waitDecisionespera una aprobaciónexecpendiente y devuelve la decisión final (onullen caso de tiempo de espera agotado).exec.approvals.getyexec.approvals.setadministran instantáneas de la política de aprobaciónexecdel gateway.exec.approvals.node.getyexec.approvals.node.setadministran la política local de aprobaciónexecdel nodo mediante comandos de relay del nodo.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionyplugin.approval.resolvecubren flujos de aprobación definidos por Plugin.
Otras familias principales
- automatización:
wakeprograma una inyección de texto de activación inmediata o en el siguiente Heartbeatcron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runs
- Skills/herramientas:
commands.list,skills.*,tools.catalog,tools.effective
Familias comunes de eventos
chat: actualizaciones de chat de la UI, comochat.injecty otros eventos de chat solo de transcripción.session.messageysession.tool: actualizaciones de transcripción/flujo de eventos para una sesión suscrita.sessions.changed: cambió el índice de sesión o sus metadatos.presence: actualizaciones de la instantánea de presencia del sistema.tick: evento periódico de keepalive / actividad.health: actualización de la instantánea de estado del gateway.heartbeat: actualización del flujo de eventos Heartbeat.cron: evento de cambio de ejecución/trabajo de Cron.shutdown: notificación de apagado del gateway.node.pair.requested/node.pair.resolved: ciclo de vida del emparejamiento de nodos.node.invoke.request: difusión de solicitud de invocación de nodo.device.pair.requested/device.pair.resolved: ciclo de vida del dispositivo emparejado.voicewake.changed: cambió la configuración de disparadores de palabra de activación.exec.approval.requested/exec.approval.resolved: ciclo de vida de aprobación deexec.plugin.approval.requested/plugin.approval.resolved: ciclo de vida de aprobación de Plugin.
Métodos helper de nodo
- Los nodos pueden llamar a
skills.binspara obtener la lista actual de ejecutables de Skills para comprobaciones de permiso automático.
Métodos helper de operador
- Los operadores pueden llamar a
commands.list(operator.read) para obtener el inventario de comandos en tiempo de ejecución para un agente.agentIdes opcional; omítalo para leer el espacio de trabajo del agente predeterminado.scopecontrola a qué superficie apunta elnameprincipal:textdevuelve el token principal de comando de texto sin la/inicialnativey la ruta predeterminadabothdevuelven nombres nativos compatibles con proveedor cuando están disponibles
textAliasescontiene alias slash exactos como/modely/m.nativeNamecontiene el nombre de comando nativo compatible con el proveedor cuando existe.provideres opcional y solo afecta el nombre nativo más la disponibilidad de comandos nativos del Plugin.includeArgs=falseomite del resultado los metadatos serializados de argumentos.
- Los operadores pueden llamar a
tools.catalog(operator.read) para obtener el catálogo de herramientas en tiempo de ejecución para un agente. La respuesta incluye herramientas agrupadas y metadatos de procedencia:source:coreopluginpluginId: propietario del Plugin cuandosource="plugin"optional: si una herramienta de Plugin es opcional
- Los operadores pueden llamar a
tools.effective(operator.read) para obtener el inventario efectivo de herramientas en tiempo de ejecución para una sesión.sessionKeyes obligatorio.- El gateway deriva el contexto confiable de tiempo de ejecución del lado del servidor a partir de la sesión en lugar de aceptar autenticación o contexto de entrega proporcionados por quien llama.
- La respuesta está acotada a la sesión y refleja lo que la conversación activa puede usar en este momento, incluidas herramientas de núcleo, Plugin y canal.
- Los operadores pueden llamar a
skills.status(operator.read) para obtener el inventario visible de Skills para un agente.agentIdes opcional; omítalo para leer el espacio de trabajo del agente predeterminado.- La respuesta incluye elegibilidad, requisitos faltantes, comprobaciones de configuración y opciones de instalación saneadas sin exponer valores secretos sin procesar.
- Los operadores pueden llamar a
skills.searchyskills.detail(operator.read) para metadatos de descubrimiento de ClawHub. - Los operadores pueden llamar a
skills.install(operator.admin) en dos modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala una carpeta de skill en el directorioskills/del espacio de trabajo del agente predeterminado. - Modo instalador de gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }ejecuta una acción declaradametadata.openclaw.installen el host del gateway.
- Modo ClawHub:
- Los operadores pueden llamar a
skills.update(operator.admin) en dos modos:- El modo ClawHub actualiza un
slugrastreado o todas las instalaciones rastreadas de ClawHub en el espacio de trabajo del agente predeterminado. - El modo configuración aplica un parche a valores
skills.entries.<skillKey>comoenabled,apiKeyyenv.
- El modo ClawHub actualiza un
Aprobaciones de exec
- Cuando una solicitud
execnecesita aprobación, el gateway difundeexec.approval.requested. - Los clientes operador resuelven llamando a
exec.approval.resolve(requiere alcanceoperator.approvals). - Para
host=node,exec.approval.requestdebe incluirsystemRunPlan(argv/cwd/rawCommand/metadatos de sesión canónicos). Las solicitudes sinsystemRunPlanse rechazan. - Después de la aprobación, las llamadas reenviadas
node.invoke system.runreutilizan esesystemRunPlancanónico como contexto autoritativo de comando/cwd/sesión. - Si quien llama modifica
command,rawCommand,cwd,agentIdosessionKeyentrepreparey el reenvío final aprobado desystem.run, el gateway rechaza la ejecución en lugar de confiar en la carga útil modificada.
Respaldo de entrega del agente
- Las solicitudes
agentpueden incluirdeliver=truepara solicitar entrega saliente. bestEffortDeliver=falsemantiene un comportamiento estricto: los destinos de entrega no resueltos o solo internos devuelvenINVALID_REQUEST.bestEffortDeliver=truepermite recurrir a ejecución solo de sesión cuando no puede resolverse ninguna ruta externa entregable (por ejemplo, sesiones internas/webchat o configuraciones ambiguas de múltiples canales).
Control de versiones
PROTOCOL_VERSIONse encuentra ensrc/gateway/protocol/schema/protocol-schemas.ts.- Los clientes envían
minProtocol+maxProtocol; el servidor rechaza discrepancias. - Los esquemas + modelos se generan a partir de definiciones TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes del cliente
El cliente de referencia ensrc/gateway/client.ts usa estos valores predeterminados. Los valores son
estables en todo el protocolo v3 y son la línea base esperada para clientes de terceros.
| Constant | Default | Source |
|---|---|---|
PROTOCOL_VERSION | 3 | src/gateway/protocol/schema/protocol-schemas.ts |
| Tiempo de espera de solicitud (por RPC) | 30_000 ms | src/gateway/client.ts (requestTimeoutMs) |
| Tiempo de espera de preautorización / desafío de conexión | 10_000 ms | src/gateway/handshake-timeouts.ts (clamp 250–10_000) |
| Retroceso inicial de reconexión | 1_000 ms | src/gateway/client.ts (backoffMs) |
| Retroceso máximo de reconexión | 30_000 ms | src/gateway/client.ts (scheduleReconnect) |
| Límite de reintento rápido tras cierre por token de dispositivo | 250 ms | src/gateway/client.ts |
Período de gracia de parada forzada antes de terminate() | 250 ms | FORCE_STOP_TERMINATE_GRACE_MS |
Tiempo de espera predeterminado de stopAndWait() | 1_000 ms | STOP_AND_WAIT_TIMEOUT_MS |
Intervalo tick predeterminado (antes de hello-ok) | 30_000 ms | src/gateway/client.ts |
Cierre por tiempo de espera de tick | código 4000 cuando el silencio supera tickIntervalMs * 2 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
policy.tickIntervalMs, policy.maxPayload
y policy.maxBufferedBytes en hello-ok; los clientes deben respetar esos valores
en lugar de los valores predeterminados previos al handshake.
Autenticación
- La autenticación del gateway con secreto compartido usa
connect.params.auth.tokenoconnect.params.auth.password, según el modo de autenticación configurado. - Los modos con identidad, como Tailscale Serve
(
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"en interfaces que no son de loopback, satisfacen la comprobación de autenticación deconnecta partir de encabezados de la solicitud en lugar deconnect.params.auth.*. gateway.auth.mode: "none"para ingreso privado omite por completo la autenticaciónconnectcon secreto compartido; no exponga ese modo en ingresos públicos o no confiables.- Después del emparejamiento, Gateway emite un token de dispositivo limitado al rol + alcances
de la conexión. Se devuelve en
hello-ok.auth.deviceTokeny el cliente debe persistirlo para conexiones futuras. - Los clientes deben persistir el
hello-ok.auth.deviceTokenprincipal después de cualquier conexión exitosa. - Al reconectarse con ese token de dispositivo almacenado, también se debe reutilizar el conjunto de alcances aprobados almacenado para ese token. Esto preserva el acceso de lectura/sondeo/estado que ya se concedió y evita que las reconexiones colapsen silenciosamente a un alcance implícito más estrecho de solo administrador.
- Ensamblado de autenticación
connectdel lado del cliente (selectConnectAuthensrc/gateway/client.ts):auth.passwordes ortogonal y siempre se reenvía cuando está establecido.auth.tokense completa en este orden de prioridad: primero el token compartido explícito, luego undeviceTokenexplícito y, después, un token almacenado por dispositivo (indexado pordeviceId+role).auth.bootstrapTokense envía solo cuando ninguna de las opciones anteriores resolvió unauth.token. Un token compartido o cualquier token de dispositivo resuelto lo suprime.- La autopromoción de un token de dispositivo almacenado en el reintento puntual
AUTH_TOKEN_MISMATCHestá restringida solo a endpoints confiables: loopback, owss://contlsFingerprintfijado.wss://público sin fijación no califica.
- Las entradas adicionales
hello-ok.auth.deviceTokensson tokens de transferencia de arranque. Persístalos solo cuando la conexión haya usado autenticación de arranque en un transporte confiable comowss://o loopback/emparejamiento local. - Si un cliente proporciona un
deviceTokenexplícito oscopesexplícitos, ese conjunto de alcances solicitado por el llamador sigue siendo autoritativo; los alcances en caché solo se reutilizan cuando el cliente está reutilizando el token almacenado por dispositivo. - Los tokens de dispositivo pueden rotarse/revocarse mediante
device.token.rotateydevice.token.revoke(requiere alcanceoperator.pairing). - La emisión/rotación de tokens se mantiene limitada al conjunto de roles aprobado registrado en la entrada de emparejamiento de ese dispositivo; rotar un token no puede ampliar el dispositivo a un rol que la aprobación de emparejamiento nunca concedió.
- Para sesiones de token de dispositivo emparejado, la administración del dispositivo está autocontenida salvo que el
llamador también tenga
operator.admin: quienes no son administradores solo pueden quitar/revocar/rotar su propia entrada de dispositivo. device.token.rotatetambién verifica el conjunto solicitado de alcances de operador frente a los alcances de la sesión actual del llamador. Quienes no son administradores no pueden rotar un token a un conjunto de alcances de operador más amplio del que ya tienen.- Los fallos de autenticación incluyen
error.details.codemás sugerencias de recuperación:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Comportamiento del cliente para
AUTH_TOKEN_MISMATCH:- Los clientes confiables pueden intentar un reintento acotado con un token almacenado por dispositivo.
- Si ese reintento falla, los clientes deben detener los bucles automáticos de reconexión y mostrar orientación de acción al operador.
Identidad del dispositivo + emparejamiento
- Los nodos deben incluir una identidad de dispositivo estable (
device.id) derivada de la huella digital de un par de claves. - Los gateways emiten tokens por dispositivo + rol.
- Las aprobaciones de emparejamiento son necesarias para nuevos ID de dispositivo, a menos que la aprobación automática local esté habilitada.
- La aprobación automática de emparejamiento se centra en conexiones directas de loopback local.
- OpenClaw también tiene una ruta estrecha de autoconexión local al backend/contenedor para flujos auxiliares confiables con secreto compartido.
- Las conexiones tailnet o LAN del mismo host se siguen tratando como remotas para el emparejamiento y requieren aprobación.
- Todos los clientes WS deben incluir identidad
deviceduranteconnect(operator+node). Control UI puede omitirla solo en estos modos:gateway.controlUi.allowInsecureAuth=truepara compatibilidad con HTTP inseguro solo en localhost.- autenticación exitosa de Control UI de operador con
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(medida extrema, degradación grave de seguridad).
- Todas las conexiones deben firmar el nonce
connect.challengeproporcionado por el servidor.
Diagnósticos de migración de autenticación de dispositivo
Para clientes heredados que todavía usan el comportamiento de firma previo al desafío,connect ahora devuelve
códigos de detalle DEVICE_AUTH_* en error.details.code con un error.details.reason estable.
Fallos comunes de migración:
| Message | details.code | details.reason | Meaning |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | El cliente omitió device.nonce (o lo envió vacío). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | El cliente firmó con un nonce obsoleto o incorrecto. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | La carga útil de la firma no coincide con la carga útil v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | La marca de tiempo firmada está fuera del desfase permitido. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id no coincide con la huella digital de la clave pública. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | El formato/canonicalización de la clave pública falló. |
- Espere siempre a
connect.challenge. - Firme la carga útil v2 que incluye el nonce del servidor.
- Envíe el mismo nonce en
connect.params.device.nonce. - La carga útil de firma preferida es
v3, que vinculaplatformydeviceFamilyademás de los campos de dispositivo/cliente/rol/alcances/token/nonce. - Las firmas heredadas
v2siguen aceptándose por compatibilidad, pero la fijación de metadatos de dispositivos emparejados sigue controlando la política de comandos al reconectarse.
TLS + fijación
- TLS es compatible con conexiones WS.
- Los clientes pueden fijar opcionalmente la huella digital del certificado del gateway (consulte la configuración
gateway.tlsmásgateway.remote.tlsFingerprinto la CLI--tls-fingerprint).
Alcance
Este protocolo expone la API completa del gateway (estado, canales, modelos, chat, agente, sesiones, nodos, aprobaciones, etc.). La superficie exacta está definida por los esquemas TypeBox ensrc/gateway/protocol/schema.ts.