Gateway
Protocolo do Gateway
O protocolo WS do Gateway é o plano de controle único + transporte de nós do OpenClaw. Todos os clientes (CLI, interface web, aplicativo macOS, nós iOS/Android, nós headless) se conectam por WebSocket e declaram seu papel + escopo no momento do handshake.
Transporte
- WebSocket, frames de texto com payloads JSON.
- O primeiro frame deve ser uma solicitação
connect. - Frames pré-conexão são limitados a 64 KiB. Após um handshake bem-sucedido, os clientes
devem seguir os limites
hello-ok.policy.maxPayloadehello-ok.policy.maxBufferedBytes. Com diagnósticos habilitados, frames de entrada grandes demais e buffers de saída lentos emitem eventospayload.largeantes que o gateway feche ou descarte o frame afetado. Esses eventos mantêm tamanhos, limites, superfícies e códigos de motivo seguros. Eles não mantêm o corpo da mensagem, conteúdo de anexos, corpo bruto do frame, tokens, cookies ou valores secretos.
Handshake (connect)
Gateway → Cliente (desafio pré-conexão):
{ "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 } }}Enquanto o Gateway ainda está finalizando serviços auxiliares de inicialização, a solicitação connect pode
retornar um erro UNAVAILABLE passível de nova tentativa com details.reason definido como
"startup-sidecars" e retryAfterMs. Os clientes devem repetir essa resposta
dentro do orçamento geral de conexão em vez de apresentá-la como uma falha terminal
de handshake.
server, features, snapshot e policy são todos obrigatórios pelo esquema
(packages/gateway-protocol/src/schema/frames.ts). auth também é obrigatório e informa
o papel/escopos negociados. pluginSurfaceUrls é opcional e mapeia nomes de superfícies de Plugin,
como canvas, para URLs hospedadas com escopo.
URLs de superfície de Plugin com escopo podem expirar. Nós podem chamar
node.pluginSurface.refresh com { "surface": "canvas" } para receber uma entrada nova
em pluginSurfaceUrls. A refatoração experimental do Plugin Canvas não
oferece suporte ao caminho de compatibilidade obsoleto canvasHostUrl, canvasCapability ou
node.canvas.capability.refresh; clientes nativos e gateways atuais devem usar superfícies de Plugin.
Quando nenhum token de dispositivo é emitido, hello-ok.auth informa as permissões negociadas
sem campos de token:
{ "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }}Clientes de backend confiáveis no mesmo processo (client.id: "gateway-client",
client.mode: "backend") podem omitir device em conexões diretas de loopback quando
se autenticam com o token/senha compartilhado do gateway. Esse caminho é reservado
para RPCs internos do plano de controle e impede que baselines obsoletas de pareamento CLI/dispositivo
bloqueiem trabalho de backend local, como atualizações de sessão de subagente. Clientes remotos,
clientes com origem em navegador, clientes de nó e clientes explícitos com token de dispositivo/identidade de dispositivo
ainda usam as verificações normais de pareamento e upgrade de escopo.
Quando um token de dispositivo é emitido, hello-ok também inclui:
{ "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] }}O bootstrap integrado por QR/código de configuração é um caminho novo de transferência móvel. Uma conexão bem-sucedida com código de configuração de baseline retorna um token primário de nó mais um token de operador limitado:
{ "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] }}A transferência de operador é intencionalmente limitada para que o onboarding por QR possa iniciar o
loop de operador móvel e concluir a configuração nativa sem conceder escopos de mutação
de pareamento ou operator.admin. Ela inclui operator.talk.secrets para que o
cliente nativo possa ler a configuração de Talk de que precisa após o bootstrap. Acesso mais amplo
a pareamento e administração exige um fluxo separado aprovado de pareamento ou token de operador.
Clientes devem persistir
hello-ok.auth.deviceTokens somente
quando a conexão usou autenticação de bootstrap em transporte confiável, como wss:// ou
pareamento local/local loopback.
Exemplo de Node
{ "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": "…" } }}Enquadramento
- Solicitação:
{type:"req", id, method, params} - Resposta:
{type:"res", id, ok, payload|error} - Evento:
{type:"event", event, payload, seq?, stateVersion?}
Métodos com efeitos colaterais exigem chaves de idempotência (consulte o esquema).
Papéis + escopos
Para o modelo completo de escopos de operador, verificações no momento da aprovação e semântica de segredo compartilhado, consulte Escopos de operador.
Papéis
operator= cliente do plano de controle (CLI/interface/automação).node= host de capacidade (câmera/tela/canvas/system.run).
Escopos (operador)
Escopos comuns:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config com includeSecrets: true exige operator.talk.secrets
(ou operator.admin).
Quando segredos são incluídos, os clientes devem ler a credencial ativa do provedor Talk
em talk.resolved.config.apiKey; talk.providers.<id>.apiKey
permanece no formato da origem e pode ser um objeto SecretRef ou uma string redigida.
Métodos RPC de gateway registrados por Plugin podem solicitar seu próprio escopo de operador, mas
prefixos administrativos centrais reservados (config.*, exec.approvals.*, wizard.*,
update.*) sempre resolvem para operator.admin.
O escopo de método é apenas a primeira barreira. Alguns comandos de barra acessados por
chat.send aplicam verificações mais rígidas em nível de comando além dela. Por exemplo, gravações persistentes
de /config set e /config unset exigem operator.admin.
node.pair.approve também tem uma verificação extra de escopo no momento da aprovação além do
escopo básico do método:
- solicitações sem comando:
operator.pairing - solicitações com comandos de nó que não sejam exec:
operator.pairing+operator.write - solicitações que incluem
system.run,system.run.prepareousystem.which:operator.pairing+operator.admin
Capacidades/comandos/permissões (nó)
Nós declaram reivindicações de capacidade no momento da conexão:
caps: categorias de capacidade de alto nível, comocamera,canvas,screen,location,voiceetalk.commands: lista de permissões de comandos para invoke.permissions: alternâncias granulares (por exemplo,screen.record,camera.capture).
O Gateway trata isso como reivindicações e aplica listas de permissões no lado do servidor.
Presença
system-presenceretorna entradas indexadas por identidade de dispositivo.- Entradas de presença incluem
deviceId,rolesescopespara que interfaces possam mostrar uma única linha por dispositivo mesmo quando ele se conecta como operador e nó. node.listinclui campos opcionaislastSeenAtMselastSeenReason. Nós conectados informam seu tempo de conexão atual comolastSeenAtMscom motivoconnect; nós pareados também podem informar presença durável em segundo plano quando um evento de nó confiável atualiza seus metadados de pareamento.
Evento de nó ativo em segundo plano
Nós podem chamar node.event com event: "node.presence.alive" para registrar que um nó pareado estava
ativo durante uma ativação em segundo plano sem marcá-lo 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 é um enum fechado: background, silent_push, bg_app_refresh,
significant_location, manual ou connect. Strings de trigger desconhecidas são normalizadas para
background pelo gateway antes da persistência. O evento só é durável para sessões de dispositivo de nó
autenticadas; sessões sem dispositivo ou não pareadas retornam handled: false.
Gateways bem-sucedidos retornam um resultado estruturado:
{ "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted"}Gateways mais antigos ainda podem retornar { "ok": true } para node.event; clientes devem tratar isso como uma
RPC confirmada, não como persistência de presença durável.
Escopo de eventos de transmissão
Eventos de transmissão WebSocket enviados pelo servidor são controlados por escopo para que sessões com escopo de pareamento ou apenas de nó não recebam passivamente conteúdo de sessão.
- Frames de chat, agente e resultado de ferramenta (incluindo eventos
agenttransmitidos e resultados de chamadas de ferramenta) exigem pelo menosoperator.read. Sessões semoperator.readignoram esses frames completamente. - Transmissões
plugin.*definidas por Plugin são controladas poroperator.writeouoperator.admin, dependendo de como o Plugin as registrou. - Eventos de status e transporte (
heartbeat,presence,tick, ciclo de vida de conexão/desconexão etc.) permanecem irrestritos para que a integridade do transporte continue observável para cada sessão autenticada. - Famílias desconhecidas de eventos de transmissão são controladas por escopo por padrão (falham fechadas), a menos que um manipulador registrado as relaxe explicitamente.
Cada conexão de cliente mantém seu próprio número de sequência por cliente, para que as transmissões preservem a ordenação monotônica nesse socket mesmo quando diferentes clientes veem diferentes subconjuntos filtrados por escopo do fluxo de eventos.
Famílias comuns de métodos RPC
A superfície WS pública é mais ampla do que os exemplos de handshake/autenticação acima. Isto
não é um despejo gerado — hello-ok.features.methods é uma lista conservadora
de descoberta criada a partir de src/gateway/server-methods-list.ts mais exports de métodos
de Plugin/canal carregados. Trate-a como descoberta de recursos, não como uma enumeração completa
de src/gateway/server-methods/*.ts.
System and identity
healthretorna o snapshot de integridade do Gateway em cache ou recém-sondado.diagnostics.stabilityretorna o registrador recente e limitado de estabilidade diagnóstica. Ele mantém metadados operacionais, como nomes de eventos, contagens, tamanhos em bytes, leituras de memória, estado de fila/sessão, nomes de canais/plugins e ids de sessão. Ele não mantém texto de chat, corpos de Webhook, saídas de ferramentas, corpos brutos de solicitação ou resposta, tokens, cookies nem valores secretos. O escopo de leitura de operador é obrigatório.statusretorna o resumo do Gateway no estilo/status; campos sensíveis são incluídos apenas para clientes operadores com escopo de administrador.gateway.identity.getretorna a identidade do dispositivo do Gateway usada por fluxos de retransmissão e pareamento.system-presenceretorna o snapshot de presença atual para dispositivos operador/Node conectados.system-eventanexa um evento do sistema e pode atualizar/transmitir o contexto de presença.last-heartbeatretorna o evento de Heartbeat persistido mais recente.set-heartbeatsalterna o processamento de Heartbeat no Gateway.
Models and usage
models.listretorna o catálogo de modelos permitido em tempo de execução. Passe{ "view": "configured" }para modelos configurados do tamanho de um seletor (agents.defaults.modelsprimeiro, depoismodels.providers.*.models), ou{ "view": "all" }para o catálogo completo.usage.statusretorna resumos de janelas de uso/cota restante do provedor.usage.costretorna resumos agregados de uso de custo para um intervalo de datas. PasseagentIdpara um agente, ouagentScope: "all"para agregar agentes configurados.doctor.memory.statusretorna a prontidão de memória vetorial / embedding em cache para o workspace do agente padrão ativo. Passe{ "probe": true }ou{ "deep": true }somente quando o chamador quiser explicitamente um ping ao vivo do provedor de embedding. Clientes cientes de Dreaming também podem passar{ "agentId": "agent-id" }para limitar as estatísticas do armazenamento de Dreaming a um workspace de agente selecionado; omitiragentIdmantém o fallback do agente padrão e agrega workspaces de Dreaming configurados.doctor.memory.dreamDiary,doctor.memory.backfillDreamDiary,doctor.memory.resetDreamDiary,doctor.memory.resetGroundedShortTerm,doctor.memory.repairDreamingArtifactsedoctor.memory.dedupeDreamDiaryaceitam parâmetros opcionais{ "agentId": "agent-id" }para visualizações/ações de Dreaming do agente selecionado. QuandoagentIdé omitido, elas operam no workspace do agente padrão configurado.doctor.memory.remHarnessretorna uma prévia limitada e somente leitura do harness REM para clientes remotos do plano de controle. Ela pode incluir caminhos de workspace, trechos de memória, markdown fundamentado renderizado e candidatos a promoção profunda, portanto os chamadores precisam deoperator.read.sessions.usageretorna resumos de uso por sessão. PasseagentIdpara um agente, ouagentScope: "all"para listar agentes configurados juntos.sessions.usage.timeseriesretorna uso de série temporal para uma sessão.sessions.usage.logsretorna entradas de log de uso para uma sessão.
Canais e auxiliares de login
channels.statusretorna resumos de status de canais/Plugins integrados + empacotados.channels.logoutencerra a sessão de um canal/conta específico quando o canal oferece suporte a logout.web.login.startinicia um fluxo de login por QR/web para o provedor de canal web atual compatível com QR.web.login.waitaguarda a conclusão desse fluxo de login por QR/web e inicia o canal em caso de sucesso.push.testenvia um push APNs de teste para um nó iOS registrado.voicewake.getretorna os gatilhos de palavra de ativação armazenados.voicewake.setatualiza os gatilhos de palavra de ativação e transmite a alteração.
Mensagens e logs
sendé o RPC direto de entrega de saída para envios direcionados por canal/conta/thread fora do executor de chat.logs.tailretorna a cauda configurada do log em arquivo do Gateway com cursor/limite e controles de bytes máximos.
Talk e TTS
talk.catalogretorna o catálogo somente leitura de provedores do Talk para fala, transcrição por streaming e voz em tempo real. Ele inclui IDs canônicos de provedores, aliases do registro, rótulos, estado configurado, um resultado opcionalreadyem nível de grupo, IDs expostos de modelos/vozes, modos canônicos, transportes, estratégias de cérebro e sinalizadores de áudio/capacidade em tempo real sem retornar segredos de provedores nem alterar a configuração global. Gateways atuais definemreadyapós aplicar a seleção de provedor em runtime; clientes devem tratar sua ausência como não verificada para compatibilidade com Gateways mais antigos.talk.configretorna o payload efetivo de configuração do Talk;includeSecretsexigeoperator.talk.secrets(ouoperator.admin).talk.session.createcria uma sessão do Talk pertencente ao Gateway pararealtime/gateway-relay,transcription/gateway-relayoustt-tts/managed-room. Parastt-tts/managed-room, chamadoresoperator.writeque passamsessionKeytambém devem passarspawnedBypara visibilidade escopada da chave de sessão; a criação não escopada desessionKeyebrain: "direct-tools"exigemoperator.admin.talk.session.joinvalida um token de sessão de sala gerenciada, emite eventossession.readyousession.replacedconforme necessário e retorna metadados de sala/sessão mais eventos recentes do Talk sem o token em texto claro nem o hash de token armazenado.talk.session.appendAudioanexa áudio de entrada PCM em base64 a sessões de relay em tempo real e transcrição pertencentes ao Gateway.talk.session.startTurn,talk.session.endTurnetalk.session.cancelTurnconduzem o ciclo de vida de turnos de sala gerenciada com rejeição de turnos obsoletos antes que o estado seja limpo.talk.session.cancelOutputinterrompe a saída de áudio do assistente, principalmente para interrupção controlada por VAD em sessões de relay do Gateway.talk.session.submitToolResultconclui uma chamada de ferramenta de provedor emitida por uma sessão de relay em tempo real pertencente ao Gateway. Passeoptions: { willContinue: true }para saída intermediária de ferramenta quando um resultado final vier depois, ouoptions: { suppressResponse: true }quando o resultado da ferramenta deve satisfazer a chamada do provedor sem iniciar outra resposta de assistente em tempo real.talk.session.steerenvia controle de voz de execução ativa para uma sessão do Talk respaldada por agente e pertencente ao Gateway. Ele aceita{ sessionId, text, mode? }, em quemodeéstatus,steer,canceloufollowup; o modo omitido é classificado a partir do texto falado.talk.session.closefecha uma sessão de relay, transcrição ou sala gerenciada pertencente ao Gateway e emite eventos terminais do Talk.talk.modedefine/transmite o estado atual do modo Talk para clientes WebChat/Control UI.talk.client.createcria uma sessão de provedor em tempo real pertencente ao cliente usandowebrtcouprovider-websocketenquanto o Gateway controla configuração, credenciais, instruções e política de ferramentas.talk.client.toolCallpermite que transportes em tempo real pertencentes ao cliente encaminhem chamadas de ferramenta do provedor para a política do Gateway. A primeira ferramenta compatível éopenclaw_agent_consult; clientes recebem um ID de execução e aguardam eventos normais do ciclo de vida do chat antes de enviar o resultado de ferramenta específico do provedor.talk.client.steerenvia controle de voz de execução ativa para transportes em tempo real pertencentes ao cliente. O Gateway resolve a execução incorporada ativa a partir desessionKeye retorna um resultado estruturado aceito/rejeitado em vez de descartar o direcionamento silenciosamente.talk.eventé o único canal de eventos do Talk para adaptadores em tempo real, transcrição, STT/TTS, sala gerenciada, telefonia e reuniões.talk.speaksintetiza fala por meio do provedor de fala ativo do Talk.tts.statusretorna o estado habilitado do TTS, o provedor ativo, provedores de fallback e o estado de configuração do provedor.tts.providersretorna o inventário visível de provedores de TTS.tts.enableetts.disablealternam o estado das preferências de TTS.tts.setProvideratualiza o provedor de TTS preferido.tts.convertexecuta uma conversão avulsa de texto para fala.
Segredos, configuração, atualização e assistente
secrets.reloadresolve novamente SecretRefs ativos e troca o estado de segredos em runtime apenas em caso de sucesso total.secrets.resolveresolve atribuições de segredos direcionadas a comandos para um conjunto específico de comando/alvo.config.getretorna o snapshot e o hash da configuração atual.config.setgrava um payload de configuração validado.config.patchmescla uma atualização parcial de configuração. A substituição destrutiva de arrays exige o caminho afetado emreplacePaths; arrays aninhados sob entradas de array usam caminhos[], comoagents.list[].skills.config.applyvalida + substitui o payload completo de configuração.config.schemaretorna o payload do esquema de configuração ativo usado pelo Control UI e pelas ferramentas de CLI: esquema,uiHints, versão e metadados de geração, incluindo metadados de esquema de plugin + canal quando o runtime consegue carregá-los. O esquema inclui metadados de campotitle/descriptionderivados dos mesmos rótulos e texto de ajuda usados pela UI, incluindo ramificações de composição de objeto aninhado, curinga, item de array eanyOf/oneOf/allOfquando existe documentação de campo correspondente.config.schema.lookupretorna um payload de consulta escopado por caminho para um caminho de configuração: caminho normalizado, um nó de esquema raso, dica correspondente +hintPath,reloadKindopcional e resumos de filhos imediatos para detalhamento na UI/CLI.reloadKindé um derestart,hotounonee espelha o planejador de recarregamento de configuração do Gateway para o caminho solicitado. Nós de esquema de consulta mantêm a documentação voltada ao usuário e campos comuns de validação (title,description,type,enum,const,format,pattern, limites numéricos/de string/de array/de objeto e sinalizadores comoadditionalProperties,deprecated,readOnly,writeOnly). Resumos de filhos expõemkey,pathnormalizado,type,required,hasChildren,reloadKindopcional, além dehint/hintPathcorrespondentes.update.runexecuta o fluxo de atualização do Gateway e agenda uma reinicialização somente quando a própria atualização foi bem-sucedida; chamadores com uma sessão podem incluircontinuationMessagepara que a inicialização retome um turno de agente de acompanhamento pela fila de continuação de reinicialização. Atualizações de gerenciador de pacotes e atualizações supervisionadas de checkout git a partir do plano de controle usam uma transferência destacada para serviço gerenciado em vez de substituir a árvore de pacotes ou alterar a saída de checkout/build dentro do Gateway ativo. Uma transferência iniciada retornaok: truecomresult.reason: "managed-service-handoff-started"ehandoff.status: "started"; transferências indisponíveis ou com falha retornamok: falsecommanaged-service-handoff-unavailableoumanaged-service-handoff-failed, maishandoff.commandquando uma atualização manual por shell é necessária. Uma transferência indisponível significa que o OpenClaw não tem um limite seguro de supervisor ou uma identidade durável de serviço, comoOPENCLAW_SYSTEMD_UNITpara systemd. Durante uma transferência iniciada, o sentinela de reinicialização pode relatar brevementestats.reason: "restart-health-pending"; a continuação é atrasada até que a CLI verifique o Gateway reiniciado e grave o sentinela finalok.update.statusatualiza e retorna o sentinela de reinicialização de atualização mais recente, incluindo a versão em execução após a reinicialização quando disponível.wizard.start,wizard.next,wizard.statusewizard.cancelexpõem o assistente de onboarding por RPC de WS.
Auxiliares de agente e workspace
agents.listretorna entradas de agente configuradas, incluindo metadados de modelo efetivo e runtime.agents.create,agents.updateeagents.deletegerenciam registros de agente e a conexão com o workspace.agents.files.list,agents.files.geteagents.files.setgerenciam os arquivos de workspace de bootstrap expostos para um agente.tasks.list,tasks.getetasks.cancelexpõem o livro-razão de tarefas do Gateway para clientes SDK e operadores.artifacts.list,artifacts.geteartifacts.downloadexpõem resumos de artefatos derivados de transcrições e downloads para um escopo explícito desessionKey,runIdoutaskId. Consultas de execução e tarefa resolvem a sessão proprietária no servidor e retornam apenas mídia de transcrição com proveniência correspondente; fontes de URL inseguras ou locais retornam downloads sem suporte em vez de buscar no servidor.environments.listeenvironments.statusexpõem descoberta somente leitura de ambientes locais ao Gateway e de nós para clientes SDK.agent.identity.getretorna a identidade efetiva do assistente para um agente ou sessão.agent.waitespera uma execução terminar e retorna o snapshot terminal quando disponível.
Controle de sessão
sessions.listretorna o índice de sessões atual, incluindo metadadosagentRuntimepor linha quando um backend de runtime de agente está configurado.sessions.subscribeesessions.unsubscribealternam assinaturas de eventos de alteração de sessão para o cliente WS atual.sessions.messages.subscribeesessions.messages.unsubscribealternam assinaturas de eventos de transcrição/mensagem para uma sessão.sessions.previewretorna prévias limitadas de transcrição para chaves de sessão específicas.sessions.describeretorna uma linha de sessão do Gateway para uma chave de sessão exata.sessions.resolveresolve ou canonicaliza um destino de sessão.sessions.createcria uma nova entrada de sessão.sessions.sendenvia uma mensagem para uma sessão existente.sessions.steeré a variante de interromper e direcionar para uma sessão ativa.sessions.abortaborta trabalho ativo para uma sessão. Um chamador pode passarkeymaisrunIdopcional, ou passar apenasrunIdpara execuções ativas que o Gateway possa resolver para uma sessão.sessions.patchatualiza metadados/substituições de sessão e relata o modelo canônico resolvido mais oagentRuntimeefetivo.sessions.reset,sessions.deleteesessions.compactexecutam manutenção de sessão.sessions.getretorna a linha completa da sessão armazenada.- A execução de chat ainda usa
chat.history,chat.send,chat.abortechat.inject.chat.historyé normalizado para exibição para clientes de UI: tags de diretiva inline são removidas do texto visível, payloads XML de chamadas de ferramenta em texto simples (incluindo<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e blocos de chamadas de ferramenta truncados) e tokens de controle de modelo ASCII/largura completa vazados são removidos, linhas de assistente com tokens puramente silenciosos, como exatamenteNO_REPLY/no_reply, são omitidas, e linhas grandes demais podem ser substituídas por placeholders. chat.message.geté o leitor aditivo limitado de mensagem completa para uma única entrada de transcrição visível. Clientes passamsessionKey,agentIdopcional quando a seleção de sessão tem escopo de agente, mais ummessageIdde transcrição previamente exposto porchat.history, e o Gateway retorna a mesma projeção normalizada para exibição sem o limite leve de truncamento do histórico quando a entrada armazenada ainda está disponível e não é grande demais.chat.sendaceitafastMode: "auto"de um turno para usar modo rápido em chamadas de modelo iniciadas antes do corte automático e, depois, iniciar chamadas posteriores de nova tentativa, fallback, resultado de ferramenta ou continuação sem modo rápido. O corte usa 60 segundos por padrão e pode ser configurado por modelo comagents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds. Um chamador dechat.sendpode passarfastAutoOnSecondsde um turno para substituir o corte nessa solicitação.
Pareamento de dispositivos e tokens de dispositivo
device.pair.listretorna dispositivos pareados pendentes e aprovados.device.pair.setupCodecria um código de configuração móvel e, por padrão, uma URL de dados QR PNG. Ele exigeoperator.admine é intencionalmente omitido da descoberta anunciada. O resultado incluisetupCode,qrDataUrlopcional,gatewayUrl, o rótulo não secretoautheurlSource.device.pair.approve,device.pair.rejectedevice.pair.removegerenciam registros de pareamento de dispositivos.device.token.rotaterotaciona um token de dispositivo pareado dentro dos limites de função aprovada e escopo do chamador.device.token.revokerevoga um token de dispositivo pareado dentro dos limites de função aprovada e escopo do chamador.
O código de configuração incorpora uma credencial de bootstrap de curta duração. Clientes não devem registrá-la em logs nem persistir a credencial além do fluxo de pareamento.
Pareamento de Node, invoke e trabalho pendente
node.pair.request,node.pair.list,node.pair.approve,node.pair.reject,node.pair.removeenode.pair.verifycobrem pareamento de nós e verificação de bootstrap.node.listenode.describeretornam o estado de nós conhecidos/conectados.node.renameatualiza o rótulo de um nó pareado.node.invokeencaminha um comando para um nó conectado.node.invoke.resultretorna o resultado de uma solicitação de invoke.node.eventcarrega eventos originados em nós de volta para o gateway.node.pending.pullenode.pending.acksão as APIs de fila de nós conectados.node.pending.enqueueenode.pending.draingerenciam trabalho pendente durável para nós offline/desconectados.
Famílias de aprovação
exec.approval.request,exec.approval.get,exec.approval.listeexec.approval.resolvecobrem solicitações de aprovação exec de uso único, além de consulta/reprodução de aprovações pendentes.exec.approval.waitDecisionespera uma aprovação exec pendente e retorna a decisão final (ounullno timeout).exec.approvals.geteexec.approvals.setgerenciam snapshots de política de aprovação exec do gateway.exec.approvals.node.geteexec.approvals.node.setgerenciam política de aprovação exec local ao nó por comandos de retransmissão do nó.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisioneplugin.approval.resolvecobrem fluxos de aprovação definidos por plugins.
Automação, Skills e ferramentas
- Automação:
wakeagenda uma injeção de texto de despertar imediata ou no próximo Heartbeat;cron.get,cron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runsgerenciam trabalho agendado. cron.runpermanece um RPC em estilo de enfileiramento para execuções manuais. Clientes que precisam de semântica de conclusão devem ler orunIdretornado e fazer polling decron.runs.cron.runsaceita um filtrorunIdopcional não vazio para que clientes possam acompanhar uma execução manual enfileirada sem competir com outras entradas de histórico para o mesmo job.- Skills e ferramentas:
commands.list,skills.*,tools.catalog,tools.effective,tools.invoke.
Famílias de eventos comuns
chat: atualizações de chat de UI, comochat.inject, e outros eventos de chat somente de transcrição. No protocolo v4, payloads delta carregamdeltaText;messagepermanece o snapshot cumulativo do assistente. Substituições que não são prefixo definemreplace=truee usamdeltaTextcomo texto de substituição.session.message,session.operationesession.tool: atualizações de transcrição, operação de sessão em andamento e stream de eventos para uma sessão assinada.sessions.changed: índice de sessões ou metadados alterados.presence: atualizações de snapshot de presença do sistema.tick: evento periódico de keepalive / liveness.health: atualização de snapshot de integridade do gateway.heartbeat: atualização de stream de eventos de Heartbeat.cron: evento de alteração de execução/job do cron.shutdown: notificação de desligamento do gateway.node.pair.requested/node.pair.resolved: ciclo de vida de pareamento de nós.node.invoke.request: transmissão de solicitação de invoke de nó.device.pair.requested/device.pair.resolved: ciclo de vida de dispositivo pareado.voicewake.changed: configuração de gatilho de palavra de despertar alterada.exec.approval.requested/exec.approval.resolved: ciclo de vida de aprovação exec.plugin.approval.requested/plugin.approval.resolved: ciclo de vida de aprovação de plugin.
Métodos auxiliares de Node
- Nós podem chamar
skills.binspara buscar a lista atual de executáveis de Skills para verificações de permissão automática.
RPCs do livro-razão de tarefas
Clientes operadores podem inspecionar e cancelar registros de tarefas em segundo plano do Gateway por meio dos RPCs do livro-razão de tarefas. Esses métodos retornam resumos de tarefas sanitizados, não estado bruto de runtime.
tasks.listexigeoperator.read.- Parâmetros:
statusopcional ("queued","running","completed","failed","cancelled"ou"timed_out") ou um array desses status,agentIdopcional,sessionKeyopcional,limitopcional de1a500e stringcursoropcional. - Resultado:
{ "tasks": TaskSummary[], "nextCursor"?: string }.
- Parâmetros:
tasks.getexigeoperator.read.- Parâmetros:
{ "taskId": string }. - Resultado:
{ "task": TaskSummary }. - IDs de tarefa ausentes retornam o formato de erro não encontrado do Gateway.
- Parâmetros:
tasks.cancelexigeoperator.write.- Parâmetros:
{ "taskId": string, "reason"?: string }. - Resultado:
{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }. foundinforma se o livro-razão tinha uma tarefa correspondente.cancelledinforma se o runtime aceitou ou registrou o cancelamento.
- Parâmetros:
TaskSummary inclui id, status e metadados opcionais como kind,
runtime, title, agentId, sessionKey, childSessionKey, ownerKey,
runId, taskId, flowId, parentTaskId, sourceId, timestamps, progresso,
resumo terminal e texto de erro sanitizado. agentId identifica o agente
que executa a tarefa; sessionKey e ownerKey preservam o contexto de solicitante e controle.
Métodos auxiliares de operador
- Operadores podem chamar
commands.list(operator.read) para buscar o inventário de comandos em tempo de execução de um agente.agentIdé opcional; omita-o para ler o workspace padrão do agente.scopecontrola qual superfície onameprimário tem como alvo:textretorna o token primário de comando de texto sem o/inicialnativee o caminho padrãobothretornam nomes nativos cientes do provedor quando disponíveis
textAliasescarrega aliases exatos com barra, como/modele/m.nativeNamecarrega o nome de comando nativo ciente do provedor quando existir.provideré opcional e afeta apenas a nomenclatura nativa e a disponibilidade de comandos nativos de plugin.includeArgs=falseomite metadados de argumentos serializados da resposta.
- Operadores podem chamar
tools.catalog(operator.read) para buscar o catálogo de ferramentas em tempo de execução de um agente. A resposta inclui ferramentas agrupadas e metadados de proveniência:source:coreoupluginpluginId: proprietário do plugin quandosource="plugin"optional: se uma ferramenta de plugin é opcional
- Operadores podem chamar
tools.effective(operator.read) para buscar o inventário de ferramentas efetivo em tempo de execução para uma sessão.sessionKeyé obrigatório.- O Gateway deriva o contexto confiável de tempo de execução da sessão no lado do servidor, em vez de aceitar contexto de autenticação ou entrega fornecido pelo chamador.
- A resposta é uma projeção derivada pelo servidor e com escopo de sessão do inventário ativo, incluindo ferramentas de core, plugin, canal e servidores MCP já descobertos.
tools.effectiveé somente leitura para MCP: ele pode projetar um catálogo MCP de sessão aquecida por meio da política final de ferramentas, mas não cria runtimes MCP, conecta transportes nem emitetools/list. Se não existir um catálogo aquecido correspondente, a resposta pode incluir um aviso comomcp-not-yet-connected,mcp-not-yet-listedoumcp-stale-catalog.- Entradas de ferramentas efetivas usam
source="core",source="plugin",source="channel"ousource="mcp".
- Operadores podem chamar
tools.invoke(operator.write) para invocar uma ferramenta disponível pelo mesmo caminho de política do Gateway que/tools/invoke.nameé obrigatório.args,sessionKey,agentId,confirmeidempotencyKeysão opcionais.- Se
sessionKeyeagentIdestiverem presentes, o agente da sessão resolvida deve corresponder aagentId. - Wrappers de core somente para proprietário, como
cron,gatewayenodes, exigem identidade de proprietário/admin (operator.admin), embora o próprio métodotools.invokesejaoperator.write. - A resposta é um envelope voltado para SDK com
ok,toolName,outputopcional e camposerrortipados. Recusas por aprovação ou política retornamok:falseno payload em vez de contornar o pipeline de política de ferramentas do Gateway.
- Operadores podem chamar
skills.status(operator.read) para buscar o inventário visível de skills de um agente.agentIdé opcional; omita-o para ler o workspace padrão do agente.- A resposta inclui elegibilidade, requisitos ausentes, verificações de configuração e opções de instalação sanitizadas sem expor valores brutos de segredos.
- Operadores podem chamar
skills.searcheskills.detail(operator.read) para metadados de descoberta do ClawHub. - Operadores podem chamar
skills.upload.begin,skills.upload.chunkeskills.upload.commit(operator.admin) para preparar um arquivo privado de skill antes de instalá-lo. Este é um caminho separado de upload administrativo para clientes confiáveis, não o fluxo normal de instalação de skill do ClawHub, e fica desabilitado por padrão, a menos queskills.install.allowUploadedArchivesesteja habilitado.skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })cria um upload vinculado a esse slug e valor de force.skills.upload.chunk({ uploadId, offset, dataBase64 })acrescenta bytes no deslocamento decodificado exato.skills.upload.commit({ uploadId, sha256? })verifica o tamanho final e o SHA-256. O commit apenas finaliza o upload; ele não instala a skill.- Arquivos de skills enviados são arquivos zip contendo uma raiz
SKILL.md. O nome do diretório interno do arquivo nunca seleciona o alvo da instalação.
- Operadores podem chamar
skills.install(operator.admin) em três modos:- Modo ClawHub:
{ source: "clawhub", slug, version?, force? }instala uma pasta de skill no diretórioskills/do workspace padrão do agente. - Modo upload:
{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }instala um upload confirmado no diretórioskills/<slug>do workspace padrão do agente. O slug e o valor de force devem corresponder à solicitação originalskills.upload.begin. Este modo é rejeitado, a menos queskills.install.allowUploadedArchivesesteja habilitado. A configuração não afeta instalações do ClawHub. - Modo instalador do Gateway:
{ name, installId, timeoutMs? }executa uma açãometadata.openclaw.installdeclarada no host do Gateway. Clientes mais antigos ainda podem enviardangerouslyForceUnsafeInstall; este campo está obsoleto, é aceito apenas para compatibilidade de protocolo e é ignorado. Usesecurity.installPolicypara decisões de instalação controladas pelo operador.
- Modo ClawHub:
- Operadores podem chamar
skills.update(operator.admin) em dois modos:- O modo ClawHub atualiza um slug rastreado ou todas as instalações rastreadas do ClawHub no workspace padrão do agente.
- O modo config aplica patches a valores de
skills.entries.<skillKey>, comoenabled,apiKeyeenv.
Visualizações de models.list
models.list aceita um parâmetro opcional view:
- Omitido ou
"default": comportamento atual em tempo de execução. Seagents.defaults.modelsestiver configurado, a resposta será o catálogo permitido, incluindo modelos descobertos dinamicamente para entradasprovider/*. Caso contrário, a resposta será o catálogo completo do Gateway. "configured": comportamento dimensionado para seletores. Seagents.defaults.modelsestiver configurado, ele ainda prevalece, incluindo descoberta com escopo de provedor para entradasprovider/*. Sem uma allowlist, a resposta usa entradas explícitas demodels.providers.*.models, recorrendo ao catálogo completo apenas quando não existem linhas de modelo configuradas."all": catálogo completo do Gateway, ignorandoagents.defaults.models. Use isto para diagnósticos e UIs de descoberta, não para seletores normais de modelo.
Aprovações de exec
- Quando uma solicitação de exec precisa de aprovação, o Gateway transmite
exec.approval.requested. - Clientes operadores resolvem chamando
exec.approval.resolve(exige escopooperator.approvals). - Para
host=node,exec.approval.requestdeve incluirsystemRunPlan(argv/cwd/rawCommand/metadados de sessão canônicos). Solicitações semsystemRunPlansão rejeitadas. - Após a aprovação, chamadas encaminhadas de
node.invoke system.runreutilizam essesystemRunPlancanônico como o contexto autoritativo de comando/cwd/sessão. - Se um chamador modificar
command,rawCommand,cwd,agentIdousessionKeyentre a preparação e o encaminhamento final aprovado desystem.run, o Gateway rejeitará a execução em vez de confiar no payload modificado.
Fallback de entrega do agente
- Solicitações
agentpodem incluirdeliver=truepara solicitar entrega de saída. bestEffortDeliver=falsemantém o comportamento estrito: alvos de entrega não resolvidos ou somente internos retornamINVALID_REQUEST.bestEffortDeliver=truepermite fallback para execução apenas na sessão quando nenhuma rota externa entregável puder ser resolvida (por exemplo, sessões internas/webchat ou configurações multicanal ambíguas).- Resultados finais de
agentpodem incluirresult.deliveryStatusquando a entrega foi solicitada, usando os mesmos statussent,suppressed,partial_failedefaileddocumentados paraopenclaw agent --json --deliver.
Versionamento
PROTOCOL_VERSIONfica empackages/gateway-protocol/src/version.ts.- Clientes enviam
minProtocol+maxProtocol; o servidor rejeita intervalos que não incluem seu protocolo atual. Clientes e servidores atuais exigem o protocolo v4. - Esquemas + modelos são gerados a partir de definições TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Constantes do cliente
O cliente de referência em src/gateway/client.ts usa estes padrões. Os valores são estáveis no protocolo v4 e são a linha de base esperada para clientes de terceiros.
| Constante | Padrão | Fonte |
|---|---|---|
PROTOCOL_VERSION |
4 |
packages/gateway-protocol/src/version.ts |
MIN_CLIENT_PROTOCOL_VERSION |
4 |
packages/gateway-protocol/src/version.ts |
| Tempo limite da solicitação (por RPC) | 30_000 ms |
src/gateway/client.ts (requestTimeoutMs) |
| Tempo limite de preauth / connect-challenge | 15_000 ms |
src/gateway/handshake-timeouts.ts (config/env podem aumentar o orçamento pareado servidor/cliente) |
| Backoff inicial de reconexão | 1_000 ms |
src/gateway/client.ts (backoffMs) |
| Backoff máximo de reconexão | 30_000 ms |
src/gateway/client.ts (scheduleReconnect) |
| Limite de retentativa rápida após fechamento por device-token | 250 ms |
src/gateway/client.ts |
Carência de force-stop antes de terminate() |
250 ms |
FORCE_STOP_TERMINATE_GRACE_MS |
Tempo limite padrão de stopAndWait() |
1_000 ms |
STOP_AND_WAIT_TIMEOUT_MS |
Intervalo de tick padrão (pré hello-ok) |
30_000 ms |
src/gateway/client.ts |
| Fechamento por tick-timeout | código 4000 quando o silêncio excede tickIntervalMs * 2 |
src/gateway/client.ts |
MAX_PAYLOAD_BYTES |
25 * 1024 * 1024 (25 MB) |
src/gateway/server-constants.ts |
O servidor anuncia policy.tickIntervalMs, policy.maxPayload e policy.maxBufferedBytes efetivos em hello-ok; clientes devem respeitar esses valores em vez dos padrões pré-handshake.
Auth
- A autenticação do Gateway por segredo compartilhado usa
connect.params.auth.tokenouconnect.params.auth.password, dependendo do modo de autenticação configurado. - Modos com identidade, como Tailscale Serve
(
gateway.auth.allowTailscale: true) ougateway.auth.mode: "trusted-proxy"sem loopback, satisfazem a verificação de autenticação de connect a partir dos cabeçalhos da solicitação, em vez deconnect.params.auth.*. gateway.auth.mode: "none"de ingresso privado ignora totalmente a autenticação de connect por segredo compartilhado; não exponha esse modo em ingresso público/não confiável.- Após o pareamento, o Gateway emite um token de dispositivo com escopo limitado à função
da conexão + escopos. Ele é retornado em
hello-ok.auth.deviceTokene deve ser persistido pelo cliente para conexões futuras. - Os clientes devem persistir o
hello-ok.auth.deviceTokenprimário após qualquer conexão bem-sucedida. - Reconectar com esse token de dispositivo armazenado também deve reutilizar o conjunto de escopos aprovados armazenado para esse token. Isso preserva o acesso de leitura/sondagem/status que já foi concedido e evita reduzir silenciosamente as reconexões para um escopo implícito mais restrito, somente de administrador.
- Montagem da autenticação de connect no lado do cliente (
selectConnectAuthemsrc/gateway/client.ts):auth.passwordé ortogonal e sempre é encaminhado quando definido.auth.tokené preenchido em ordem de prioridade: primeiro o token compartilhado explícito, depois umdeviceTokenexplícito, depois um token armazenado por dispositivo (indexado pordeviceId+role).auth.bootstrapTokené enviado somente quando nenhum dos itens acima resolveu umauth.token. Um token compartilhado ou qualquer token de dispositivo resolvido o suprime.- A promoção automática de um token de dispositivo armazenado na nova tentativa única
AUTH_TOKEN_MISMATCHé restrita a endpoints confiáveis apenas — loopback ouwss://com umtlsFingerprintfixado.wss://público sem fixação não se qualifica.
- O bootstrap de código de configuração integrado retorna o
hello-ok.auth.deviceTokendo Node primário mais um token de operador limitado emhello-ok.auth.deviceTokenspara transferência móvel confiável. O token de operador incluioperator.talk.secretspara leituras de configuração nativa do Talk, mas exclui escopos de mutação de pareamento eoperator.admin. - Enquanto um bootstrap de código de configuração não basal aguarda aprovação, os detalhes de
PAIRING_REQUIREDincluemrecommendedNextStep: "wait_then_retry",retryable: trueepauseReconnect: false. Os clientes devem continuar reconectando com o mesmo token de bootstrap até que a solicitação seja aprovada ou o token se torne inválido. - Persista
hello-ok.auth.deviceTokenssomente quando a conexão usar autenticação de bootstrap em um transporte confiável, comowss://ou pareamento local/loopback. - Se um cliente fornece um
deviceTokenexplícito ouscopesexplícitos, esse conjunto de escopos solicitado pelo chamador permanece autoritativo; escopos em cache só são reutilizados quando o cliente está reutilizando o token armazenado por dispositivo. - Tokens de dispositivo podem ser rotacionados/revogados por meio de
device.token.rotateedevice.token.revoke(exige o escopooperator.pairing). Rotacionar ou revogar um Node ou outra função não operadora também exigeoperator.admin. device.token.rotateretorna metadados de rotação. Ele ecoa o token bearer de substituição somente para chamadas do mesmo dispositivo que já estão autenticadas com esse token de dispositivo, para que clientes somente com token possam persistir a substituição antes de reconectar. Rotações compartilhadas/de administrador não ecoam o token bearer.- A emissão, rotação e revogação de tokens permanecem limitadas ao conjunto de funções aprovado registrado na entrada de pareamento desse dispositivo; a mutação de token não pode expandir nem direcionar uma função de dispositivo que a aprovação de pareamento nunca concedeu.
- Para sessões de token de dispositivo pareado, o gerenciamento de dispositivos é autoescopado, a menos que o
chamador também tenha
operator.admin: chamadores não administradores podem gerenciar somente o token de operador da entrada do próprio dispositivo. O gerenciamento de tokens de Node e de outros não operadores é somente de administrador, mesmo para o próprio dispositivo do chamador. device.token.rotateedevice.token.revoketambém verificam o conjunto de escopos do token de operador de destino em relação aos escopos da sessão atual do chamador. Chamadores não administradores não podem rotacionar nem revogar um token de operador mais amplo do que já possuem.- Falhas de autenticação incluem
error.details.codemais dicas de recuperação:error.details.canRetryWithDeviceToken(booleano)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Comportamento do cliente para
AUTH_TOKEN_MISMATCH:- Clientes confiáveis podem tentar uma nova tentativa limitada com um token em cache por dispositivo.
- Se essa nova tentativa falhar, os clientes devem interromper loops de reconexão automática e exibir orientação de ação para o operador.
AUTH_SCOPE_MISMATCHsignifica que o token de dispositivo foi reconhecido, mas não cobre a função/escopos solicitados. Os clientes não devem apresentar isso como um token inválido; solicite que o operador faça o pareamento novamente ou aprove o contrato de escopo mais restrito/mais amplo.
Identidade do dispositivo + pareamento
- Nodes devem incluir uma identidade de dispositivo estável (
device.id) derivada de uma impressão digital de par de chaves. - Gateways emitem tokens por dispositivo + função.
- Aprovações de pareamento são exigidas para novos IDs de dispositivo, a menos que a aprovação automática local esteja habilitada.
- A aprovação automática de pareamento é centrada em conexões diretas de local loopback.
- O OpenClaw também tem um caminho restrito de autoconexão local de backend/contêiner para fluxos auxiliares confiáveis de segredo compartilhado.
- Conexões de tailnet ou LAN no mesmo host ainda são tratadas como remotas para pareamento e exigem aprovação.
- Clientes WS normalmente incluem identidade
deviceduranteconnect(operador + Node). As únicas exceções de operador sem dispositivo são caminhos de confiança explícitos:gateway.controlUi.allowInsecureAuth=truepara compatibilidade com HTTP inseguro somente em localhost.- autenticação bem-sucedida do Control UI de operador com
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(break-glass, rebaixamento severo de segurança).- RPCs de backend
gateway-clientde loopback direto no caminho auxiliar interno reservado.
- Omitir a identidade do dispositivo tem consequências de escopo. Quando uma conexão
de operador sem dispositivo é permitida por meio de um caminho de confiança explícito, o OpenClaw ainda limpa
os escopos autodeclarados para um conjunto vazio, a menos que esse caminho tenha uma exceção nomeada
de preservação de escopo. Métodos protegidos por escopo então falham com
missing scope. gateway.controlUi.dangerouslyDisableDeviceAuth=trueé um caminho break-glass de preservação de escopo do Control UI. Ele não concede escopos a clientes WebSocket arbitrários personalizados de backend ou em formato de CLI.- O caminho auxiliar de backend
gateway-clientreservado de loopback direto preserva escopos apenas para RPCs internos locais do plano de controle; IDs personalizados de backend não recebem essa exceção. - Todas as conexões devem assinar o nonce
connect.challengefornecido pelo servidor.
Diagnósticos de migração de autenticação de dispositivo
Para clientes legados que ainda usam o comportamento de assinatura anterior ao desafio, connect agora retorna
códigos de detalhe DEVICE_AUTH_* em error.details.code com um error.details.reason estável.
Falhas comuns de migração:
| Mensagem | details.code | details.reason | Significado |
|---|---|---|---|
device nonce required |
DEVICE_AUTH_NONCE_REQUIRED |
device-nonce-missing |
O cliente omitiu device.nonce (ou enviou em branco). |
device nonce mismatch |
DEVICE_AUTH_NONCE_MISMATCH |
device-nonce-mismatch |
O cliente assinou com um nonce obsoleto/incorreto. |
device signature invalid |
DEVICE_AUTH_SIGNATURE_INVALID |
device-signature |
A carga de assinatura não corresponde à carga v2. |
device signature expired |
DEVICE_AUTH_SIGNATURE_EXPIRED |
device-signature-stale |
O carimbo de data/hora assinado está fora da tolerância permitida. |
device identity mismatch |
DEVICE_AUTH_DEVICE_ID_MISMATCH |
device-id-mismatch |
device.id não corresponde à impressão digital da chave pública. |
device public key invalid |
DEVICE_AUTH_PUBLIC_KEY_INVALID |
device-public-key |
O formato/canonicalização da chave pública falhou. |
Destino da migração:
- Sempre aguarde
connect.challenge. - Assine a carga v2 que inclui o nonce do servidor.
- Envie o mesmo nonce em
connect.params.device.nonce. - A carga de assinatura preferida é
v3, que vinculaplatformedeviceFamilyalém dos campos device/client/role/scopes/token/nonce. - Assinaturas legadas
v2continuam aceitas para compatibilidade, mas a fixação de metadados de dispositivo pareado ainda controla a política de comandos na reconexão.
TLS + fixação
- TLS é compatível com conexões WS.
- Os clientes podem, opcionalmente, fixar a impressão digital do certificado do Gateway (consulte a configuração
gateway.tlsmaisgateway.remote.tlsFingerprintou a CLI--tls-fingerprint).
Escopo
Este protocolo expõe a API completa do Gateway (status, canais, modelos, chat,
agente, sessões, Nodes, aprovações etc.). A superfície exata é definida pelos
esquemas TypeBox em packages/gateway-protocol/src/schema.ts.