Protocollo Gateway (WebSocket)
Il protocollo WS del Gateway è il singolo piano di controllo + trasporto dei node per OpenClaw. Tutti i client (CLI, interfaccia web, app macOS, node iOS/Android, node headless) si connettono tramite WebSocket e dichiarano il proprio ruolo + ambito al momento dell’handshake.Trasporto
- WebSocket, frame di testo con payload JSON.
- Il primo frame deve essere una richiesta
connect.
Handshake (connect)
Gateway → Client (challenge di pre-connessione):server, features, snapshot e policy sono tutti obbligatori nello schema
(src/gateway/protocol/schema/frames.ts). canvasHostUrl è facoltativo. auth
riporta il ruolo/gli scope negoziati quando disponibili e include deviceToken
quando il gateway ne emette uno.
Quando non viene emesso alcun token del dispositivo, hello-ok.auth può comunque riportare i
permessi negoziati:
hello-ok include anche:
hello-ok.auth può includere anche
voci di ruolo aggiuntive con ambito limitato in deviceTokens:
scopes: [] e qualsiasi token operator passato rimane limitato alla allowlist
dell’operator di bootstrap (operator.approvals, operator.read,
operator.talk.secrets, operator.write). I controlli degli scope di bootstrap restano
con prefisso del ruolo: le voci operator soddisfano solo le richieste operator e i ruoli non operator
continuano a richiedere scope sotto il prefisso del proprio ruolo.
Esempio di node
Framing
- Request:
{type:"req", id, method, params} - Response:
{type:"res", id, ok, payload|error} - Event:
{type:"event", event, payload, seq?, stateVersion?}
Ruoli + scope
Ruoli
operator= client del piano di controllo (CLI/UI/automazione).node= host delle capacità (camera/screen/canvas/system.run).
Scope (operator)
Scope comuni:operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config con includeSecrets: true richiede operator.talk.secrets
(o operator.admin).
I metodi RPC del Gateway registrati dai Plugin possono richiedere un proprio scope operator, ma
i prefissi admin core riservati (config.*, exec.approvals.*, wizard.*,
update.*) vengono sempre risolti come operator.admin.
Lo scope del metodo è solo il primo controllo. Alcuni comandi slash raggiunti tramite
chat.send applicano controlli a livello di comando più restrittivi in aggiunta. Per esempio, le scritture
persistenti /config set e /config unset richiedono operator.admin.
Anche node.pair.approve ha un controllo degli scope aggiuntivo al momento dell’approvazione oltre allo
scope di base del metodo:
- richieste senza comando:
operator.pairing - richieste con comandi node non exec:
operator.pairing+operator.write - richieste che includono
system.run,system.run.prepareosystem.which:operator.pairing+operator.admin
Caps/commands/permissions (node)
I node dichiarano le proprie capacità al momento della connessione:caps: categorie di capacità di alto livello.commands: allowlist dei comandi per invoke.permissions: toggle granulari (ad esempioscreen.record,camera.capture).
Presenza
system-presencerestituisce voci indicate in base all’identità del dispositivo.- Le voci di presenza includono
deviceId,rolesescopescosì le UI possono mostrare una singola riga per dispositivo anche quando questo si connette sia come operator sia come node.
Famiglie comuni di metodi RPC
Questa pagina non è un dump completo generato, ma la superficie WS pubblica è più ampia dei soli esempi di handshake/auth sopra. Queste sono le principali famiglie di metodi che il Gateway espone oggi.hello-ok.features.methods è un elenco di individuazione conservativo costruito da
src/gateway/server-methods-list.ts più le esportazioni dei metodi di plugin/channel caricati.
Trattalo come individuazione delle funzionalità, non come un dump generato di ogni helper richiamabile
implementato in src/gateway/server-methods/*.ts.
Sistema e identità
healthrestituisce lo snapshot dello stato del gateway memorizzato nella cache o appena verificato.statusrestituisce il riepilogo del gateway in stile/status; i campi sensibili sono inclusi solo per i client operator con scope admin.gateway.identity.getrestituisce l’identità del dispositivo gateway usata dai flussi relay e pairing.system-presencerestituisce lo snapshot di presenza corrente per i dispositivi operator/node connessi.system-eventaggiunge un evento di sistema e può aggiornare/trasmettere il contesto di presenza.last-heartbeatrestituisce l’ultimo evento Heartbeat persistito.set-heartbeatsattiva o disattiva l’elaborazione Heartbeat sul gateway.
Modelli e utilizzo
models.listrestituisce il catalogo dei modelli consentiti a runtime.usage.statusrestituisce finestre di utilizzo dei provider/riepiloghi della quota residua.usage.costrestituisce riepiloghi aggregati dei costi di utilizzo per un intervallo di date.doctor.memory.statusrestituisce lo stato di prontezza di memoria vettoriale / embedding per il workspace dell’agente predefinito attivo.sessions.usagerestituisce riepiloghi di utilizzo per sessione.sessions.usage.timeseriesrestituisce serie temporali di utilizzo per una sessione.sessions.usage.logsrestituisce le voci del log di utilizzo per una sessione.
Canali e helper di accesso
channels.statusrestituisce riepiloghi di stato dei canali/plugin integrati + inclusi.channels.logoutdisconnette un canale/account specifico nei casi in cui il canale supporti il logout.web.login.startavvia un flusso di accesso QR/web per il provider del canale web compatibile con QR attualmente in uso.web.login.waitattende il completamento di quel flusso di accesso QR/web e avvia il canale in caso di successo.push.testinvia una notifica push APNs di test a un node iOS registrato.voicewake.getrestituisce i trigger della parola di attivazione memorizzati.voicewake.setaggiorna i trigger della parola di attivazione e trasmette la modifica.
Messaggistica e log
sendè l’RPC di consegna diretta in uscita per invii mirati a canale/account/thread al di fuori del runner di chat.logs.tailrestituisce la coda del log file del gateway configurato con controlli di cursore/limite e byte massimi.
Talk e TTS
talk.configrestituisce il payload effettivo della configurazione Talk;includeSecretsrichiedeoperator.talk.secrets(ooperator.admin).talk.modeimposta/trasmette lo stato attuale della modalità Talk per i client WebChat/Control UI.talk.speaksintetizza il parlato tramite il provider speech Talk attivo.tts.statusrestituisce lo stato di abilitazione TTS, il provider attivo, i provider di fallback e lo stato di configurazione del provider.tts.providersrestituisce l’inventario visibile dei provider TTS.tts.enableetts.disableattivano e disattivano lo stato delle preferenze TTS.tts.setProvideraggiorna il provider TTS preferito.tts.convertesegue una conversione text-to-speech una tantum.
Secrets, config, update e wizard
secrets.reloadrisolve nuovamente i SecretRef attivi e sostituisce lo stato dei segreti a runtime solo in caso di successo completo.secrets.resolverisolve le assegnazioni dei segreti destinati ai comandi per un insieme specifico di comando/destinazione.config.getrestituisce lo snapshot e l’hash della configurazione corrente.config.setscrive un payload di configurazione validato.config.patchunisce un aggiornamento parziale della configurazione.config.applyvalida e sostituisce il payload di configurazione completo.config.schemarestituisce il payload dello schema di configurazione live usato da Control UI e dagli strumenti CLI: schema,uiHints, versione e metadati di generazione, inclusi metadati di schema di plugin + canale quando il runtime può caricarli. Lo schema include metadati dei campititle/descriptionderivati dalle stesse etichette e dallo stesso testo di aiuto usati dalla UI, incluse le diramazioni di composizione annidate di oggetto, wildcard, elemento di array eanyOf/oneOf/allOfquando esiste documentazione dei campi corrispondente.config.schema.lookuprestituisce un payload di ricerca con ambito al percorso per un percorso di configurazione: percorso normalizzato, un nodo di schema superficiale, hint corrispondente +hintPath, e riepiloghi dei figli immediati per drill-down UI/CLI.- I nodi di schema di ricerca mantengono la documentazione visibile all’utente e i comuni campi di validazione:
title,description,type,enum,const,format,pattern, limiti numerici/stringa/array/oggetto e flag booleani comeadditionalProperties,deprecated,readOnly,writeOnly. - I riepiloghi dei figli espongono
key,pathnormalizzato,type,required,hasChildren, oltre ahint/hintPathcorrispondenti.
- I nodi di schema di ricerca mantengono la documentazione visibile all’utente e i comuni campi di validazione:
update.runesegue il flusso di aggiornamento del gateway e pianifica un riavvio solo quando l’aggiornamento stesso è riuscito.wizard.start,wizard.next,wizard.statusewizard.cancelespongono la procedura guidata di onboarding tramite WS RPC.
Principali famiglie esistenti
Helper per agente e workspace
agents.listrestituisce le voci degli agenti configurati.agents.create,agents.updateeagents.deletegestiscono i record degli agenti e il wiring del workspace.agents.files.list,agents.files.geteagents.files.setgestiscono i file del workspace di bootstrap esposti per un agente.agent.identity.getrestituisce l’identità effettiva dell’assistente per un agente o una sessione.agent.waitattende il completamento di un’esecuzione e restituisce lo snapshot terminale quando disponibile.
Controllo della sessione
sessions.listrestituisce l’indice corrente delle sessioni.sessions.subscribeesessions.unsubscribeattivano o disattivano le sottoscrizioni agli eventi di modifica della sessione per il client WS corrente.sessions.messages.subscribeesessions.messages.unsubscribeattivano o disattivano le sottoscrizioni agli eventi di trascrizione/messaggio per una sessione.sessions.previewrestituisce anteprime limitate della trascrizione per chiavi di sessione specifiche.sessions.resolverisolve o canonizza una destinazione di sessione.sessions.createcrea una nuova voce di sessione.sessions.sendinvia un messaggio in una sessione esistente.sessions.steerè la variante di interruzione e reindirizzamento per una sessione attiva.sessions.abortinterrompe il lavoro attivo per una sessione.sessions.patchaggiorna i metadati/le sostituzioni della sessione.sessions.reset,sessions.deleteesessions.compacteseguono operazioni di manutenzione della sessione.sessions.getrestituisce l’intera riga di sessione memorizzata.- L’esecuzione della chat usa ancora
chat.history,chat.send,chat.abortechat.inject. chat.historyè normalizzato per la visualizzazione per i client UI: i tag di direttiva inline vengono rimossi dal testo visibile, i payload XML di chiamata di strumenti in testo semplice (inclusi<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>e i blocchi di chiamata di strumenti troncati) e i token di controllo del modello ASCII/a larghezza piena fuoriusciti vengono rimossi, le righe assistant composte solo da token silenziosi come l’esattoNO_REPLY/no_replyvengono omesse e le righe troppo grandi possono essere sostituite con segnaposto.
Associazione dei dispositivi e token del dispositivo
device.pair.listrestituisce i dispositivi associati in attesa e approvati.device.pair.approve,device.pair.rejectedevice.pair.removegestiscono i record di associazione dei dispositivi.device.token.rotateruota un token di dispositivo associato entro i limiti del ruolo e dello scope approvati.device.token.revokerevoca un token di dispositivo associato.
Associazione dei node, invoke e lavoro in sospeso
node.pair.request,node.pair.list,node.pair.approve,node.pair.rejectenode.pair.verifycoprono l’associazione dei node e la verifica del bootstrap.node.listenode.describerestituiscono lo stato dei node conosciuti/connessi.node.renameaggiorna l’etichetta di un node associato.node.invokeinoltra un comando a un node connesso.node.invoke.resultrestituisce il risultato di una richiesta invoke.node.eventtrasporta nel gateway gli eventi originati dal node.node.canvas.capability.refreshaggiorna i token delle capacità canvas con scope limitato.node.pending.pullenode.pending.acksono le API di coda per i node connessi.node.pending.enqueueenode.pending.draingestiscono il lavoro in sospeso durevole per i node offline/disconnessi.
Famiglie di approvazione
exec.approval.request,exec.approval.get,exec.approval.listeexec.approval.resolvecoprono le richieste di approvazione exec una tantum più la ricerca/riproduzione delle approvazioni in sospeso.exec.approval.waitDecisionattende una decisione di approvazione exec in sospeso e restituisce la decisione finale (onullin caso di timeout).exec.approvals.geteexec.approvals.setgestiscono gli snapshot dei criteri di approvazione exec del gateway.exec.approvals.node.geteexec.approvals.node.setgestiscono i criteri locali di approvazione exec del node tramite comandi relay del node.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisioneplugin.approval.resolvecoprono i flussi di approvazione definiti dai Plugin.
Altre famiglie principali
- automazione:
wakepianifica un’iniezione di testo wake immediata o al prossimo Heartbeatcron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runs
- Skills/strumenti:
commands.list,skills.*,tools.catalog,tools.effective
Famiglie di eventi comuni
chat: aggiornamenti della chat UI comechat.injecte altri eventi di chat solo di trascrizione.session.messageesession.tool: aggiornamenti della trascrizione/del flusso di eventi per una sessione sottoscritta.sessions.changed: l’indice della sessione o i metadati sono cambiati.presence: aggiornamenti dello snapshot di presenza del sistema.tick: evento periodico di keepalive / verifica di attività.health: aggiornamento dello snapshot dello stato del gateway.heartbeat: aggiornamento del flusso di eventi Heartbeat.cron: evento di modifica dell’esecuzione/del job Cron.shutdown: notifica di arresto del gateway.node.pair.requested/node.pair.resolved: ciclo di vita dell’associazione dei node.node.invoke.request: trasmissione della richiesta invoke del node.device.pair.requested/device.pair.resolved: ciclo di vita del dispositivo associato.voicewake.changed: la configurazione del trigger della parola di attivazione è cambiata.exec.approval.requested/exec.approval.resolved: ciclo di vita dell’approvazione exec.plugin.approval.requested/plugin.approval.resolved: ciclo di vita dell’approvazione del Plugin.
Metodi helper del node
- I node possono chiamare
skills.binsper recuperare l’elenco corrente degli eseguibili delle Skills per i controlli di autorizzazione automatica.
Metodi helper dell’operator
- Gli operator possono chiamare
commands.list(operator.read) per recuperare l’inventario dei comandi a runtime per un agente.agentIdè facoltativo; omettilo per leggere il workspace dell’agente predefinito.scopecontrolla quale superficie usa ilnameprimario:textrestituisce il token del comando di testo primario senza la/inizialenativee il percorso predefinitobothrestituiscono nomi nativi dipendenti dal provider quando disponibili
textAliasescontiene alias slash esatti come/modele/m.nativeNamecontiene il nome del comando nativo dipendente dal provider quando esiste.providerè facoltativo e influisce solo sulla denominazione nativa più sulla disponibilità dei comandi nativi del Plugin.includeArgs=falseomette i metadati degli argomenti serializzati dalla risposta.
- Gli operator possono chiamare
tools.catalog(operator.read) per recuperare il catalogo degli strumenti a runtime per un agente. La risposta include strumenti raggruppati e metadati di provenienza:source:coreopluginpluginId: proprietario del Plugin quandosource="plugin"optional: indica se uno strumento del Plugin è facoltativo
- Gli operator possono chiamare
tools.effective(operator.read) per recuperare l’inventario effettivo degli strumenti a runtime per una sessione.sessionKeyè obbligatorio.- Il gateway ricava il contesto runtime attendibile dalla sessione lato server invece di accettare auth o contesto di consegna forniti dal chiamante.
- La risposta ha ambito di sessione e riflette ciò che la conversazione attiva può usare in quel momento, inclusi gli strumenti core, dei Plugin e dei canali.
- Gli operator possono chiamare
skills.status(operator.read) per recuperare l’inventario visibile delle Skills per un agente.agentIdè facoltativo; omettilo per leggere il workspace dell’agente predefinito.- La risposta include idoneità, requisiti mancanti, controlli di configurazione e opzioni di installazione sanificate senza esporre valori segreti grezzi.
- Gli operator possono chiamare
skills.searcheskills.detail(operator.read) per i metadati di individuazione di ClawHub. - Gli operator possono chiamare
skills.install(operator.admin) in due modalità:- Modalità ClawHub:
{ source: "clawhub", slug, version?, force? }installa una cartella skill nella directoryskills/del workspace dell’agente predefinito. - Modalità installer Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }esegue un’azionemetadata.openclaw.installdichiarata sull’host gateway.
- Modalità ClawHub:
- Gli operator possono chiamare
skills.update(operator.admin) in due modalità:- La modalità ClawHub aggiorna uno slug tracciato o tutte le installazioni ClawHub tracciate nel workspace dell’agente predefinito.
- La modalità config applica patch ai valori
skills.entries.<skillKey>comeenabled,apiKeyedenv.
Approvazioni exec
- Quando una richiesta exec necessita di approvazione, il gateway trasmette
exec.approval.requested. - I client operator risolvono chiamando
exec.approval.resolve(richiede lo scopeoperator.approvals). - Per
host=node,exec.approval.requestdeve includeresystemRunPlan(argv/cwd/rawCommand/metadati di sessione canonici). Le richieste senzasystemRunPlanvengono rifiutate. - Dopo l’approvazione, le chiamate inoltrate
node.invoke system.runriutilizzano quelsystemRunPlancanonico come contesto autorevole per comando/cwd/sessione. - Se un chiamante modifica
command,rawCommand,cwd,agentIdosessionKeytra prepare e l’inoltro finale approvato disystem.run, il gateway rifiuta l’esecuzione invece di fidarsi del payload modificato.
Fallback di consegna dell’agente
- Le richieste
agentpossono includeredeliver=trueper richiedere la consegna in uscita. bestEffortDeliver=falsemantiene il comportamento rigoroso: le destinazioni di consegna irrisolte o solo interne restituisconoINVALID_REQUEST.bestEffortDeliver=trueconsente il fallback all’esecuzione solo di sessione quando non è possibile risolvere alcun percorso esterno recapitabile (per esempio sessioni interne/webchat o configurazioni multicanale ambigue).
Controllo delle versioni
PROTOCOL_VERSIONsi trova insrc/gateway/protocol/schema/protocol-schemas.ts.- I client inviano
minProtocol+maxProtocol; il server rifiuta le incongruenze. - Schemi + modelli sono generati da definizioni TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Costanti del client
Il client di riferimento insrc/gateway/client.ts usa questi valori predefiniti. I valori sono
stabili in tutto il protocollo v3 e costituiscono la baseline attesa per i client di terze parti.
| Constant | Default | Source |
|---|---|---|
PROTOCOL_VERSION | 3 | src/gateway/protocol/schema/protocol-schemas.ts |
| Timeout della richiesta (per RPC) | 30_000 ms | src/gateway/client.ts (requestTimeoutMs) |
| Timeout preauth / connect-challenge | 10_000 ms | src/gateway/handshake-timeouts.ts (clamp 250–10_000) |
| Backoff iniziale di riconnessione | 1_000 ms | src/gateway/client.ts (backoffMs) |
| Backoff massimo di riconnessione | 30_000 ms | src/gateway/client.ts (scheduleReconnect) |
| Clamp di retry rapido dopo chiusura del token del dispositivo | 250 ms | src/gateway/client.ts |
Grace force-stop prima di terminate() | 250 ms | FORCE_STOP_TERMINATE_GRACE_MS |
Timeout predefinito di stopAndWait() | 1_000 ms | STOP_AND_WAIT_TIMEOUT_MS |
Intervallo tick predefinito (prima di hello-ok) | 30_000 ms | src/gateway/client.ts |
| Chiusura per timeout del tick | codice 4000 quando il silenzio supera tickIntervalMs * 2 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
policy.tickIntervalMs, policy.maxPayload
e policy.maxBufferedBytes in hello-ok; i client dovrebbero rispettare tali valori
piuttosto che i valori predefiniti pre-handshake.
Auth
- L’autenticazione del gateway con segreto condiviso usa
connect.params.auth.tokenoppureconnect.params.auth.password, a seconda della modalità auth configurata. - Le modalità che portano identità, come Tailscale Serve
(
gateway.auth.allowTailscale: true) ogateway.auth.mode: "trusted-proxy"non-loopback, soddisfano il controllo auth di connect a partire dalle intestazioni della richiesta invece che daconnect.params.auth.*. - L’ingresso privato con
gateway.auth.mode: "none"salta completamente l’auth connect con segreto condiviso; non esporre quella modalità su ingressi pubblici/non attendibili. - Dopo l’associazione, il Gateway emette un token del dispositivo con scope limitato al ruolo + agli scope
della connessione. Viene restituito in
hello-ok.auth.deviceTokene dovrebbe essere persistito dal client per connessioni future. - I client dovrebbero persistere il
hello-ok.auth.deviceTokenprimario dopo ogni connessione riuscita. - Anche la riconnessione con quel token del dispositivo memorizzato dovrebbe riutilizzare l’insieme di scope approvati memorizzato per quel token. Questo preserva l’accesso già concesso per lettura/verifica/stato ed evita che le riconnessioni si riducano silenziosamente a un scope implicito solo admin più ristretto.
- Assemblaggio auth connect lato client (
selectConnectAuthinsrc/gateway/client.ts):auth.passwordè ortogonale e viene sempre inoltrato quando impostato.auth.tokenviene popolato in ordine di priorità: prima un token condiviso esplicito, poi undeviceTokenesplicito, quindi un token per dispositivo memorizzato (indicato dadeviceId+role).auth.bootstrapTokenviene inviato solo quando nessuna delle opzioni sopra ha risolto unauth.token. Un token condiviso o qualsiasi token del dispositivo risolto lo sopprime.- L’auto-promozione di un token del dispositivo memorizzato nel retry one-shot
AUTH_TOKEN_MISMATCHè limitata ai soli endpoint attendibili — loopback oppurewss://contlsFingerprintfissata.wss://pubblico senza pinning non è idoneo.
- Le voci aggiuntive
hello-ok.auth.deviceTokenssono token di handoff bootstrap. Persistile solo quando la connessione ha usato auth bootstrap su un trasporto attendibile comewss://o pairing loopback/local. - Se un client fornisce un deviceToken esplicito o
scopesespliciti, quell’insieme di scope richiesto dal chiamante resta autorevole; gli scope in cache vengono riutilizzati solo quando il client sta riutilizzando il token per dispositivo memorizzato. - I token del dispositivo possono essere ruotati/revocati tramite
device.token.rotateedevice.token.revoke(richiede lo scopeoperator.pairing). - L’emissione/rotazione del token rimane limitata all’insieme di ruoli approvati registrato nella voce di associazione di quel dispositivo; ruotare un token non può estendere il dispositivo in un ruolo che l’approvazione del pairing non ha mai concesso.
- Per le sessioni con token del dispositivo associato, la gestione del dispositivo ha scope limitato al chiamante a meno che il
chiamante non abbia anche
operator.admin: i chiamanti non admin possono rimuovere/revocare/ruotare solo la propria voce di dispositivo. device.token.rotatecontrolla anche l’insieme di scope operator richiesto rispetto agli scope della sessione corrente del chiamante. I chiamanti non admin non possono ruotare un token verso un insieme di scope operator più ampio di quello che già possiedono.- Gli errori di autenticazione includono
error.details.codepiù suggerimenti per il recupero:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Comportamento del client per
AUTH_TOKEN_MISMATCH:- I client attendibili possono tentare un retry limitato con un token per dispositivo in cache.
- Se quel retry fallisce, i client dovrebbero interrompere i loop di riconnessione automatica e mostrare indicazioni per l’intervento dell’operatore.
Identità del dispositivo + pairing
- I node dovrebbero includere un’identità del dispositivo stabile (
device.id) derivata da un fingerprint della coppia di chiavi. - I gateway emettono token per dispositivo + ruolo.
- Le approvazioni di pairing sono richieste per nuovi ID dispositivo a meno che non sia abilitata l’auto-approvazione locale.
- L’auto-approvazione del pairing è centrata sulle connessioni loopback locali dirette.
- OpenClaw ha anche un percorso ristretto di self-connect backend/container-local per flussi helper attendibili con segreto condiviso.
- Le connessioni tailnet o LAN sullo stesso host sono comunque trattate come remote per il pairing e richiedono approvazione.
- Tutti i client WS devono includere l’identità
deviceduranteconnect(operator + node). Control UI può ometterla solo in queste modalità:gateway.controlUi.allowInsecureAuth=trueper compatibilità con HTTP non sicuro solo localhost.- autenticazione operator Control UI riuscita con
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(modalità break-glass, grave riduzione della sicurezza).
- Tutte le connessioni devono firmare il nonce
connect.challengefornito dal server.
Diagnostica di migrazione auth del dispositivo
Per i client legacy che usano ancora il comportamento di firma pre-challenge,connect ora restituisce
codici di dettaglio DEVICE_AUTH_* in error.details.code con un valore stabile di error.details.reason.
Errori di migrazione comuni:
| Message | details.code | details.reason | Meaning |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | Il client ha omesso device.nonce (o l’ha inviato vuoto). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | Il client ha firmato con un nonce obsoleto/errato. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | Il payload della firma non corrisponde al payload v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | Il timestamp firmato è fuori dallo skew consentito. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id non corrisponde al fingerprint della chiave pubblica. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | Il formato/canonicalizzazione della chiave pubblica non è riuscito. |
- Attendere sempre
connect.challenge. - Firmare il payload v2 che include il nonce del server.
- Inviare lo stesso nonce in
connect.params.device.nonce. - Il payload di firma preferito è
v3, che vincolaplatformedeviceFamilyoltre ai campi device/client/role/scopes/token/nonce. - Le firme legacy
v2restano accettate per compatibilità, ma il pinning dei metadati del dispositivo associato continua a controllare la policy dei comandi alla riconnessione.
TLS + pinning
- TLS è supportato per le connessioni WS.
- I client possono facoltativamente fissare il fingerprint del certificato del gateway (vedere la configurazione
gateway.tlspiùgateway.remote.tlsFingerprinto il flag CLI--tls-fingerprint).
Ambito
Questo protocollo espone l’API completa del gateway (status, canali, modelli, chat, agent, sessioni, node, approvazioni, ecc.). La superficie esatta è definita dagli schemi TypeBox insrc/gateway/protocol/schema.ts.