Gateway
Uwierzytelnianie przez zaufane proxy
Kiedy używać
Użyj trybu uwierzytelniania trusted-proxy, gdy:
- Uruchamiasz OpenClaw za proxy świadomym tożsamości (Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + forward auth).
- Twoje proxy obsługuje całe uwierzytelnianie i przekazuje tożsamość użytkownika przez nagłówki.
- Działasz w środowisku Kubernetes lub kontenerowym, gdzie proxy jest jedyną ścieżką do Gateway.
- Trafiasz na błędy WebSocket
1008 unauthorized, ponieważ przeglądarki nie mogą przekazywać tokenów w ładunkach WS.
Kiedy NIE używać
- Jeśli Twoje proxy nie uwierzytelnia użytkowników (jest tylko terminatorem TLS lub równoważnikiem obciążenia).
- Jeśli istnieje jakakolwiek ścieżka do Gateway omijająca proxy (luki w zaporze, dostęp z sieci wewnętrznej).
- Jeśli nie masz pewności, czy Twoje proxy poprawnie usuwa/nadpisuje przekazywane nagłówki.
- Jeśli potrzebujesz tylko osobistego dostępu dla jednego użytkownika (rozważ Tailscale Serve + loopback dla prostszej konfiguracji).
Jak to działa
Proxy authenticates the user
Twoje reverse proxy uwierzytelnia użytkowników (OAuth, OIDC, SAML itd.).
Proxy adds an identity header
Proxy dodaje nagłówek z tożsamością uwierzytelnionego użytkownika (np. x-forwarded-user: [email protected]).
Gateway verifies trusted source
OpenClaw sprawdza, czy żądanie pochodzi z zaufanego adresu IP proxy (skonfigurowanego w gateway.trustedProxies).
Gateway extracts identity
OpenClaw wyodrębnia tożsamość użytkownika ze skonfigurowanego nagłówka.
Authorize
Jeśli wszystko się zgadza, żądanie zostaje autoryzowane.
Zachowanie parowania Control UI
Gdy gateway.auth.mode = "trusted-proxy" jest aktywne, a żądanie przejdzie kontrole trusted-proxy, sesje WebSocket Control UI mogą łączyć się bez tożsamości parowania urządzenia.
Konsekwencje:
- Parowanie nie jest już główną bramką dostępu do Control UI w tym trybie.
- Polityka uwierzytelniania Twojego reverse proxy i
allowUsersstają się skuteczną kontrolą dostępu. - Ogranicz wejście do gateway wyłącznie do zaufanych adresów IP proxy (
gateway.trustedProxies+ zapora).
Konfiguracja
{
gateway: {
// Trusted-proxy auth expects requests from a non-loopback trusted proxy source by default
bind: "lan",
// CRITICAL: Only add your proxy's IP(s) here
trustedProxies: ["10.0.0.1", "172.17.0.1"],
auth: {
mode: "trusted-proxy",
trustedProxy: {
// Header containing authenticated user identity (required)
userHeader: "x-forwarded-user",
// Optional: headers that MUST be present (proxy verification)
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
// Optional: restrict to specific users (empty = allow all)
allowUsers: ["[email protected]", "[email protected]"],
// Optional: allow a same-host loopback proxy after explicit opt-in
allowLoopback: false,
},
},
},
}
Opis konfiguracji
gateway.trustedProxiesstring[]requiredTablica adresów IP proxy, którym należy ufać. Żądania z innych adresów IP są odrzucane.
gateway.auth.modestringrequiredMusi być "trusted-proxy".
gateway.auth.trustedProxy.userHeaderstringrequiredNazwa nagłówka zawierającego tożsamość uwierzytelnionego użytkownika.
gateway.auth.trustedProxy.requiredHeadersstring[]Dodatkowe nagłówki, które muszą być obecne, aby żądanie zostało uznane za zaufane.
gateway.auth.trustedProxy.allowUsersstring[]Lista dozwolonych tożsamości użytkowników. Pusta oznacza zezwolenie wszystkim uwierzytelnionym użytkownikom.
gateway.auth.trustedProxy.allowLoopbackbooleanJawnie włączane wsparcie dla reverse proxy loopback na tym samym hoście. Domyślnie false.
Terminacja TLS i HSTS
Użyj jednego punktu terminacji TLS i zastosuj tam HSTS.
Proxy TLS termination (recommended)
Gdy Twoje reverse proxy obsługuje HTTPS dla https://control.example.com, ustaw Strict-Transport-Security w proxy dla tej domeny.
- Dobrze pasuje do wdrożeń wystawionych do internetu.
- Utrzymuje certyfikat i politykę utwardzania HTTP w jednym miejscu.
- OpenClaw może pozostać na HTTP loopback za proxy.
Przykładowa wartość nagłówka:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Gateway TLS termination
Jeśli sam OpenClaw bezpośrednio obsługuje HTTPS (bez proxy terminującego TLS), ustaw:
{
gateway: {
tls: { enabled: true },
http: {
securityHeaders: {
strictTransportSecurity: "max-age=31536000; includeSubDomains",
},
},
},
}
strictTransportSecurity przyjmuje wartość nagłówka jako ciąg znaków albo false, aby jawnie wyłączyć.
Wskazówki wdrożeniowe
- Zacznij najpierw od krótkiego maksymalnego wieku (na przykład
max-age=300) podczas walidowania ruchu. - Zwiększ do wartości długotrwałych (na przykład
max-age=31536000) dopiero po uzyskaniu wysokiej pewności. - Dodaj
includeSubDomainstylko wtedy, gdy każda subdomena jest gotowa na HTTPS. - Używaj preload tylko wtedy, gdy celowo spełniasz wymagania preload dla pełnego zestawu domen.
- Lokalne programowanie wyłącznie na loopback nie korzysta z HSTS.
Przykłady konfiguracji proxy
Pomerium
Pomerium przekazuje tożsamość w x-pomerium-claim-email (lub innych nagłówkach roszczeń) oraz JWT w x-pomerium-jwt-assertion.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // Pomerium's IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-pomerium-claim-email",
requiredHeaders: ["x-pomerium-jwt-assertion"],
},
},
},
}
Fragment konfiguracji Pomerium:
routes:
- from: https://openclaw.example.com
to: http://openclaw-gateway:18789
policy:
- allow:
or:
- email:
is: [email protected]
pass_identity_headers: true
Caddy with OAuth
Caddy z Plugin caddy-security może uwierzytelniać użytkowników i przekazywać nagłówki tożsamości.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // Caddy/sidecar proxy IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Fragment Caddyfile:
openclaw.example.com {
authenticate with oauth2_provider
authorize with policy1
reverse_proxy openclaw:18789 {
header_up X-Forwarded-User {http.auth.user.email}
}
}
nginx + oauth2-proxy
oauth2-proxy uwierzytelnia użytkowników i przekazuje tożsamość w x-auth-request-email.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // nginx/oauth2-proxy IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-auth-request-email",
},
},
},
}
Fragment konfiguracji nginx:
location / {
auth_request /oauth2/auth;
auth_request_set $user $upstream_http_x_auth_request_email;
proxy_pass http://openclaw:18789;
proxy_set_header X-Auth-Request-Email $user;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Traefik with forward auth
{
gateway: {
bind: "lan",
trustedProxies: ["172.17.0.1"], // Traefik container IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Mieszana konfiguracja tokenów
OpenClaw odrzuca niejednoznaczne konfiguracje, w których jednocześnie aktywne są gateway.auth.token (lub OPENCLAW_GATEWAY_TOKEN) i tryb trusted-proxy. Mieszane konfiguracje tokenów mogą sprawić, że żądania loopback zostaną po cichu uwierzytelnione na niewłaściwej ścieżce uwierzytelniania.
Jeśli podczas uruchamiania zobaczysz błąd mixed_trusted_proxy_token:
- Usuń współdzielony token podczas używania trybu trusted-proxy albo
- Przełącz
gateway.auth.modena"token", jeśli zamierzasz używać uwierzytelniania opartego na tokenie.
Nagłówki tożsamości trusted-proxy z loopback nadal kończą się zamkniętą odmową: wywołujący z tego samego hosta nie są po cichu uwierzytelniani jako użytkownicy proxy. Wewnętrzni wywołujący OpenClaw, którzy omijają proxy, mogą zamiast tego uwierzytelniać się przez gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD. Awaryjny powrót do tokenu pozostaje celowo nieobsługiwany w trybie trusted-proxy.
Nagłówek zakresów operatora
Uwierzytelnianie trusted-proxy jest trybem HTTP niosącym tożsamość, więc wywołujący mogą opcjonalnie deklarować zakresy operatora za pomocą x-openclaw-scopes.
Przykłady:
x-openclaw-scopes: operator.readx-openclaw-scopes: operator.read,operator.writex-openclaw-scopes: operator.admin,operator.write
Zachowanie:
- Gdy nagłówek jest obecny, OpenClaw respektuje zadeklarowany zestaw zakresów.
- Gdy nagłówek jest obecny, ale pusty, żądanie deklaruje brak zakresów operatora.
- Gdy nagłówka nie ma, zwykłe interfejsy API HTTP niosące tożsamość wracają do standardowego domyślnego zestawu zakresów operatora.
- Trasy HTTP Plugin uwierzytelniane przez Gateway są domyślnie węższe: gdy
x-openclaw-scopesjest nieobecny, ich zakres czasu wykonania wraca dooperator.write. - Żądania HTTP pochodzące z przeglądarki nadal muszą przejść
gateway.controlUi.allowedOrigins(lub celowy tryb awaryjny oparty na nagłówku Host), nawet po powodzeniu uwierzytelniania trusted-proxy.
Praktyczna zasada: wysyłaj x-openclaw-scopes jawnie, gdy chcesz, aby żądanie trusted-proxy było węższe niż wartości domyślne, albo gdy trasa Plugin uwierzytelniana przez gateway wymaga czegoś silniejszego niż zakres zapisu.
Lista kontrolna bezpieczeństwa
Przed włączeniem uwierzytelniania trusted-proxy sprawdź:
- [ ] Proxy is the only path: Port Gateway jest odizolowany zaporą od wszystkiego poza Twoim proxy.
- [ ] trustedProxies is minimal: Tylko rzeczywiste adresy IP Twojego proxy, a nie całe podsieci.
- [ ] Loopback proxy source is deliberate: Uwierzytelnianie trusted-proxy kończy się bezpieczną odmową dla żądań ze źródła loopback, chyba że
gateway.auth.trustedProxy.allowLoopbackjest jawnie włączone dla proxy na tym samym hoście. - [ ] Proxy strips headers: Twoje proxy nadpisuje (nie dopisuje) nagłówki
x-forwarded-*od klientów. - [ ] TLS termination: Twoje proxy obsługuje TLS; użytkownicy łączą się przez HTTPS.
- [ ] allowedOrigins is explicit: Control UI poza loopback używa jawnego
gateway.controlUi.allowedOrigins. - [ ] allowUsers is set (zalecane): Ogranicz dostęp do znanych użytkowników zamiast zezwalać każdemu uwierzytelnionemu.
- [ ] No mixed token config: Nie ustawiaj jednocześnie
gateway.auth.tokenigateway.auth.mode: "trusted-proxy". - [ ] Local password fallback is private: Jeśli konfigurujesz
gateway.auth.passworddla wewnętrznych wywołań bezpośrednich, utrzymuj port Gateway za zaporą, aby zdalni klienci spoza proxy nie mogli dotrzeć do niego bezpośrednio.
Audyt bezpieczeństwa
openclaw security audit oznaczy uwierzytelnianie trusted-proxy wynikiem o ważności krytycznej. To zamierzone — jest to przypomnienie, że delegujesz bezpieczeństwo do konfiguracji proxy.
Audyt sprawdza:
- Podstawowe ostrzeżenie/krytyczne przypomnienie
gateway.trusted_proxy_auth - Brak konfiguracji
trustedProxies - Brak konfiguracji
userHeader - Puste
allowUsers(zezwala każdemu uwierzytelnionemu użytkownikowi) - Włączone
allowLoopbackdla źródeł proxy na tym samym hoście - Wieloznaczną lub brakującą politykę pochodzenia przeglądarki na wystawionych powierzchniach Control UI
Rozwiązywanie problemów
trusted_proxy_untrusted_source
Żądanie nie przyszło z adresu IP w gateway.trustedProxies. Sprawdź:
- Czy adres IP proxy jest poprawny? (Adresy IP kontenerów Docker mogą się zmieniać.)
- Czy przed proxy znajduje się load balancer?
- Użyj
docker inspectalbokubectl get pods -o wide, aby znaleźć rzeczywiste adresy IP.
trusted_proxy_loopback_source
OpenClaw odrzucił żądanie trusted-proxy ze źródła loopback.
Sprawdź:
- Czy proxy łączy się z
127.0.0.1/::1? - Czy próbujesz użyć uwierzytelniania trusted-proxy z odwrotnym proxy loopback na tym samym hoście?
Naprawa:
- Preferuj uwierzytelnianie tokenem/hasłem dla wewnętrznych klientów na tym samym hoście, którzy nie przechodzą przez proxy, albo
- Kieruj ruch przez adres zaufanego proxy spoza loopback i utrzymuj ten adres IP w
gateway.trustedProxies, albo - Dla celowo skonfigurowanego odwrotnego proxy na tym samym hoście ustaw
gateway.auth.trustedProxy.allowLoopback = true, pozostaw adres loopback wgateway.trustedProxiesi upewnij się, że proxy usuwa lub nadpisuje nagłówki tożsamości.
trusted_proxy_user_missing
Nagłówek użytkownika był pusty lub go brakowało. Sprawdź:
- Czy proxy jest skonfigurowane do przekazywania nagłówków tożsamości?
- Czy nazwa nagłówka jest poprawna? (wielkość liter nie ma znaczenia, ale pisownia tak)
- Czy użytkownik jest faktycznie uwierzytelniony na proxy?
trusted_proxy_missing_header_*
Wymagany nagłówek nie był obecny. Sprawdź:
- Konfigurację proxy dla tych konkretnych nagłówków.
- Czy nagłówki nie są usuwane gdzieś w łańcuchu.
trusted_proxy_user_not_allowed
Użytkownik jest uwierzytelniony, ale nie znajduje się w allowUsers. Dodaj go albo usuń listę dozwolonych.
trusted_proxy_origin_not_allowed
Uwierzytelnianie trusted-proxy powiodło się, ale nagłówek przeglądarki Origin nie przeszedł kontroli pochodzenia Control UI.
Sprawdź:
gateway.controlUi.allowedOriginszawiera dokładne pochodzenie przeglądarki.- Nie polegasz na wieloznacznych pochodzeniach, chyba że celowo chcesz zachowania zezwalającego na wszystko.
- Jeśli celowo używasz trybu awaryjnego opartego na nagłówku Host,
gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=truejest ustawione świadomie.
WebSocket nadal się nie udaje
Upewnij się, że Twoje proxy:
- Obsługuje aktualizacje WebSocket (
Upgrade: websocket,Connection: upgrade). - Przekazuje nagłówki tożsamości przy żądaniach aktualizacji WebSocket (nie tylko HTTP).
- Nie ma osobnej ścieżki uwierzytelniania dla połączeń WebSocket.
Migracja z uwierzytelniania tokenem
Jeśli przechodzisz z uwierzytelniania tokenem na trusted-proxy:
Skonfiguruj proxy
Skonfiguruj proxy tak, aby uwierzytelniało użytkowników i przekazywało nagłówki.
Przetestuj proxy niezależnie
Przetestuj konfigurację proxy niezależnie (curl z nagłówkami).
Zaktualizuj konfigurację OpenClaw
Zaktualizuj konfigurację OpenClaw z uwierzytelnianiem trusted-proxy.
Uruchom ponownie Gateway
Uruchom ponownie Gateway.
Przetestuj WebSocket
Przetestuj połączenia WebSocket z Control UI.
Audyt
Uruchom openclaw security audit i przejrzyj wyniki.
Powiązane
- Konfiguracja — dokumentacja konfiguracji
- Dostęp zdalny — inne wzorce dostępu zdalnego
- Bezpieczeństwo — pełny przewodnik po bezpieczeństwie
- Tailscale — prostsza alternatywa dla dostępu tylko w tailnet