Protokół Gateway (WebSocket)
Protokół Gateway WS to pojedyncza płaszczyzna sterowania + transport node’ów dla OpenClaw. Wszyscy klienci (CLI, web UI, aplikacja macOS, nody iOS/Android, nody bezgłowe) łączą się przez WebSocket i deklarują swoją rolę + zakres w czasie uzgadniania połączenia.Transport
- WebSocket, ramki tekstowe z ładunkami JSON.
- Pierwsza ramka musi być żądaniem
connect.
Uzgadnianie połączenia (connect)
Gateway → klient (wyzwanie przed połączeniem):server, features, snapshot i policy są wymagane przez schemat
(src/gateway/protocol/schema/frames.ts). canvasHostUrl jest opcjonalne. auth
zgłasza uzgodnioną rolę/zakresy, gdy są dostępne, i zawiera deviceToken,
gdy gateway go wyda.
Gdy nie jest wydawany token urządzenia, hello-ok.auth może nadal zgłaszać
uzgodnione uprawnienia:
hello-ok zawiera także:
hello-ok.auth może także zawierać
dodatkowe wpisy ról ograniczonych zakresem w deviceTokens:
scopes: [], a każdy przekazany token operatora pozostaje ograniczony do listy
dozwolonych zakresów operatora bootstrapu (operator.approvals, operator.read,
operator.talk.secrets, operator.write). Kontrole zakresów bootstrapu
pozostają prefiksowane rolą: wpisy operatora spełniają tylko żądania operatora,
a role inne niż operator nadal wymagają zakresów pod własnym prefiksem roli.
Przykład node’a
Ramkowanie
- Żądanie:
{type:"req", id, method, params} - Odpowiedź:
{type:"res", id, ok, payload|error} - Zdarzenie:
{type:"event", event, payload, seq?, stateVersion?}
Role + zakresy
Role
operator= klient płaszczyzny sterowania (CLI/UI/automatyzacja).node= host możliwości (camera/screen/canvas/system.run).
Zakresy (operator)
Typowe zakresy:operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairingoperator.talk.secrets
talk.config z includeSecrets: true wymaga operator.talk.secrets
(lub operator.admin).
Metody Gateway RPC zarejestrowane przez Plugin mogą wymagać własnego zakresu operatora, ale
zastrzeżone prefiksy podstawowego administratora (config.*, exec.approvals.*, wizard.*,
update.*) są zawsze mapowane na operator.admin.
Zakres metody to tylko pierwszy próg. Niektóre komendy slash osiągane przez
chat.send stosują dodatkowo bardziej rygorystyczne kontrole na poziomie komendy. Na przykład trwałe
zapisy /config set i /config unset wymagają operator.admin.
node.pair.approve ma także dodatkową kontrolę zakresu w momencie zatwierdzania,
oprócz bazowego zakresu metody:
- żądania bez komendy:
operator.pairing - żądania z komendami node’a innymi niż exec:
operator.pairing+operator.write - żądania zawierające
system.run,system.run.preparelubsystem.which:operator.pairing+operator.admin
Caps/commands/permissions (node)
Nody deklarują zgłoszenia możliwości w czasieconnect:
caps: wysokopoziomowe kategorie możliwości.commands: lista dozwolonych komend dla invoke.permissions: szczegółowe przełączniki (np.screen.record,camera.capture).
Obecność
system-presencezwraca wpisy kluczowane tożsamością urządzenia.- Wpisy obecności zawierają
deviceId,rolesiscopes, dzięki czemu interfejsy UI mogą pokazywać jeden wiersz na urządzenie, nawet gdy łączy się ono zarówno jako operator, jak i node.
Typowe rodziny metod RPC
Ta strona nie jest wygenerowanym pełnym zrzutem, ale publiczna powierzchnia WS jest szersza niż przykłady uzgadniania połączenia/uwierzytelniania powyżej. To główne rodziny metod, które Gateway udostępnia obecnie.hello-ok.features.methods to zachowawcza lista wykrywania zbudowana z
src/gateway/server-methods-list.ts oraz załadowanych eksportów metod pluginów/kanałów.
Traktuj ją jako wykrywanie funkcji, a nie jako wygenerowany zrzut każdej wywoływalnej funkcji pomocniczej
zaimplementowanej w src/gateway/server-methods/*.ts.
System i tożsamość
healthzwraca zapisany w pamięci podręcznej lub świeżo sprawdzony snapshot kondycji gateway.statuszwraca podsumowanie gateway w stylu/status; pola wrażliwe są uwzględniane tylko dla klientów operatora z zakresem administratora.gateway.identity.getzwraca tożsamość urządzenia gateway używaną przez relay i przepływy parowania.system-presencezwraca bieżący snapshot obecności dla podłączonych urządzeń operatora/node’a.system-eventdopisuje zdarzenie systemowe i może aktualizować/rozgłaszać kontekst obecności.last-heartbeatzwraca najnowsze utrwalone zdarzenie Heartbeat.set-heartbeatsprzełącza przetwarzanie Heartbeat w gateway.
Modele i użycie
models.listzwraca katalog modeli dozwolonych w czasie działania.usage.statuszwraca okna użycia dostawców/podsumowania pozostałego limitu.usage.costzwraca zagregowane podsumowania kosztów użycia dla zakresu dat.doctor.memory.statuszwraca gotowość pamięci wektorowej / osadzania dla aktywnego domyślnego obszaru roboczego agenta.sessions.usagezwraca podsumowania użycia na sesję.sessions.usage.timeserieszwraca szereg czasowy użycia dla jednej sesji.sessions.usage.logszwraca wpisy dziennika użycia dla jednej sesji.
Kanały i pomocniki logowania
channels.statuszwraca podsumowania stanu wbudowanych i dołączonych kanałów/pluginów.channels.logoutwylogowuje określony kanał/konto tam, gdzie kanał obsługuje wylogowanie.web.login.starturuchamia przepływ logowania QR/web dla bieżącego dostawcy kanału web obsługującego QR.web.login.waitczeka na zakończenie tego przepływu logowania QR/web i po powodzeniu uruchamia kanał.push.testwysyła testowe powiadomienie APNs push do zarejestrowanego node’a iOS.voicewake.getzwraca zapisane wyzwalacze słowa wybudzającego.voicewake.setaktualizuje wyzwalacze słowa wybudzającego i rozgłasza zmianę.
Wiadomości i logi
sendto bezpośrednie RPC dostarczania wychodzącego dla wysyłek poza runnerem czatu kierowanych na kanał/konto/wątek.logs.tailzwraca skonfigurowany ogon logu plikowego gateway z kursorem/limitem i kontrolą maksymalnej liczby bajtów.
Talk i TTS
talk.configzwraca efektywny ładunek konfiguracji Talk;includeSecretswymagaoperator.talk.secrets(luboperator.admin).talk.modeustawia/rozgłasza bieżący stan trybu Talk dla klientów WebChat/Control UI.talk.speaksyntetyzuje mowę przez aktywnego dostawcę mowy Talk.tts.statuszwraca stan włączenia TTS, aktywnego dostawcę, dostawców zapasowych oraz stan konfiguracji dostawcy.tts.providerszwraca widoczny inwentarz dostawców TTS.tts.enableitts.disableprzełączają stan preferencji TTS.tts.setProvideraktualizuje preferowanego dostawcę TTS.tts.convertwykonuje jednorazową konwersję tekstu na mowę.
Sekrety, konfiguracja, aktualizacja i kreator
secrets.reloadponownie rozwiązuje aktywne SecretRef i przełącza stan sekretów w czasie działania tylko przy pełnym powodzeniu.secrets.resolverozwiązuje przypisania sekretów dla określonego zestawu komend/celów.config.getzwraca bieżący snapshot konfiguracji i hash.config.setzapisuje zweryfikowany ładunek konfiguracji.config.patchscala częściową aktualizację konfiguracji.config.applyweryfikuje + zastępuje pełny ładunek konfiguracji.config.schemazwraca aktywny ładunek schematu konfiguracji używany przez Control UI i narzędzia CLI: schemat,uiHints, wersję i metadane generowania, w tym metadane schematów pluginów + kanałów, gdy środowisko uruchomieniowe może je załadować. Schemat zawiera metadane póltitle/descriptionpochodzące z tych samych etykiet i tekstów pomocy używanych przez UI, w tym dla obiektów zagnieżdżonych, wildcardów, elementów tablic, oraz gałęzi kompozycjianyOf/oneOf/allOf, gdy istnieje pasująca dokumentacja pola.config.schema.lookupzwraca ładunek wyszukiwania ograniczony do ścieżki dla jednej ścieżki konfiguracji: znormalizowaną ścieżkę, płytki węzeł schematu, dopasowaną wskazówkę +hintPath, oraz podsumowania bezpośrednich elementów podrzędnych do drążenia w UI/CLI.- Węzły schematu wyszukiwania zachowują dokumentację widoczną dla użytkownika i typowe pola walidacji:
title,description,type,enum,const,format,pattern, ograniczenia numeryczne/łańcuchów/tablic/obiektów oraz flagi logiczne takie jakadditionalProperties,deprecated,readOnly,writeOnly. - Podsumowania elementów podrzędnych ujawniają
key, znormalizowanąpath,type,required,hasChildren, a także dopasowanehint/hintPath.
- Węzły schematu wyszukiwania zachowują dokumentację widoczną dla użytkownika i typowe pola walidacji:
update.runuruchamia przepływ aktualizacji gateway i planuje restart tylko wtedy, gdy sama aktualizacja się powiodła.wizard.start,wizard.next,wizard.statusiwizard.canceludostępniają kreator onboardingu przez WS RPC.
Istniejące główne rodziny
Pomocniki agentów i obszaru roboczego
agents.listzwraca skonfigurowane wpisy agentów.agents.create,agents.updateiagents.deletezarządzają rekordami agentów i powiązaniem obszaru roboczego.agents.files.list,agents.files.getiagents.files.setzarządzają plikami bootstrapowego obszaru roboczego udostępnionymi dla agenta.agent.identity.getzwraca efektywną tożsamość asystenta dla agenta lub sesji.agent.waitczeka na zakończenie uruchomienia i zwraca końcowy snapshot, gdy jest dostępny.
Sterowanie sesją
sessions.listzwraca bieżący indeks sesji.sessions.subscribeisessions.unsubscribeprzełączają subskrypcje zdarzeń zmian sesji dla bieżącego klienta WS.sessions.messages.subscribeisessions.messages.unsubscribeprzełączają subskrypcje zdarzeń transkryptu/wiadomości dla jednej sesji.sessions.previewzwraca ograniczone podglądy transkryptu dla określonych kluczy sesji.sessions.resolverozwiązuje lub kanonizuje cel sesji.sessions.createtworzy nowy wpis sesji.sessions.sendwysyła wiadomość do istniejącej sesji.sessions.steerto wariant przerwania i ukierunkowania dla aktywnej sesji.sessions.abortprzerywa aktywną pracę dla sesji.sessions.patchaktualizuje metadane/nadpisania sesji.sessions.reset,sessions.deleteisessions.compactwykonują utrzymanie sesji.sessions.getzwraca pełny zapisany wiersz sesji.- wykonanie czatu nadal używa
chat.history,chat.send,chat.abortichat.inject. chat.historyjest znormalizowane pod kątem wyświetlania dla klientów UI: znaczniki dyrektyw inline są usuwane z widocznego tekstu, ładunki XML wywołań narzędzi w postaci zwykłego tekstu (w tym<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>oraz ucięte bloki wywołań narzędzi) i wyciekłe tokeny sterujące modelu ASCII/full-width są usuwane, czyste wiersze asystenta z cichym tokenem takie jak dokładneNO_REPLY/no_replysą pomijane, a zbyt duże wiersze mogą zostać zastąpione placeholderami.
Parowanie urządzeń i tokeny urządzeń
device.pair.listzwraca oczekujące i zatwierdzone sparowane urządzenia.device.pair.approve,device.pair.rejectidevice.pair.removezarządzają rekordami parowania urządzeń.device.token.rotaterotuje token sparowanego urządzenia w granicach jego zatwierdzonej roli i zakresów.device.token.revokeunieważnia token sparowanego urządzenia.
Parowanie node’ów, invoke i oczekująca praca
node.pair.request,node.pair.list,node.pair.approve,node.pair.rejectinode.pair.verifyobejmują parowanie node’ów i weryfikację bootstrapu.node.listinode.describezwracają stan znanych/podłączonych node’ów.node.renameaktualizuje etykietę sparowanego node’a.node.invokeprzekazuje komendę do podłączonego node’a.node.invoke.resultzwraca wynik dla żądania invoke.node.eventprzenosi zdarzenia pochodzące z node’a z powrotem do gateway.node.canvas.capability.refreshodświeża tokeny możliwości canvas ograniczone zakresem.node.pending.pullinode.pending.ackto API kolejki podłączonych node’ów.node.pending.enqueueinode.pending.drainzarządzają trwałą oczekującą pracą dla node’ów offline/odłączonych.
Rodziny zatwierdzeń
exec.approval.request,exec.approval.get,exec.approval.listiexec.approval.resolveobejmują jednorazowe żądania zatwierdzenia exec oraz wyszukiwanie/odtwarzanie oczekujących zatwierdzeń.exec.approval.waitDecisionczeka na jedną oczekującą decyzję zatwierdzenia exec i zwraca końcową decyzję (lubnullpo przekroczeniu limitu czasu).exec.approvals.getiexec.approvals.setzarządzają snapshotami zasad zatwierdzania exec w gateway.exec.approvals.node.getiexec.approvals.node.setzarządzają lokalnymi dla node’a zasadami zatwierdzania exec za pomocą komend relay node’a.plugin.approval.request,plugin.approval.list,plugin.approval.waitDecisioniplugin.approval.resolveobejmują przepływy zatwierdzania zdefiniowane przez Plugin.
Inne główne rodziny
- automatyzacja:
wakeplanuje natychmiastowe lub przy następnym Heartbeat wstrzyknięcie tekstu wybudzeniacron.list,cron.status,cron.add,cron.update,cron.remove,cron.run,cron.runs
- Skills/narzędzia:
commands.list,skills.*,tools.catalog,tools.effective
Typowe rodziny zdarzeń
chat: aktualizacje czatu UI takie jakchat.injecti inne zdarzenia czatu tylko dla transkryptu.session.messageisession.tool: aktualizacje strumienia transkryptu/zdarzeń dla subskrybowanej sesji.sessions.changed: indeks sesji lub metadane uległy zmianie.presence: aktualizacje snapshotu obecności systemu.tick: okresowe zdarzenie keepalive / żywotności.health: aktualizacja snapshotu kondycji gateway.heartbeat: aktualizacja strumienia zdarzeń Heartbeat.cron: zdarzenie zmiany uruchomienia/zadania Cron.shutdown: powiadomienie o wyłączeniu gateway.node.pair.requested/node.pair.resolved: cykl życia parowania node’a.node.invoke.request: rozgłoszenie żądania invoke node’a.device.pair.requested/device.pair.resolved: cykl życia sparowanego urządzenia.voicewake.changed: konfiguracja wyzwalacza słowa wybudzającego uległa zmianie.exec.approval.requested/exec.approval.resolved: cykl życia zatwierdzania exec.plugin.approval.requested/plugin.approval.resolved: cykl życia zatwierdzania Plugin.
Metody pomocnicze node’a
- Nody mogą wywołać
skills.bins, aby pobrać bieżącą listę plików wykonywalnych Skills do automatycznych kontroli allowlisty.
Metody pomocnicze operatora
- Operatorzy mogą wywołać
commands.list(operator.read), aby pobrać inwentarz komend środowiska uruchomieniowego dla agenta.agentIdjest opcjonalne; pomiń je, aby odczytać domyślny obszar roboczy agenta.scopekontroluje, którą powierzchnię wskazuje podstawowename:textzwraca podstawowy tekstowy token komendy bez początkowego/nativeoraz domyślna ścieżkabothzwracają nazwy natywne zależne od dostawcy, gdy są dostępne
textAliaseszawiera dokładne aliasy slash, takie jak/modeli/m.nativeNamezawiera zależną od dostawcy natywną nazwę komendy, gdy taka istnieje.providerjest opcjonalne i wpływa tylko na nazewnictwo natywne oraz dostępność natywnych komend Plugin.includeArgs=falsepomija zserializowane metadane argumentów w odpowiedzi.
- Operatorzy mogą wywołać
tools.catalog(operator.read), aby pobrać katalog narzędzi środowiska uruchomieniowego dla agenta. Odpowiedź zawiera pogrupowane narzędzia i metadane pochodzenia:source:corelubpluginpluginId: właściciel Plugin, gdysource="plugin"optional: czy narzędzie Plugin jest opcjonalne
- Operatorzy mogą wywołać
tools.effective(operator.read), aby pobrać efektywny w czasie działania inwentarz narzędzi dla sesji.sessionKeyjest wymagane.- Gateway wyprowadza zaufany kontekst środowiska uruchomieniowego po stronie serwera z sesji zamiast akceptować dostarczony przez wywołującego kontekst uwierzytelniania lub dostarczania.
- Odpowiedź jest ograniczona do sesji i odzwierciedla to, czego aktywna konwersacja może użyć w tej chwili, w tym narzędzia core, Plugin i kanałów.
- Operatorzy mogą wywołać
skills.status(operator.read), aby pobrać widoczny inwentarz Skills dla agenta.agentIdjest opcjonalne; pomiń je, aby odczytać domyślny obszar roboczy agenta.- Odpowiedź zawiera kwalifikowalność, brakujące wymagania, kontrole konfiguracji i oczyszczone opcje instalacji bez ujawniania surowych wartości sekretów.
- Operatorzy mogą wywołać
skills.searchiskills.detail(operator.read) dla metadanych wykrywania ClawHub. - Operatorzy mogą wywołać
skills.install(operator.admin) w dwóch trybach:- Tryb ClawHub:
{ source: "clawhub", slug, version?, force? }instaluje folder skill do kataloguskills/domyślnego obszaru roboczego agenta. - Tryb instalatora Gateway:
{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }uruchamia zadeklarowaną akcjęmetadata.openclaw.installna hoście gateway.
- Tryb ClawHub:
- Operatorzy mogą wywołać
skills.update(operator.admin) w dwóch trybach:- Tryb ClawHub aktualizuje jeden śledzony slug lub wszystkie śledzone instalacje ClawHub w domyślnym obszarze roboczym agenta.
- Tryb konfiguracji łata wartości
skills.entries.<skillKey>takie jakenabled,apiKeyienv.
Zatwierdzenia exec
- Gdy żądanie exec wymaga zatwierdzenia, gateway rozgłasza
exec.approval.requested. - Klienci operatora rozwiązują to, wywołując
exec.approval.resolve(wymaga zakresuoperator.approvals). - Dla
host=nodeexec.approval.requestmusi zawieraćsystemRunPlan(kanoniczneargv/cwd/rawCommand/metadane sesji). Żądania bezsystemRunPlansą odrzucane. - Po zatwierdzeniu przekazane wywołania
node.invoke system.runponownie używają tego kanonicznegosystemRunPlanjako autorytatywnego kontekstu komendy/cwd/sesji. - Jeśli wywołujący zmieni
command,rawCommand,cwd,agentIdlubsessionKeymiędzy przygotowaniem a końcowym zatwierdzonym przekazaniemsystem.run, gateway odrzuci uruchomienie zamiast ufać zmodyfikowanemu ładunkowi.
Fallback dostarczania agenta
- Żądania
agentmogą zawieraćdeliver=true, aby zażądać dostarczenia wychodzącego. bestEffortDeliver=falsezachowuje ścisłe działanie: nierozwiązane lub tylko wewnętrzne cele dostarczenia zwracająINVALID_REQUEST.bestEffortDeliver=truepozwala na fallback do wykonania tylko w sesji, gdy nie można rozwiązać żadnej zewnętrznej trasy dostarczania (na przykład sesje wewnętrzne/webchat lub niejednoznaczne konfiguracje wielokanałowe).
Wersjonowanie
PROTOCOL_VERSIONznajduje się wsrc/gateway/protocol/schema/protocol-schemas.ts.- Klienci wysyłają
minProtocol+maxProtocol; serwer odrzuca niezgodności. - Schematy + modele są generowane z definicji TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
Stałe klienta
Klient referencyjny wsrc/gateway/client.ts używa tych wartości domyślnych. Wartości
są stabilne w całym protokole v3 i stanowią oczekiwaną bazę dla klientów zewnętrznych.
| Stała | Wartość domyślna | Źródło |
|---|---|---|
PROTOCOL_VERSION | 3 | src/gateway/protocol/schema/protocol-schemas.ts |
| Limit czasu żądania (na RPC) | 30_000 ms | src/gateway/client.ts (requestTimeoutMs) |
| Limit czasu preauth / connect-challenge | 10_000 ms | src/gateway/handshake-timeouts.ts (ograniczenie 250–10_000) |
| Początkowy backoff ponownego połączenia | 1_000 ms | src/gateway/client.ts (backoffMs) |
| Maksymalny backoff ponownego połączenia | 30_000 ms | src/gateway/client.ts (scheduleReconnect) |
| Ograniczenie szybkiej ponownej próby po zamknięciu tokenu urządzenia | 250 ms | src/gateway/client.ts |
Grace przed terminate() przy wymuszonym zatrzymaniu | 250 ms | FORCE_STOP_TERMINATE_GRACE_MS |
Domyślny limit czasu stopAndWait() | 1_000 ms | STOP_AND_WAIT_TIMEOUT_MS |
Domyślny interwał tick (przed hello-ok) | 30_000 ms | src/gateway/client.ts |
| Zamknięcie z powodu limitu czasu tick | kod 4000, gdy cisza przekracza tickIntervalMs * 2 | src/gateway/client.ts |
MAX_PAYLOAD_BYTES | 25 * 1024 * 1024 (25 MB) | src/gateway/server-constants.ts |
policy.tickIntervalMs, policy.maxPayload
i policy.maxBufferedBytes w hello-ok; klienci powinni respektować te wartości,
zamiast wartości domyślnych sprzed uzgadniania połączenia.
Uwierzytelnianie
- Uwierzytelnianie gateway przy użyciu wspólnego sekretu korzysta z
connect.params.auth.tokenlubconnect.params.auth.password, zależnie od skonfigurowanego trybu uwierzytelniania. - Tryby niosące tożsamość, takie jak Tailscale Serve
(
gateway.auth.allowTailscale: true) lub inne niż loopbackgateway.auth.mode: "trusted-proxy", spełniają kontrolę uwierzytelniania connect na podstawie nagłówków żądania zamiastconnect.params.auth.*. - Prywatny ingress
gateway.auth.mode: "none"całkowicie pomija uwierzytelnianie connect wspólnym sekretem; nie wystawiaj tego trybu na publicznym/niezaufanym ingressie. - Po sparowaniu Gateway wydaje token urządzenia ograniczony do roli + zakresów
połączenia. Jest on zwracany w
hello-ok.auth.deviceTokeni powinien być utrwalany przez klienta do przyszłych połączeń. - Klienci powinni utrwalać podstawowy
hello-ok.auth.deviceTokenpo każdym pomyślnym połączeniu. - Ponowne łączenie przy użyciu tego zapisanego tokenu urządzenia powinno także ponownie używać zapisanego zatwierdzonego zestawu zakresów dla tego tokenu. Zachowuje to już przyznany dostęp do odczytu/sprawdzania/statusu i zapobiega cichemu zawężeniu ponownych połączeń do węższego domyślnego zakresu tylko administratora.
- Składanie uwierzytelniania connect po stronie klienta (
selectConnectAuthwsrc/gateway/client.ts):auth.passwordjest niezależne i zawsze jest przekazywane, gdy jest ustawione.auth.tokenjest wypełniane w kolejności priorytetu: najpierw jawny współdzielony token, potem jawnydeviceToken, a następnie zapisany token na urządzenie (kluczowany przezdeviceId+role).auth.bootstrapTokenjest wysyłane tylko wtedy, gdy żadne z powyższych nie ustawiłoauth.token. Współdzielony token lub dowolny rozwiązany token urządzenia je tłumi.- Automatyczne promowanie zapisanego tokenu urządzenia przy jednorazowej
ponownej próbie
AUTH_TOKEN_MISMATCHjest ograniczone wyłącznie do zaufanych endpointów — loopback albowss://z przypiętymtlsFingerprint. Publicznewss://bez pinningu się nie kwalifikuje.
- Dodatkowe wpisy
hello-ok.auth.deviceTokensto tokeny przekazania bootstrapu. Utrwalaj je tylko wtedy, gdy połączenie używało uwierzytelniania bootstrap przez zaufany transport taki jakwss://lub loopback/parowanie lokalne. - Jeśli klient podaje jawny
deviceTokenlub jawnescopes, autorytatywny pozostaje zestaw zakresów zażądany przez wywołującego; zapisane zakresy są ponownie używane tylko wtedy, gdy klient ponownie używa zapisanego tokenu na urządzenie. - Tokeny urządzeń można rotować/unieważniać za pomocą
device.token.rotateidevice.token.revoke(wymaga zakresuoperator.pairing). - Wydawanie/rotacja tokenów pozostaje ograniczone do zatwierdzonego zestawu ról zapisanego we wpisie parowania tego urządzenia; rotacja tokenu nie może rozszerzyć urządzenia do roli, której zatwierdzenie parowania nigdy nie przyznało.
- Dla sesji tokenów sparowanych urządzeń zarządzanie urządzeniami jest ograniczone do własnego zakresu, chyba że
wywołujący ma także
operator.admin: wywołujący bez uprawnień administratora mogą usuwać/unieważniać/rotować tylko własny wpis urządzenia. device.token.rotatesprawdza także żądany zestaw zakresów operatora względem bieżących zakresów sesji wywołującego. Wywołujący bez uprawnień administratora nie mogą obrócić tokenu do szerszego zestawu zakresów operatora niż już posiadają.- Błędy uwierzytelniania zawierają
error.details.codeoraz wskazówki odzyskiwania:error.details.canRetryWithDeviceToken(boolean)error.details.recommendedNextStep(retry_with_device_token,update_auth_configuration,update_auth_credentials,wait_then_retry,review_auth_configuration)
- Zachowanie klienta dla
AUTH_TOKEN_MISMATCH:- Zaufani klienci mogą podjąć jedną ograniczoną ponowną próbę z zapisanym tokenem na urządzenie.
- Jeśli ta ponowna próba się nie powiedzie, klienci powinni zatrzymać automatyczne pętle ponownego łączenia i pokazać operatorowi wskazówki dotyczące dalszego działania.
Tożsamość urządzenia + parowanie
- Nody powinny zawierać stabilną tożsamość urządzenia (
device.id) wyprowadzoną z odcisku palca pary kluczy. - Gateway wydaje tokeny dla urządzenia + roli.
- Zatwierdzenia parowania są wymagane dla nowych identyfikatorów urządzeń, chyba że włączone jest lokalne automatyczne zatwierdzanie.
- Automatyczne zatwierdzanie parowania jest skoncentrowane na bezpośrednich lokalnych połączeniach loopback.
- OpenClaw ma także wąską ścieżkę samopołączenia backend/container-local dla zaufanych przepływów pomocniczych opartych na współdzielonym sekrecie.
- Połączenia tailnet lub LAN z tego samego hosta są nadal traktowane jako zdalne na potrzeby parowania i wymagają zatwierdzenia.
- Wszyscy klienci WS muszą dołączać tożsamość
devicepodczasconnect(operator + node). Control UI może ją pominąć tylko w tych trybach:gateway.controlUi.allowInsecureAuth=truedla zgodności z niebezpiecznym HTTP tylko dla localhost.- pomyślne uwierzytelnienie operatora Control UI przy
gateway.auth.mode: "trusted-proxy". gateway.controlUi.dangerouslyDisableDeviceAuth=true(tryb awaryjny, poważne obniżenie bezpieczeństwa).
- Wszystkie połączenia muszą podpisywać nonce
connect.challengedostarczone przez serwer.
Diagnostyka migracji uwierzytelniania urządzenia
Dla starszych klientów, które nadal używają zachowania podpisywania sprzed challenge,connect zwraca teraz
kody szczegółowe DEVICE_AUTH_* w error.details.code wraz ze stabilnym error.details.reason.
Typowe błędy migracji:
| Wiadomość | details.code | details.reason | Znaczenie |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | Klient pominął device.nonce (lub wysłał pustą wartość). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | Klient podpisał starym/błędnym nonce. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | Ładunek podpisu nie odpowiada ładunkowi v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | Podpisany znacznik czasu wykracza poza dozwolone odchylenie. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id nie odpowiada odciskowi palca klucza publicznego. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | Format/kanonizacja klucza publicznego nie powiodły się. |
- Zawsze czekaj na
connect.challenge. - Podpisuj ładunek v2 zawierający nonce serwera.
- Wyślij ten sam nonce w
connect.params.device.nonce. - Preferowany ładunek podpisu to
v3, który wiążeplatformideviceFamilyoprócz pól device/client/role/scopes/token/nonce. - Starsze podpisy
v2pozostają akceptowane dla zgodności, ale przypinanie metadanych sparowanego urządzenia nadal kontroluje politykę komend przy ponownym połączeniu.
TLS + pinning
- TLS jest obsługiwany dla połączeń WS.
- Klienci mogą opcjonalnie przypiąć odcisk palca certyfikatu gateway (zobacz konfigurację
gateway.tlsorazgateway.remote.tlsFingerprintlub flagę CLI--tls-fingerprint).
Zakres
Ten protokół udostępnia pełne API gateway (status, kanały, modele, chat, agent, sesje, nody, zatwierdzenia itd.). Dokładna powierzchnia jest zdefiniowana przez schematy TypeBox wsrc/gateway/protocol/schema.ts.