Protocolo de Gateway
El protocolo WS de la puerta de enlace es el único plano de control + transporte de nodos para OpenClaw. Todos los clientes (CLI, interfaz web, aplicación macOS, nodos iOS/Android, nodos sin cabeza) se conectan a través de WebSocket y declaran su rol + alcance en el momento del handshake.
Transporte
Sección titulada «Transporte»- WebSocket, tramas de texto con cargas JSON.
- La primera trama debe ser una solicitud
connect. - Las tramas de preconexión están limitadas a 64 KiB. Después de un enlace exitoso, los clientes
deben seguir los límites de
hello-ok.policy.maxPayloadyhello-ok.policy.maxBufferedBytes. Con el diagnóstico habilitado, las tramas entrantes excesivamente grandes y los búferes de salida lentos emiten eventospayload.largeantes de que el gateway cierre o descarte la trama afectada. Estos eventos conservan tamaños, límites, superficies y códigos de motivo seguros. No conservan el cuerpo del mensaje, el contenido de los archivos adjuntos, el cuerpo de la trama sin procesar, tokens, cookies ni valores secretos.
Handshake (conexión)
Sección titulada «Handshake (conexión)»Gateway → Cliente (desafío previo a la conexión):
{ "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 }}Cliente → Gateway:
{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 4, "client": { "id": "cli", "version": "1.2.3", "platform": "macos", "mode": "operator" }, "role": "operator", "scopes": ["operator.read", "operator.write"], "caps": [], "commands": [], "permissions": {}, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-cli/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } }}Gateway → Cliente:
{ "type": "res", "id": "…", "ok": true, "payload": { "type": "hello-ok", "protocol": 4, "server": { "version": "…", "connId": "…" }, "features": { "methods": ["…"], "events": ["…"] }, "snapshot": { "…": "…" }, "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }, "policy": { "maxPayload": 26214400, "maxBufferedBytes": 52428800, "tickIntervalMs": 15000 } }}Mientras el Gateway aún está finalizando los sidecars de inicio, la solicitud connect puede
devolver un error UNAVAILABLE reintentable con details.reason establecido en
"startup-sidecars" y retryAfterMs. Los clientes deben reintentar esa respuesta
dentro de su presupuesto general de conexión en lugar de exponerla como un error de
enlace terminal.
server, features, snapshot y policy son todos obligatorios según el esquema
(packages/gateway-protocol/src/schema/frames.ts). auth también es obligatorio e informa
los roles/alcances negociados. pluginSurfaceUrls es opcional y asigna los nombres de
las superficies de los complementos, como canvas, a URL alojadas con alcance.
Las URL de superficies de complementos con ámbito pueden caducar. Los nodos pueden llamar a
node.pluginSurface.refresh con { "surface": "canvas" } para recibir una entrada
nueva en pluginSurfaceUrls. La refactorización experimental del complemento Canvas no
admite la ruta de compatibilidad obsoleta canvasHostUrl, canvasCapability o
node.canvas.capability.refresh; los clientes nativos y
gateways actuales deben usar superficies de complementos.
Cuando no se emite ningún token de dispositivo, hello-ok.auth informa de los permisos
negociados sin campos de token:
{ "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }}Los clientes de backend de mismo proceso de confianza (client.id: "gateway-client",
client.mode: "backend") pueden omitir device en conexiones directas de bucle invertido cuando
se autentican con el token/contraseña compartida de la puerta de enlace. Esta ruta está reservada
para RPCs del plano de control interno y evita que las líneas base de emparejamiento CLI/dispositivo obsoletas
bloqueen el trabajo del backend local, como las actualizaciones de sesión de subagente. Los clientes remotos,
clientes de origen del navegador, clientes de nodo y clientes explícitos de token de dispositivo/identidad de dispositivo
todavía usan las verificaciones normales de emparejamiento y actualización de ámbito.
Cuando se emite un token de dispositivo, hello-ok también incluye:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}El arranque mediante QR/código de configuración integrado es una ruta nueva de entrega móvil. Una conexión exitosa con un código de configuración de línea base devuelve un token de nodo principal más un token de operador limitado:
{ "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] }}La entrega del operador se limita intencionalmente para que la incorporación mediante QR pueda iniciar el
bucle del operador móvil sin otorgar operator.admin o operator.pairing.
Incluye operator.talk.secrets para que el cliente nativo pueda leer la configuración
de Talk que necesita después del arranque. Los alcances administrativos y de emparejamiento más amplios requieren
un flujo de emparejamiento o token de operador aprobado por separado. Los clientes deben persistir
hello-ok.auth.deviceTokens solo
cuando la conexión use autenticación de arranque en un transporte confiable, como wss:// o
emparejamiento local/bucle de retorno.
Ejemplo de nodo
Sección titulada «Ejemplo de nodo»{ "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 4, "client": { "id": "ios-node", "version": "1.2.3", "platform": "ios", "mode": "node" }, "role": "node", "scopes": [], "caps": ["camera", "canvas", "screen", "location", "voice"], "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"], "permissions": { "camera.capture": true, "screen.record": false }, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-ios/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } }}Estructura (Framing)
Sección titulada «Estructura (Framing)»- Solicitud:
{type:"req", id, method, params} - Respuesta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Los métodos con efectos secundarios requieren claves de idempotencia (ver esquema).
Roles + ámbitos
Sección titulada «Roles + ámbitos»Para obtener el modelo completo de ámbito de operador, las comprobaciones en el momento de aprobación y la semántica de secreto compartido, consulte Ámbitos de operador.
operator= cliente del plano de control (CLI/UI/automatización).node= host de capacidad (cámara/pantalla/lien/system.run).
Ámbitos (operador)
Sección titulada «Ámbitos (operador)»Ámbitos 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 puerta de enlace registrados por complementos 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 la primera puerta. Algunos comandos de barra reached a través de
chat.send aplican comprobaciones más estrictas a nivel de comando además. Por ejemplo, las escrituras persistentes de
/config set y /config unset requieren operator.admin.
node.pair.approve también tiene una verificación de alcance adicional en el momento de la aprobación además del
alcance del método base:
- solicitudes sin comando:
operator.pairing - solicitudes con comandos de nodo no ejecutables:
operator.pairing+operator.write - solicitudes que incluyen
system.run,system.run.prepare, osystem.which:operator.pairing+operator.admin
Caps/commands/permissions (nodo)
Sección titulada «Caps/commands/permissions (nodo)»Los nodos declaran reclamos de capacidad en el momento de la conexión:
caps: categorías de capacidades de alto nivel comocamera,canvas,screen,location,voiceytalk.commands: lista blanca de comandos para invocar.permissions: interruptores granulares (ej.screen.record,camera.capture).
El Gateway trata estos como reclamos y hace cumplir las listas de permitidos del lado del servidor.
Presencia
Sección titulada «Presencia»system-presencedevuelve entradas claveadas por la identidad del dispositivo.- Las entradas de presencia incluyen
deviceId,rolesyscopespara que las interfaces de usuario puedan mostrar una sola fila por dispositivo incluso cuando se conecta tanto como operador como nodo. node.listincluye campos opcionaleslastSeenAtMsylastSeenReason. Los nodos conectados reportan su tiempo de conexión actual comolastSeenAtMscon el motivoconnect; los nodos emparejados también pueden reportar presencia duradera en segundo plano cuando un evento de nodo de confianza actualiza sus metadatos de emparejamiento.
Evento de actividad en segundo plano del nodo
Sección titulada «Evento de actividad en segundo plano del nodo»Los nodos pueden llamar node.event con event: "node.presence.alive" para registrar que un nodo emparejado estaba
vivo durante una activación en segundo plano sin marcarlo como conectado.
{ "event": "node.presence.alive", "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"}trigger es un enumerado cerrado: background, silent_push, bg_app_refresh,
significant_location, manual o connect. Las cadenas de activador desconocidas se normalizan a
background por el puerta de enlace antes de la persistencia. El evento es duradero solo para sesiones de dispositivo de nodo
autenticadas; las sesiones sin dispositivo o no emparejadas devuelven handled: false.
Las pasarelas exitosas devuelven un resultado estructurado:
{ "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted"}Las puertas de enlace (gateways) antiguas todavía pueden devolver { "ok": true } para node.event; los clientes deben tratar eso como un
RPC reconocido, no como una persistencia de presencia duradera.
Ámbito de eventos de difusión
Sección titulada «Ámbito de eventos de difusión»Los eventos de difusión WebSocket enviados por el servidor están restringidos por ámbito para que las sesiones con ámbito de emparejamiento o solo de nodo no reciban pasivamente el contenido de la sesión.
- Los marcos de chat, agente y resultado de herramienta (incluidos los eventos
agenttransmitidos y los resultados de llamadas a herramientas) requieren al menosoperator.read. Las sesiones sinoperator.readomiten estos marcos por completo. - Las transmisiones
plugin.*definidas por el complemento están limitadas aoperator.writeooperator.admin, dependiendo de cómo el complemento las haya registrado. - Los eventos de estado y transporte (
heartbeat,presence,tick, ciclo de vida de conexión/desconexión, etc.) permanecen sin restricciones para que la salud del transporte siga siendo observable para cada sesión autenticada. - Las familias de eventos de difusión desconocidas están restringidas por ámbito de forma predeterminada (fail-closed) a menos que un controlador registrado las relaje explícitamente.
Cada conexión de cliente mantiene su propio número de secuencia por cliente para que las difusiones preserven el orden monótono en ese socket, incluso cuando diferentes clientes vean subconjuntos diferentes del flujo de eventos filtrados por ámbito.
Familias comunes de métodos RPC
Sección titulada «Familias comunes de métodos RPC»La superficie pública de WS es más amplia que los ejemplos de enlace/autenticación anteriores. Esto
no es un volcado generado — hello-ok.features.methods es una lista de descubrimiento conservadora construida a partir de src/gateway/server-methods-list.ts además de las exportaciones de métodos de complemento/canal cargados. Trátelo como descubrimiento de características, no como una enumeración completa de src/gateway/server-methods/*.ts.
Sistema e identidad
healthdevuelve la instantánea de estado del gateway almacenada en caché o recién sondeada.diagnostics.stabilitydevuelve el grabador de estabilidad de diagnóstico reciente y limitado. Mantiene metadatos operativos como nombres de eventos, recuentos, tamaños de bytes, lecturas de memoria, estado de cola/sesión, nombres de canal/complemento e identificadores de sesión. No mantiene texto de chat, cuerpos de webhook, salidas de herramientas, cuerpos de solicitudes o respuestas sin procesar, tokens, cookies o valores secretos. Se requiere el alcance de lectura del operador.statusdevuelve el resumen del gateway estilo/status; los campos confidenciales se incluyen solo para clientes de operador con alcance de administrador.gateway.identity.getdevuelve la identidad del dispositivo del gateway utilizada por los flujos de retransmisión y emparejamiento.system-presencedevuelve la instantánea de presencia actual para los dispositivos de operador/nodo conectados.system-eventagrega un evento del sistema y puede actualizar/transmitir el contexto de presencia.last-heartbeatdevuelve el evento de latido persistido más reciente.set-heartbeatsalterna el procesamiento de latidos en el gateway.
Modelos y uso
models.listdevuelve el catálogo de modelos permitidos en tiempo de ejecución. Pase{ "view": "configured" }para modelos configurados de tamaño de selector (agents.defaults.modelsprimero, luegomodels.providers.*.models), o{ "view": "all" }para el catálogo completo.usage.statusdevuelve resúmenes de ventanas de uso del proveedor/cuota restante.usage.costdevuelve resúmenes de costos de uso agregados para un rango de fechas. PaseagentIdpara un agente, oagentScope: "all"para agregar los agentes configurados.doctor.memory.statusdevuelve el estado de preparación de la memoria vectorial/incrustaciones en caché para el espacio de trabajo del agente predeterminado activo. Pase{ "probe": true }o{ "deep": true }solo cuando la persona que llama explícitamente desea un ping en vivo del proveedor de incrustaciones. Los clientes con conocimiento de “Dreaming” también pueden pasar{ "agentId": "agent-id" }para delimitar las estadísticas de la tienda Dreaming a un espacio de trabajo de agente seleccionado; omitiragentIdmantiene la alternativa del agente predeterminado y agrega los espacios de trabajo Dreaming configurados.doctor.memory.dreamDiary,doctor.memory.backfillDreamDiary,doctor.memory.resetDreamDiary,doctor.memory.resetGroundedShortTerm,doctor.memory.repairDreamingArtifactsydoctor.memory.dedupeDreamDiaryaceptan parámetros{ "agentId": "agent-id" }opcionales para vistas/acciones de Dreaming del agente seleccionado. Cuando se omiteagentId, operan en el espacio de trabajo del agente predeterminado configurado.doctor.memory.remHarnessdevuelve una vista previa limitada y de solo lectura del arnés REM para clientes remotos del plano de control. Puede incluir rutas del espacio de trabajo, fragmentos de memoria, markdown fundamentado renderizado y candidatos de promoción profunda, por lo que las personas que llaman necesitanoperator.read.sessions.usagedevuelve resúmenes de uso por sesión. PaseagentIdpara un agente, oagentScope: "all"para listar los agentes configurados juntos.sessions.usage.timeseriesdevuelve el uso de series temporales para una sesión.sessions.usage.logsdevuelve entradas de registro de uso para una sesión.
Canales y asistentes de inicio de sesión
channels.statusdevuelve resúmenes de estado de los canales/complementos integrados y agrupados.channels.logoutcierra la sesión de un canal/cuenta específico cuando el canal soporta cerrar sesión.web.login.startinicia un flujo de inicio de sesión QR/web para el proveedor de canal web actual con capacidad QR.web.login.waitespera a que ese flujo de inicio de sesión QR/web se complete e inicia el canal si tiene éxito.push.testenvía una push de prueba de APNs a un nodo iOS registrado.voicewake.getdevuelve los disparadores de palabra de activación almacenados.voicewake.setactualiza los disparadores de palabra de activación y transmite el cambio.
Mensajería y registros
sendes el RPC de entrega directa de salida para envíos dirigidos a canal/cuenta/hilo fuera del ejecutor de chat.logs.taildevuelve la cola del registro de archivos de la puerta de enlace configurada con controles de cursor/límite y bytes máximos.
Talk y TTS
talk.catalogdevuelve el catálogo de proveedores Talk de solo lectura para voz, transcripción en streaming y voz en tiempo real. Incluye IDs de proveedor, etiquetas, estado configurado, IDs de modelo/voz expuestos, modos canónicos, transportes, estrategias cerebrales y banderas de audio/capacidad en tiempo real sin devolver secretos del proveedor ni modificar la configuración global.talk.configdevuelve la carga útil de configuración efectiva de Talk;includeSecretsrequiereoperator.talk.secrets(ooperator.admin).talk.session.createcrea una sesión Talk propiedad de Gateway pararealtime/gateway-relay,transcription/gateway-relayostt-tts/managed-room. Parastt-tts/managed-room, los llamadoresoperator.writeque pasansessionKeytambién deben pasarspawnedBypara la visibilidad de la clave de sesión con ámbito; la creación desessionKeysin ámbito ybrain: "direct-tools"requierenoperator.admin.talk.session.joinvalida un token de sesión de sala administrada, emite eventossession.readyosession.replacedsegún sea necesario y devuelve metadatos de la sala/sesión más eventos recientes de Talk sin el token en texto plano ni el hash del token almacenado.talk.session.appendAudioañade audio de entrada PCM en base64 a sesiones de transcripción y retransmisión en tiempo real propiedad de Gateway.talk.session.startTurn,talk.session.endTurnytalk.session.cancelTurnimpulsan el ciclo de vida de turnos de sala administrada con rechazo de turnos obsoletos antes de que se borre el estado.talk.session.cancelOutputdetiene la salida de audio del asistente, principalmente para interrupciones controladas por VAD en sesiones de retransmisión de Gateway.talk.session.submitToolResultcompleta una llamada a la herramienta del proveedor emitida por una sesión de retransmisión en tiempo real propiedad de Gateway. Paseoptions: { willContinue: true }para la salida interina de la herramienta cuando seguirá un resultado final, ooptions: { suppressResponse: true }cuando el resultado de la herramienta debe satisfacer la llamada del proveedor sin iniciar otra respuesta del asistente en tiempo real.talk.session.steerenvía el control de voz de ejecución activa a una sesión Talk respaldada por un agente y propiedad de Gateway. Acepta{ sessionId, text, mode? }, dondemodeesstatus,steer,cancelofollowup; el modo omitido se clasifica a partir del texto hablado.talk.session.closecierra una sesión de retransmisión, transcripción o sala administrada propiedad de Gateway y emite eventos terminales de Talk.talk.modeestablece/difunde el estado del modo Talk actual para clientes de WebChat/Control UI.talk.client.createcrea una sesión de proveedor en tiempo real propiedad del cliente usandowebrtcoprovider-websocketmientras que Gateway posee la configuración, las credenciales, las instrucciones y la política de herramientas.talk.client.toolCallpermite que los transportes en tiempo real propiedad del cliente reenvíen llamadas a herramientas del proveedor a la política de Gateway. La primera herramienta compatible esopenclaw_agent_consult; los clientes reciben un ID de ejecución y esperan los eventos normales del ciclo de vida del chat antes de enviar el resultado específico del proveedor de la herramienta.talk.client.steerenvía el control de voz de ejecución activa para transportes en tiempo real propiedad del cliente. Gateway resuelve la ejecución incrustada activa desdesessionKeyy devuelve un resultado estructurado aceptado/rechazado en lugar de descartar silenciosamente la dirección.talk.eventes el único canal de eventos de Talk para adaptadores en tiempo real, transcripción, STT/TTS, sala administrada, telefonía y reuniones.talk.speaksintetiza voz a través del proveedor de voz Talk activo.tts.statusdevuelve el estado habilitado 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.disablealternan el estado de preferencias de TTS.tts.setProvideractualiza el proveedor TTS preferido.tts.convertejecuta una conversión de texto a voz de un solo disparo.
Secretos, configuración, actualización y asistente
secrets.reloadvuelve a resolver los SecretRefs activos e intercambia el estado de los secretos en tiempo de ejecución solo si tiene éxito total.secrets.resolveresuelve las asignaciones de secretos de comando-objetivo para un conjunto de comando/objetivo específico.config.getdevuelve la instantánea y el hash de configuración actuales.config.setescribe una carga de configuración validada.config.patchcombina una actualización de configuración parcial.config.applyvalida y reemplaza la carga de configuración completa.config.schemadevuelve la carga del esquema de configuración en vivo utilizada por la interfaz de usuario de Control y las herramientas de CLI: esquema,uiHints, versión y metadatos de generación, incluyendo los metadatos del esquema de complemento y canal cuando el tiempo de ejecución puede cargarlo. El esquema incluye metadatos de campotitle/descriptionderivados de las mismas etiquetas y textos de ayuda utilizados por la interfaz de usuario, incluyendo ramas de composición de objetos anidados, comodines, elementos de matriz yanyOf/oneOf/allOfcuando existe la documentación del campo coincidente.config.schema.lookupdevuelve una carga de búsqueda con alcance de ruta para una ruta de configuración: ruta normalizada, un nodo de esquema superficial, sugerencia coincidente +hintPath,reloadKindopcional, y resúmenes secundarios inmediatos para exploración en la interfaz de usuario/CLI.reloadKindes uno derestart,hotononey refleja el planificador de recarga de configuración de Gateway para la ruta solicitada. Los nodos de esquema de búsqueda mantienen la documentación orientada al usuario y los campos de validación comunes (title,description,type,enum,const,format,pattern, límites numéricos/cadena/matriz/objeto, y banderas comoadditionalProperties,deprecated,readOnly,writeOnly). Los resúmenes secundarios exponenkey,pathnormalizado,type,required,hasChildren,reloadKindopcional, más la sugerencia coincidentehint/hintPath.update.runejecuta el flujo de actualización de la puerta de enlace y programa un reinicio solo cuando la actualización misma tuvo éxito; los llamadores con una sesión pueden incluircontinuationMessagepara que el inicio continúe un turno de agente de seguimiento a través de la cola de continuación de reinicio. Las actualizaciones del administrador de paquetes desde el plano de control utilizan una transferencia de servicio administrado separada en lugar de reemplazar el árbol de paquetes dentro de la puerta de enlace en vivo. Una transferencia iniciada devuelveok: trueconresult.reason: "managed-service-handoff-started"yhandoff.status: "started"; las transferencias no disponibles o fallidas devuelvenok: falseconmanaged-service-handoff-unavailableomanaged-service-handoff-failed, máshandoff.commandcuando se requiere una actualización manual del shell. Durante una transferencia iniciada, el centinela de reinicio puede informar brevementestats.reason: "restart-health-pending"; la continuación se retrasa hasta que la CLI verifica la puerta de enlace reiniciada y escribe el centinela finalok.update.statusdevuelve el centinela de reinicio de actualización en caché más reciente, incluyendo la versión en ejecución posterior al reinicio cuando está disponible.wizard.start,wizard.next,wizard.statusywizard.cancelexponen el asistente de incorporación a través de WS RPC.
Agentes y asistentes del espacio de trabajo
agents.listdevuelve las entradas de agentes configuradas, incluidos los metadatos del modelo efectivo y del tiempo de ejecución.agents.create,agents.updateyagents.deletegestionan los registros de agentes y la conexión del espacio de trabajo.agents.files.list,agents.files.getyagents.files.setgestionan los archivos de arranque del espacio de trabajo expuestos para un agente.tasks.list,tasks.getytasks.cancelexponen el libro de tareas de Gateway a los clientes del SDK y operadores.artifacts.list,artifacts.getyartifacts.downloadexponen resúmenes y descargas de artefactos derivados de transcripciones para unsessionKey,runIdotaskIdexplícito. Las consultas de ejecución y tareas resuelven la sesión propietaria del lado del servidor y solo devuelven medios de transcripción con procedencia coincidente; las fuentes de URL no seguras o locales devuelven descargas no compatibles en lugar de obtenerlas del lado del servidor.environments.listyenvironments.statusexponen el descubrimiento de entorno local de Gateway y de nodo de solo lectura para los clientes del SDK.agent.identity.getdevuelve la identidad efectiva del asistente para un agente o sesión.agent.waitespera a que finalice una ejecución y devuelve la instantánea terminal cuando está disponible.
Control de sesión
sessions.listdevuelve el índice de sesión actual, incluidos los metadatosagentRuntimepor fila cuando se configura un backend de tiempo de ejecución de agente.sessions.subscribeysessions.unsubscribealternan las suscripciones a eventos de cambio de sesión para el cliente WS actual.sessions.messages.subscribeysessions.messages.unsubscribealternan las suscripciones a eventos de transcripción/mensaje para una sesión.sessions.previewdevuelve vistas previas limitadas de transcripciones para claves de sesión específicas.sessions.describedevuelve una fila de sesión de Gateway para una clave de sesión exacta.sessions.resolveresuelve o canónica un objetivo 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 interrupción y dirección para una sesión activa.sessions.abortaborta el trabajo activo para una sesión. Un llamador puede pasarkeymás opcionalrunId, o pasarrunIdsolo para ejecuciones activas que el Gateway puede resolver a una sesión.sessions.patchactualiza los metadatos/sobreescrituras de sesión e informa el modelo canónico resuelto másagentRuntimeefectivo.sessions.reset,sessions.delete, ysessions.compactrealizan el mantenimiento de la sesión.sessions.getdevuelve la fila de sesión almacenada completa.- La ejecución del chat aún usa
chat.history,chat.send,chat.abort, ychat.inject.chat.historyestá normalizado para visualización para clientes de IU: las etiquetas de directiva en línea se eliminan del texto visible, las cargas útiles XML de llamadas a herramientas en texto plano (incluidas `
…
,
…
,
…
,
…
, y bloques de llamadas a herramientas truncados) y los tokens de control de modelo ASCII/ancho completo filtrados se eliminan, las filas de asistente de token silencioso puro como NO_REPLY/no_replyexactas se omiten, y las filas demasiado grandes pueden reemplazarse con marcadores de posición. -chat.message.getes el lector completo de mensajes aditivo limitado para una sola entrada de transcripción visible. Los clientes pasansessionKey, opcional agentIdcuando la selección de sesión está en el ámbito del agente, más unmessageIdde transcripción previamente surfaced a través dechat.history`, y el Gateway devuelve la misma proyección normalizada para visualización sin el límite de truncamiento de historial ligero cuando la entrada almacenada todavía está disponible y no es demasiado grande.
Emparejamiento de dispositivos y tokens de dispositivo
device.pair.listdevuelve los dispositivos emparejados pendientes y aprobados.device.pair.approve,device.pair.rejectydevice.pair.removegestionan los registros de emparejamiento de dispositivos.device.token.rotaterota un token de dispositivo emparejado dentro de los límites de su rol aprobado y el ámbito de la persona que llama.device.token.revokerevoca un token de dispositivo emparejado dentro de los límites de su rol aprobado y el ámbito de la persona que llama.
Emparejamiento de nodos, invocación y trabajo pendiente
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.removeynode.pair.verifycubren el emparejamiento de nodos y la verificación de arranque.node.listynode.describedevuelven el estado del nodo conocido/conectado.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.eventlleva eventos originados en el nodo de vuelta a la puerta de enlace.node.pending.pullynode.pending.ackson las API de cola de nodos conectados.node.pending.enqueueynode.pending.draingestionan el trabajo pendiente duradero para nodos sin conexión/desconectados.
Familias de aprobación
exec.approval.request,exec.approval.get,exec.approval.listyexec.approval.resolvecubren solicitudes de aprobación de ejecución únicas, además de la búsqueda/reproducción de aprobaciones pendientes.exec.approval.waitDecisionespera una aprobación de ejecución pendiente y devuelve la decisión final (onullsi se agota el tiempo de espera).exec.approvals.getyexec.approvals.setgestionan instantáneas de la política de aprobación de ejecución de la puerta de enlace.exec.approvals.node.getyexec.approvals.node.setgestionan la política de aprobación de ejecución local del nodo mediante comandos de retransmisión del nodo.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisionyplugin.approval.resolvecubren flujos de aprobación definidos por complementos.
Automatización, habilidades y herramientas
- Automatización:
wakeprograma una inyección de texto de activación inmediata o en el próximo latido;cron.get,cron.list,cron.status,cron.add,cron.update,cron.remove,cron.runycron.runsgestionan el trabajo programado. cron.runsigue siendo un RPC de tipo de cola para ejecuciones manuales. Los clientes que necesiten semántica de finalización deben leer elrunIddevuelto y sondearcron.runs.cron.runsacepta un filtrorunIdopcional no vacío para que los clientes puedan seguir una ejecución manual en cola sin competir con otras entradas de historial para el mismo trabajo.- Habilidades y herramientas:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke.
Familias de eventos comunes
Sección titulada «Familias de eventos comunes»chat: actualizaciones de chat de la UI comochat.injecty otros eventos de chat solo de transcripción. En el protocolo v4, las cargas delta llevandeltaText;messagesigue siendo la instantánea acumulativa del asistente. Los reemplazos que no son prefijos establecenreplace=truey usandeltaTextcomo el texto de reemplazo.session.message,session.operationysession.tool: transcripción, operación de sesión en curso y actualizaciones del flujo de eventos para una sesión suscrita.sessions.changed: índice de sesión o metadatos cambiados.presence: actualizaciones de instantáneas de presencia del sistema.tick: evento periódico de keepalive / estado vivo.health: actualización de instantánea de salud de la puerta de enlace.heartbeat: actualización del flujo de eventos de latido.cron: evento de cambio de ejecución/trabajo de cron.shutdown: notificación de apagado de la puerta de enlace.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: configuración de activación por palabra clave cambiada.exec.approval.requested/exec.approval.resolved: ciclo de vida de aprobación de exec.plugin.approval.requested/plugin.approval.resolved: ciclo de vida de aprobación de plugin.
Métodos auxiliares de nodo
Sección titulada «Métodos auxiliares de nodo»- Los nodos pueden llamar a
skills.binspara obtener la lista actual de ejecutables de habilidades para comprobaciones de permiso automático.
RPC del libro de tareas (Task ledger)
Sección titulada «RPC del libro de tareas (Task ledger)»Los clientes operadores pueden inspeccionar y cancelar registros de tareas en segundo plano de la Gateway a través del libro de tareas (task ledger) RPC. Estos métodos devuelven resúmenes de tareas saneados, no el estado en tiempo de ejecución sin procesar.
tasks.listrequiereoperator.read.- Params: opcional
status("queued","running","completed","failed","cancelled", o"timed_out") o una matriz de esos estados, opcionalagentId, opcionalsessionKey, opcionallimitde1a500, y cadena opcionalcursor. - Resultado:
{ "tasks": TaskSummary[], "nextCursor"?: string }.
- Params: opcional
tasks.getrequiereoperator.read.- Params:
{ "taskId": string }. - Resultado:
{ "task": TaskSummary }. - Los ids de tareas faltantes devuelven la forma de error no encontrado de la Gateway.
- Params:
tasks.cancelrequiereoperator.write.- Params:
{ "taskId": string, "reason"?: string }. - Resultado:
{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }. foundindica si el libro mayor tenía una tarea coincidente.cancelledindica si el tiempo de ejecución aceptó o registró la cancelación.
- Params:
TaskSummary incluye id, status y metadatos opcionales como kind,
runtime, title, agentId, sessionKey, childSessionKey, ownerKey,
runId, taskId, flowId, parentTaskId, sourceId, marcas de tiempo, progreso,
resumen terminal y texto de error saneado.
Métodos auxiliares del operador
Sección titulada «Métodos auxiliares del 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 qué superficie apunta elnameprimario:textdevuelve el token de comando de texto principal sin el/inicialnativey la rutabothpredeterminada devuelven nombres nativos conscientes del proveedor cuando están disponibles
textAliaseslleva alias de barra exactos como/modely/m.nativeNamelleva el nombre de comando nativo consciente del proveedor cuando existe uno.provideres opcional y solo afecta la nomenclatura nativa más la disponibilidad de comandos de complementos nativos.includeArgs=falseomite los metadatos de argumentos serializados de la respuesta.
- Los operadores pueden llamar a
tools.catalog(operator.read) para obtener el catálogo de herramientas en tiempo de ejecución de un agente. La respuesta incluye herramientas agrupadas y metadatos de procedencia:source:coreopluginpluginId: propietario del complemento cuandosource="plugin"optional: si una herramienta de complemento es opcional
- Los operadores pueden llamar a
tools.effective(operator.read) para obtener el inventario de herramientas efectivas en tiempo de ejecución para una sesión.- Se requiere
sessionKey. - La puerta de enlace deriva el contexto de tiempo de ejecución confiable de la sesión en el lado del servidor en lugar de aceptar el contexto de autenticación o entrega proporcionado por el llamador.
- La respuesta es una proyección derivada del servidor con alcance de sesión del inventario activo, que incluye herramientas principales, de complemento, de canal y de servidores MCP ya descubiertos.
tools.effectivees de solo lectura para MCP: puede proyectar un catálogo MCP de sesión “caliente” a través de la política de herramientas final, pero no crea tiempos de ejecución MCP, conecta transportes ni emitetools/list. Si no existe un catálogo “caliente” coincidente, la respuesta puede incluir un aviso comomcp-not-yet-connected,mcp-not-yet-listedomcp-stale-catalog.- Las entradas de herramientas efectivas usan
source="core",source="plugin",source="channel"osource="mcp".
- Se requiere
- Los operadores pueden llamar a
tools.invoke(operator.write) para invocar una herramienta disponible a través de la misma ruta de política de puerta de enlace que/tools/invoke.- Se requiere
name.args,sessionKey,agentId,confirmyidempotencyKeyson opcionales. - Si tanto
sessionKeycomoagentIdestán presentes, el agente de sesión resuelto debe coincidir conagentId. - La respuesta es un sobre orientado al SDK con
ok,toolName,outputopcional y camposerrortipados. Las reutilizaciones de aprobación o política devuelvenok:falseen la carga útil en lugar de omitir la canalización de política de herramientas de la puerta de enlace.
- Se requiere
- Los operadores pueden llamar a
skills.status(operator.read) para obtener el inventario de habilidades visible para un agente.agentIdes opcional; omítalo para leer el espacio de trabajo del agente predeterminado.- La respuesta incluye la elegibilidad, los requisitos faltantes, las comprobaciones de configuración y las opciones de instalación saneadas sin exponer valores de secretos sin procesar.
- Los operadores pueden llamar a
skills.searchyskills.detail(operator.read) para obtener metadatos de descubrimiento de ClawHub. - Los operadores pueden llamar a
skills.upload.begin,skills.upload.chunkyskills.upload.commit(operator.admin) para preparar un archivo de habilidades privado antes de instalarlo. Esta es una ruta de carga de administración separada para clientes de confianza, no el flujo normal de instalación de habilidades de ClawHub, y está deshabilitada de forma predeterminada a menos queskills.install.allowUploadedArchivesesté habilitado.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })crea una carga vinculada a ese slug y valor de forzado.skills.upload.chunk({ uploadId, offset, dataBase64 })añade bytes en el desplazamiento decodificado exacto.skills.upload.commit({ uploadId, sha256? })verifica el tamaño final y SHA-256. La confirmación solo finaliza la carga; no instala la habilidad.- Los archivos de habilidades cargados son archivos zip que contienen una raíz
SKILL.md. El nombre del directorio interno del archivo nunca selecciona el destino de instalación.
- Los operadores pueden llamar a
skills.install(operator.admin) en tres modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala una carpeta de habilidades en el directorioskills/del espacio de trabajo del agente predeterminado. - Modo de carga:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }instala una carga confirmada en el espacio de trabajo predeterminado del agenteskills/<slug>directorio. El slug y el valor de fuerza deben coincidir con la solicitudskills.upload.beginoriginal. Este modo se rechaza a menos queskills.install.allowUploadedArchivesesté habilitado. La configuración no afecta las instalaciones de ClawHub. - Modo de instalador de puerta de enlace:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }ejecuta una acciónmetadata.openclaw.installdeclarada en el host de la puerta de enlace.
- Modo ClawHub:
- Los operadores pueden llamar a
skills.update(operator.admin) en dos modos:- El modo ClawHub actualiza un slug rastreado o todas las instalaciones de ClawHub rastreadas en el espacio de trabajo del agente predeterminado.
- El modo de configuración parchea los valores
skills.entries.<skillKey>tales comoenabled,apiKeyyenv.
Vistas models.list
Sección titulada «Vistas models.list»models.list acepta un parámetro opcional view:
- Omitido o
"default": comportamiento del tiempo de ejecución actual. Siagents.defaults.modelsestá configurado, la respuesta es el catálogo permitido, incluyendo modelos descubiertos dinámicamente para entradasprovider/*. De lo contrario, la respuesta es el catálogo completo de la puerta de enlace. "configured": comportamiento de tamaño de selector. Siagents.defaults.modelsestá configurado, todavía tiene prioridad, incluyendo el descubrimiento con ámbito de proveedor para entradasprovider/*. Sin una lista de permitidos, la respuesta usa entradasmodels.providers.*.modelsexplícitas, recurriendo al catálogo completo solo cuando no existen filas de modelo configuradas."all": catálogo completo de la puerta de enlace, omitiendoagents.defaults.models. Use esto para diagnósticos e interfaces de usuario de descubrimiento, no para selectores de modelo normales.
Aprobaciones de ejecución
Sección titulada «Aprobaciones de ejecución»- Cuando una solicitud de ejecución necesita aprobación, la puerta de enlace transmite
exec.approval.requested. - Los clientes del operador resuelven llamando a
exec.approval.resolve(requiere ámbitooperator.approvals). - Para
host=node,exec.approval.requestdebe incluirsystemRunPlan(metadatos canónicos deargv/cwd/rawCommand/sesión). Las solicitudes que carecen desystemRunPlanse rechazan. - Tras la aprobación, las llamadas reenviadas de
node.invoke system.runreutilizan esesystemRunPlancanónico como el contexto autoritativo de comando/cwd/sesión. - Si un autor muta
command,rawCommand,cwd,agentIdosessionKeyentre la preparación y el reenvío final aprobado desystem.run, la puerta de enlace rechaza la ejecución en lugar de confiar en el payload mutado.
Respaldo de entrega del agente
Sección titulada «Respaldo de entrega del agente»- Las solicitudes de
agentpueden incluirdeliver=truepara solicitar entrega saliente. bestEffortDeliver=falsemantiene un comportamiento estricto: los destinos de entrega no resueltos o solo internos devuelvenINVALID_REQUEST.bestEffortDeliver=truepermite volver a una ejecución solo de sesión cuando no se puede resolver una ruta de entrega externa (por ejemplo, sesiones internas/webchat o configuraciones multicanales ambiguas).- Los resultados finales de
agentpueden incluirresult.deliveryStatuscuando se solicitó entrega, utilizando los mismos estadossent,suppressed,partial_failedyfaileddocumentados paraopenclaw agent --json --deliver.
Versionado
Sección titulada «Versionado»PROTOCOL_VERSIONreside enpackages/gateway-protocol/src/version.ts.- Los clientes envían
minProtocol+maxProtocol; el servidor rechaza los rangos que no incluyen su protocolo actual. Los clientes y servidores actuales requieren el protocolo v4. - Los esquemas y modelos se generan a partir de definiciones TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes del cliente
Sección titulada «Constantes del cliente»El cliente de referencia en src/gateway/client.ts utiliza estos valores predeterminados. Los valores son estables en la versión 4 del protocolo y constituyen la base esperada para los clientes de terceros.
| Constante | Predeterminado | Fuente |
|---|---|---|
PROTOCOL_VERSION | 4 | packages/gateway-protocol/src/version.ts |
MIN_CLIENT_PROTOCOL_VERSION | 4 | packages/gateway-protocol/src/version.ts |
| Tiempo de espera de solicitud (por RPC) | 30_000 ms | src/gateway/client.ts (requestTimeoutMs) |
| Tiempo de espera de preautenticación / desafío de conexión | 15_000 ms | src/gateway/handshake-timeouts.ts (config/env puede aumentar el presupuesto emparejado servidor/cliente) |
| 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 el cierre del token del dispositivo | 250 ms | src/gateway/client.ts |
Período de gracia de detención 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 de tick predeterminado (pre hello-ok) | 30_000 ms | src/gateway/client.ts |
| Cierre por tiempo de espera de tick | código 4000 cuando el silencio excede tickIntervalMs * 2 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
El servidor anuncia el policy.tickIntervalMs, policy.maxPayload
y policy.maxBufferedBytes efectivos en hello-ok; los clientes deben respetar esos valores
en lugar de los valores predeterminados previos al handshake.
- La autenticación de puerta de enlace de secreto compartido utiliza
connect.params.auth.tokenoconnect.params.auth.password, dependiendo del modo de autenticación configurado. - Los modos con identidad, como Tailscale Serve
(
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"que no sea de bucle local satisfacen la verificación de autenticación de conexión desde los encabezados de solicitud en lugar deconnect.params.auth.*. - Private-ingress
gateway.auth.mode: "none"omite por completo la autenticación de conexión mediante secreto compartido; no exponga ese modo en ingresos públicos o no confiables. - Después del emparejamiento, el Gateway emite un device token con alcance al rol + alcances de la conexión. Se devuelve en
hello-ok.auth.deviceTokeny el cliente debe persistirlo para futuras conexiones. - Los clientes deben persistir el
hello-ok.auth.deviceTokenprincipal después de cualquier conexión exitosa. - Volver a conectarse con ese token de dispositivo almacenado también debe reutilizar el conjunto de alcances aprobados almacenados para dicho token. Esto preserva el acceso de lectura/sondeo/estado que ya se había otorgado y evita colapsar silenciosamente las reconexiones a un alcance implícito más limitado de solo administrador.
- Ensamblaje de autenticación de conexión del lado del cliente (
selectConnectAuthensrc/gateway/client.ts):auth.passwordes ortogonal y siempre se reenvía cuando está establecido.auth.tokense completa en orden de prioridad: primero el token compartido explícito, luego undeviceTokenexplícito, y luego un token almacenado por dispositivo (claveado pordeviceId+role).auth.bootstrapTokensolo se envía cuando ninguno de los 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
AUTH_TOKEN_MISMATCHde un solo uso está limitada a solo endpoints de confianza: loopback owss://con untlsFingerprintanclado.wss://público sin anclaje no califica.
- El arranque mediante código de configuración integrado devuelve el
hello-ok.auth.deviceTokendel nodo principal más un token de operador limitado enhello-ok.auth.deviceTokenspara traspaso móvil confiable. El token de operador incluyeoperator.talk.secretspara lecturas de configuración nativa de Talk y excluyeoperator.adminyoperator.pairing. - Mientras un arranque mediante código de configuración no base está esperando aprobación, los detalles de
PAIRING_REQUIREDincluyenrecommendedNextStep: "wait_then_retry",retryable: trueypauseReconnect: false. Los clientes deben seguir reconectando con el mismo token de arranque hasta que se apruebe la solicitud o el token se vuelva inválido. - Persistir
hello-ok.auth.deviceTokenssolo cuando la conexión utilizó autenticación de arranque (bootstrap auth) en un transporte de confianza comowss://o emparejamiento local/bucle local (loopback). - Si un cliente proporciona un
deviceTokenexplícito o unscopesexplícito, ese conjunto de alcances solicitado por el llamador permanece como autoridad; los alcances en caché solo se reutilizan cuando el cliente está reutilizando el token almacenado por dispositivo. - Los tokens de dispositivo se pueden rotar/revocar a través de
device.token.rotateydevice.token.revoke(requiere el alcanceoperator.pairing). Rotar o revocar un nodo u otro rol que no sea operador también requiereoperator.admin. device.token.rotatedevuelve metadatos de rotación. Repite el token de portador de reemplazo solo para llamadas del mismo dispositivo que ya están autenticadas con ese token de dispositivo, para que los clientes solo con token puedan persistir su reemplazo antes de volver a conectarse. Las rotaciones compartidas/de administrador no repiten el token de portador.- La emisión, rotación y revocación de tokens permanecen limitadas al conjunto de roles aprobado registrado en la entrada de emparejamiento de ese dispositivo; la mutación del token no puede expandir ni dirigirse a un rol de dispositivo que la aprobación de emparejamiento nunca otorgó.
- Para sesiones de token de dispositivo emparejado, la gestión de dispositivos tiene alcance propio a menos que el
llamador también tenga
operator.admin: los llamadores que no son administradores solo pueden gestionar el token de operador para su propia entrada de dispositivo. La gestión de tokens de nodo y otros que no son operadores es exclusiva de administradores, incluso para el propio dispositivo del llamador. device.token.rotateydevice.token.revoketambién verifican el conjunto de alcances del token de operador de destino con los alcances de la sesión actual del llamador. Los llamadores que no son administradores no pueden rotar ni revocar un token de operador más amplio del que ya poseen.- 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 de confianza pueden intentar un reintento limitado con un token almacenado en caché por dispositivo.
- Si ese reintento falla, los clientes deben detener los bucles de reconexión automática y mostrar orientación de acción para el operador.
AUTH_SCOPE_MISMATCHsignifica que el token del dispositivo fue reconocido pero no cubre el rol/alcances solicitados. Los clientes no deben presentar esto como un token incorrecto; solicite al operador que vuelva a emparejar o apruebe el contrato de alcance más estrecho/amplio.
Identidad del dispositivo + emparejamiento
Sección titulada «Identidad del dispositivo + emparejamiento»- Los nodos deben incluir una identidad de dispositivo estable (
device.id) derivada de una huella de par de claves. - Las gateways emiten tokens por dispositivo + rol.
- Se requieren aprobaciones de emparejamiento para los nuevos ID de dispositivo a menos que se habilite la autoaprobación local.
- La autoaprobación de emparejamiento se centra en conexiones directas de bucle invertido local.
- OpenClaw también tiene una ruta estrecha de autoconexión local de backend/contenedor para flujos de ayuda de secreto compartido de confianza.
- Las conexiones tailnet o LAN del mismo host aún se tratan como remotas para el emparejamiento y requieren aprobación.
- Los clientes de WS normalmente incluyen la identidad
deviceduranteconnect(operador + nodo). Las únicas excepciones de operador sin dispositivo son rutas de confianza explícitas:gateway.controlUi.allowInsecureAuth=truepara compatibilidad HTTP insegura solo para localhost.gateway.auth.mode: "trusted-proxy"autenticación de interfaz de usuario de control del operador exitosa.gateway.controlUi.dangerouslyDisableDeviceAuth=true(romper-cristal, degradación de seguridad grave).- RPCs de backend
gateway-clientde bucle directo autenticados con el token/contraseña de puerta de enlace compartida.
- Omitir la identidad del dispositivo tiene consecuencias en el alcance. Cuando una conexión de interfaz de usuario de control carece de identidad de dispositivo,
shouldClearUnboundScopesForMissingDeviceIdentityborra los alcances autodeclarados a un conjunto vacío para la autenticación por token, contraseña y proxy de confianza. La conexión se permite en rutas de confianza explícitas, pero fallan los métodos con restricción de alcance. La excepción son las sesiones de token/contraseña de interfaz de usuario de control local conallowInsecureAuth, que preservan los alcances. Para otros casos, establezcagateway.controlUi.dangerouslyDisableDeviceAuth=truesolo como una ruta de preservación de alcance de emergencia. - Todas las conexiones deben firmar el nonce
connect.challengeproporcionado por el servidor.
Diagnósticos de migración de autenticación de dispositivos
Sección titulada «Diagnósticos de migración de autenticación de dispositivos»Para clientes heredados que aún utilizan el comportamiento de firma previa al desafío, connect ahora devuelve códigos de detalle DEVICE_AUTH_* bajo error.details.code con un error.details.reason estable.
Fallos comunes de migración:
| Mensaje | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | El cliente omitió device.nonce (o lo envió en blanco). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | El cliente firmó con un nonce obsoleto/incorrecto. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | El payload de la firma no coincide con el payload v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | La marca de tiempo firmada está fuera de la desviación permitida. |
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 | Falló el formato/canonicalización de la clave pública. |
Objetivo de migración:
- Espere siempre
connect.challenge. - Firme el payload 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/ámbitos/token/nonce. - Las firmas
v2heredadas siguen siendo aceptadas por compatibilidad, pero la fijación de metadatos del dispositivo emparejado todavía controla la política de comandos al reconectar.
TLS + fijación
Sección titulada «TLS + fijación»- TLS es compatible para conexiones WS.
- Los clientes opcionalmente pueden fijar la huella digital del certificado de la puerta de enlace (ver configuración
gateway.tlsmásgateway.remote.tlsFingerprinto CLI--tls-fingerprint).
Alcance
Sección titulada «Alcance»Este protocolo expone la API completa de la puerta de enlace (estado, canales, modelos, chat,
agente, sesiones, nodos, aprobaciones, etc.). La superficie exacta se define por los
esquemas TypeBox en packages/gateway-protocol/src/schema.ts.