Trusted-Proxy-Auth
Sicherheitssensitives Feature. Dieser Modus delegiert die Authentifizierung vollständig an deinen Reverse-Proxy. Fehlkonfiguration kann dein Gateway unbefugtem Zugriff aussetzen. Lies diese Seite sorgfältig, bevor du ihn aktivierst.
Wann verwenden
Verwende den trusted-proxy-Auth-Modus, wenn:
- Du OpenClaw hinter einem identitätsbewussten Proxy betreibst (Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + Forward-Auth)
- Dein Proxy die gesamte Authentifizierung übernimmt und die Benutzeridentität per Header weitergibt
- Du dich in einer Kubernetes- oder Container-Umgebung befindest, in der der Proxy der einzige Weg zum Gateway ist
- Du auf WebSocket-
1008 unauthorized-Fehler stößt, weil Browser keine Tokens in WS-Payloads senden können
Wann NICHT verwenden
- Wenn dein Proxy keine Benutzer authentifiziert (nur TLS-Terminator oder Load-Balancer)
- Wenn es einen Weg zum Gateway gibt, der den Proxy umgeht (Firewall-Löcher, interner Netzwerkzugriff)
- Wenn du unsicher bist, ob dein Proxy Forwarded-Header korrekt entfernt/überschreibt
- Wenn du nur persönlichen Single-User-Zugriff brauchst (erwäge Tailscale Serve + Loopback für ein einfacheres Setup)
Funktionsweise
- Dein Reverse-Proxy authentifiziert Benutzer (OAuth, OIDC, SAML usw.)
- Der Proxy fügt einen Header mit der authentifizierten Benutzeridentität hinzu (z. B.
x-forwarded-user: [email protected]) - OpenClaw prüft, ob die Anfrage von einer vertrauenswürdigen Proxy-IP kommt (konfiguriert in
gateway.trustedProxies) - OpenClaw extrahiert die Benutzeridentität aus dem konfigurierten Header
- Wenn alles stimmt, wird die Anfrage autorisiert
Control-UI-Pairing-Verhalten
Wenn gateway.auth.mode = "trusted-proxy" aktiv ist und die Anfrage die
Trusted-Proxy-Prüfungen besteht, können Control-UI-WebSocket-Sessions ohne Device-Pairing-Identität verbinden.
Implikationen:
- Pairing ist in diesem Modus nicht mehr das primäre Gate für Control-UI-Zugriff.
- Die Auth-Policy deines Reverse-Proxys und
allowUserswerden zur effektiven Zugriffskontrolle. - Halte den Gateway-Ingress auf vertrauenswürdige Proxy-IPs beschränkt (
gateway.trustedProxies+ Firewall).
Konfiguration
{
gateway: {
// loopback für Same-Host-Proxy-Setups; lan/custom für Remote-Proxy-Hosts verwenden
bind: "loopback",
// WICHTIG: Hier nur die IPs deines Proxys eintragen
trustedProxies: ["10.0.0.1", "172.17.0.1"],
auth: {
mode: "trusted-proxy",
trustedProxy: {
// Header mit authentifizierter Benutzeridentität (erforderlich)
userHeader: "x-forwarded-user",
// Optional: Header, die vorhanden sein MÜSSEN (Proxy-Verifizierung)
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
// Optional: auf bestimmte Benutzer einschränken (leer = alle erlauben)
allowUsers: ["[email protected]", "[email protected]"],
},
},
},
}
Wenn gateway.bind auf loopback steht, nimm eine Loopback-Proxy-Adresse in
gateway.trustedProxies auf (127.0.0.1, ::1 oder ein äquivalentes Loopback-CIDR).
Konfigurationsreferenz
| Feld | Erforderlich | Beschreibung |
|---|---|---|
gateway.trustedProxies | Ja | Array von Proxy-IP-Adressen, denen vertraut wird. Anfragen von anderen IPs werden abgelehnt. |
gateway.auth.mode | Ja | Muss "trusted-proxy" sein |
gateway.auth.trustedProxy.userHeader | Ja | Header-Name mit der authentifizierten Benutzeridentität |
gateway.auth.trustedProxy.requiredHeaders | Nein | Zusätzliche Header, die vorhanden sein müssen, damit die Anfrage als vertrauenswürdig gilt |
gateway.auth.trustedProxy.allowUsers | Nein | Allowlist von Benutzeridentitäten. Leer bedeutet: alle authentifizierten Benutzer erlauben. |
TLS-Terminierung und HSTS
Verwende einen TLS-Terminierungspunkt und wende HSTS dort an.
Empfohlenes Muster: Proxy-TLS-Terminierung
Wenn dein Reverse-Proxy HTTPS für https://control.example.com handhabt, setze
Strict-Transport-Security am Proxy für diese Domain.
- Gute Wahl für internetexponierte Deployments.
- Hält Zertifikat + HTTP-Härtungs-Policy an einem Ort.
- OpenClaw kann hinter dem Proxy auf Loopback-HTTP bleiben.
Beispiel-Header-Wert:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Gateway-TLS-Terminierung
Wenn OpenClaw selbst direkt HTTPS bereitstellt (kein TLS-terminierender Proxy), setze:
{
gateway: {
tls: { enabled: true },
http: {
securityHeaders: {
strictTransportSecurity: "max-age=31536000; includeSubDomains",
},
},
},
}
strictTransportSecurity akzeptiert einen String-Header-Wert oder false zum expliziten Deaktivieren.
Rollout-Empfehlungen
- Beginne mit einer kurzen Max-Age (z. B.
max-age=300) während der Validierung des Traffics. - Erhöhe auf langlebige Werte (z. B.
max-age=31536000) erst nach ausreichend Vertrauen. - Füge
includeSubDomainsnur hinzu, wenn jede Subdomain HTTPS-bereit ist. - Verwende Preload nur, wenn du bewusst die Preload-Anforderungen für dein gesamtes Domain-Set erfüllst.
- Loopback-only lokale Entwicklung profitiert nicht von HSTS.
Proxy-Setup-Beispiele
Pomerium
Pomerium übergibt die Identität in x-pomerium-claim-email (oder anderen Claim-Headern) und ein JWT in x-pomerium-jwt-assertion.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // Pomeriums IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-pomerium-claim-email",
requiredHeaders: ["x-pomerium-jwt-assertion"],
},
},
},
}
Pomerium-Konfigurationsauszug:
routes:
- from: https://openclaw.example.com
to: http://openclaw-gateway:18789
policy:
- allow:
or:
- email:
is: [email protected]
pass_identity_headers: true
Caddy mit OAuth
Caddy mit dem caddy-security-Plugin kann Benutzer authentifizieren und Identity-Header weiterleiten.
{
gateway: {
bind: "lan",
trustedProxies: ["127.0.0.1"], // Caddys IP (wenn auf demselben Host)
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Caddyfile-Auszug:
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 authentifiziert Benutzer und übergibt die Identität in 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",
},
},
},
}
nginx-Konfigurationsauszug:
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 mit Forward-Auth
{
gateway: {
bind: "lan",
trustedProxies: ["172.17.0.1"], // Traefik-Container-IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Sicherheits-Checkliste
Überprüfe vor der Aktivierung von Trusted-Proxy-Auth:
- Proxy ist der einzige Weg: Der Gateway-Port ist per Firewall gegen alles außer deinem Proxy geschützt
- trustedProxies ist minimal: Nur die tatsächlichen Proxy-IPs, keine ganzen Subnetze
- Proxy entfernt Header: Dein Proxy überschreibt (nicht anhängt)
x-forwarded-*-Header von Clients - TLS-Terminierung: Dein Proxy handhabt TLS; Benutzer verbinden sich via HTTPS
- allowUsers ist gesetzt (empfohlen): Auf bekannte Benutzer einschränken statt jeden Authentifizierten zuzulassen
Security Audit
openclaw security audit markiert Trusted-Proxy-Auth mit einem Finding der Schwere critical. Das ist beabsichtigt — es erinnert daran, dass du die Sicherheit an dein Proxy-Setup delegierst.
Das Audit prüft auf:
- Fehlende
trustedProxies-Konfiguration - Fehlende
userHeader-Konfiguration - Leere
allowUsers(erlaubt jeden authentifizierten Benutzer)
Fehlerbehebung
”trusted_proxy_untrusted_source”
Die Anfrage kam nicht von einer IP in gateway.trustedProxies. Prüfe:
- Stimmt die Proxy-IP? (Docker-Container-IPs können sich ändern)
- Gibt es einen Load-Balancer vor deinem Proxy?
- Verwende
docker inspectoderkubectl get pods -o wide, um die tatsächlichen IPs zu finden
”trusted_proxy_user_missing”
Der User-Header war leer oder fehlte. Prüfe:
- Ist dein Proxy konfiguriert, Identity-Header weiterzuleiten?
- Stimmt der Header-Name? (Case-insensitive, aber Schreibweise zählt)
- Ist der Benutzer tatsächlich beim Proxy authentifiziert?
“trustedproxy_missing_header*”
Ein erforderlicher Header war nicht vorhanden. Prüfe:
- Die Proxy-Konfiguration für diese spezifischen Header
- Ob Header irgendwo in der Kette entfernt werden
”trusted_proxy_user_not_allowed”
Der Benutzer ist authentifiziert, aber nicht in allowUsers. Entweder hinzufügen oder die Allowlist entfernen.
WebSocket schlägt weiterhin fehl
Stelle sicher, dass dein Proxy:
- WebSocket-Upgrades unterstützt (
Upgrade: websocket,Connection: upgrade) - Die Identity-Header bei WebSocket-Upgrade-Requests weiterleitet (nicht nur bei HTTP)
- Keinen separaten Auth-Pfad für WebSocket-Verbindungen hat
Migration von Token-Auth
Wenn du von Token-Auth zu Trusted-Proxy wechselst:
- Konfiguriere deinen Proxy zur Benutzer-Authentifizierung und Header-Weiterleitung
- Teste das Proxy-Setup unabhängig (curl mit Headern)
- Aktualisiere die OpenClaw-Konfiguration mit Trusted-Proxy-Auth
- Starte das Gateway neu
- Teste WebSocket-Verbindungen von der Control-UI
- Führe
openclaw security auditaus und prüfe die Befunde
Verwandt
- Sicherheit — vollständiger Sicherheitsleitfaden
- Konfiguration — Konfigurationsreferenz
- Remote-Zugriff — andere Remote-Zugriffsmuster
- Tailscale — einfachere Alternative für Tailnet-only-Zugriff