Aller au contenu

Authentification par proxy de confiance

⚠️ Fonctionnalité sensible à la sécurité. Ce mode délègue entièrement l’authentification à votre reverse proxy. Une mauvaise configuration peut exposer votre Gateway à un accès non autorisé. Lisez attentivement cette page avant d’activer cette fonctionnalité.

Utilisez le mode d’authentification trusted-proxy lorsque :

  • Vous exécutez OpenClaw derrière un proxy conscient de l’identité (Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + authentification de transfert)
  • Votre proxy gère toute l’authentification et transmet l’identité de l’utilisateur via des en-têtes
  • Vous êtes dans un environnement Kubernetes ou conteneurisé où le proxy est le seul chemin d’accès à la Gateway
  • Vous rencontrez des erreurs WebSocket 1008 unauthorized car les navigateurs ne peuvent pas transmettre de jetons dans les charges utiles WS
  • Si votre proxy n’authentifie pas les utilisateurs (simplement un terminateur TLS ou un équilibreur de charge)
  • S’il existe un chemin vers la Gateway qui contourne le proxy (trous dans le pare-feu, accès réseau interne)
  • Si vous n’êtes pas sûr que votre proxy supprime/écrase correctement les en-têtes transférés
  • Si vous avez uniquement besoin d’un accès personnel monoutilisateur (envisagez Tailscale Serve + boucle locale pour une configuration plus simple)
  1. Votre reverse proxy authentifie les utilisateurs (OAuth, OIDC, SAML, etc.)
  2. Le proxy ajoute un en-tête avec l’identité de l’utilisateur authentifié (par exemple, x-forwarded-user: [email protected])
  3. OpenClaw vérifie que la requête provient d’une IP de proxy de confiance (configurée dans gateway.trustedProxies)
  4. OpenClaw extrait l’identité de l’utilisateur de l’en-tête configuré
  5. Si tout est vérifié, la requête est autorisée

Comportement de l’appairage de l’interface de contrôle

Section intitulée « Comportement de l’appairage de l’interface de contrôle »

Lorsque gateway.auth.mode = "trusted-proxy" est actif et que la requête réussit les vérifications du proxy de confiance, les sessions WebSocket de l’interface de contrôle peuvent se connecter sans dentité d’appairage d’appareil.

Implications :

  • L’appairage n’est plus la porte principale pour l’accès à l’interface de contrôle dans ce mode.
  • Votre stratégie d’authentification de reverse proxy et allowUsers deviennent le contrôle d’accès effectif.
  • Maintenez l’accès à la passerelle verrouillé uniquement sur les IP de proxy de confiance (gateway.trustedProxies + pare-feu).
{
gateway: {
// Use loopback for same-host proxy setups; use lan/custom for remote proxy hosts
bind: "loopback",
// 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)
},
},
},
}

Si gateway.bind est loopback, incluez une adresse proxy de bouclage dans gateway.trustedProxies (127.0.0.1, ::1, ou un CIDR de bouclage équivalent).

ChampObligatoireDescription
gateway.trustedProxiesOuiTableau d’adresses IP de proxy à approuver. Les requêtes provenant d’autres adresses IP sont rejetées.
gateway.auth.modeOuiDoit être "trusted-proxy"
gateway.auth.trustedProxy.userHeaderOuiNom de l’en-tête contenant l’identité de l’utilisateur authentifié
gateway.auth.trustedProxy.requiredHeadersNonEn-têtes supplémentaires qui doivent être présents pour que la requête soit approuvée
gateway.auth.trustedProxy.allowUsersNonListe blanche des identités utilisateur. Vide signifie autoriser tous les utilisateurs authentifiés.

Utilisez un seul point de terminaison TLS et appliquez HSTS à cet endroit.

Modèle recommandé : terminaison TLS par le proxy

Section intitulée « Modèle recommandé : terminaison TLS par le proxy »

Lorsque votre proxy inverse gère le HTTPS pour https://control.example.com, définissez Strict-Transport-Security au niveau du proxy pour ce domaine.

  • Convient bien aux déploiements accessibles sur Internet.
  • Conserve le certificat et la stratégie de durcissement HTTP au même endroit.
  • OpenClaw peut rester en HTTP loopback derrière le proxy.

Exemple de valeur d’en-tête :

Strict-Transport-Security: max-age=31536000; includeSubDomains

Si OpenClaw sert directement le HTTPS (sans proxy de terminaison TLS), définissez :

{
gateway: {
tls: { enabled: true },
http: {
securityHeaders: {
strictTransportSecurity: "max-age=31536000; includeSubDomains",
},
},
},
}

strictTransportSecurity accepte une valeur d’en-tête sous forme de chaîne, ou false pour désactiver explicitement.

  • Commencez par une durée max-age courte (par exemple max-age=300) lors de la validation du trafic.
  • Augmentez vers des valeurs de longue durée (par exemple max-age=31536000) uniquement lorsque vous êtes pleinement confiant.
  • Ajoutez includeSubDomains uniquement si chaque sous-domaine est prêt pour le HTTPS.
  • Utilisez le préchargement uniquement si vous répondez intentionnellement aux exigences de préchargement pour l’ensemble de vos domaines.
  • Le développement local en boucle locale (loopback) ne bénéficie pas de HSTS.

Pomerium transmet l’identité dans x-pomerium-claim-email (ou d’autres en-têtes de revendication) et un JWT dans 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"],
},
},
},
}

Extrait de configuration Pomerium :

routes:
- from: https://openclaw.example.com
to: http://openclaw-gateway:18789
policy:
- allow:
or:
- email:
pass_identity_headers: true

Caddy avec le plugin caddy-security peut authentifier les utilisateurs et transmettre les en-têtes d’identité.

{
gateway: {
bind: "lan",
trustedProxies: ["127.0.0.1"], // Caddy's IP (if on same host)
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}

Extrait de Caddyfile :

openclaw.example.com {
authenticate with oauth2_provider
authorize with policy1
reverse_proxy openclaw:18789 {
header_up X-Forwarded-User {http.auth.user.email}
}
}

oauth2-proxy authentifie les utilisateurs et transmet l’identité dans 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",
},
},
},
}

Extrait de configuration 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";
}
{
gateway: {
bind: "lan",
trustedProxies: ["172.17.0.1"], // Traefik container IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}

OpenClaw rejette les configurations ambiguës où un gateway.auth.token (ou OPENCLAW_GATEWAY_TOKEN) et le mode trusted-proxy sont actifs simultanément. Les configurations de jetons mixtes peuvent provoquer l’authentification silencieuse des requêtes de bouclage sur le mauvais chemin d’authentification.

Si vous rencontrez une erreur mixed_trusted_proxy_token au démarrage :

  • Supprimez le jeton partagé lors de l’utilisation du mode trusted-proxy, ou
  • Passez gateway.auth.mode à "token" si vous avez l’intention d’utiliser une authentification par jeton.

L’authentification trusted-proxy en boucle échoue également de manière sécurisée : les appelants sur le même hôte doivent fournir les en-têtes d’identité configurés via un proxy de confiance au lieu d’être authentifiés silencieusement.

Avant d’activer l’authentification de proxy de confiance, vérifiez :

  • Le proxy est le seul chemin : Le port du Gateway est protégé par un pare-feu contre tout sauf votre proxy
  • trustedProxies est minimal : Uniquement vos adresses IP de proxy réelles, et non des sous-réseaux entiers
  • Proxy strips headers : Votre proxy écrase (n’ajoute pas à) les en-têtes x-forwarded-* des clients
  • TLS termination : Votre proxy gère le TLS ; les utilisateurs se connectent via HTTPS
  • allowUsers est défini (recommandé) : Restreindre aux utilisateurs connus plutôt que d’autoriser toute personne authentifiée
  • Pas de configuration de jetons mixte : Ne définissez pas à la fois gateway.auth.token et gateway.auth.mode: "trusted-proxy"

openclaw security audit signalera l’authentification de proxy de confiance avec une constatation de gravité critique. C’est intentionnel — c’est un rappel que vous déléguez la sécurité à votre configuration de proxy.

L’audit vérifie :

  • Configuration trustedProxies manquante
  • Configuration userHeader manquante
  • allowUsers vide (autorise tout utilisateur authentifié)

La requête ne provenait pas d’une adresse IP présente dans gateway.trustedProxies. Vérifiez :

  • L’adresse IP du proxy est-elle correcte ? (Les adresses IP des conteneurs Docker peuvent changer)
  • Y a-t-il un équilibreur de charge devant votre proxy ?
  • Utilisez docker inspect ou kubectl get pods -o wide pour trouver les adresses IP réelles

L’en-tête utilisateur était vide ou manquant. Vérifiez :

  • Votre proxy est-il configuré pour transmettre les en-têtes d’identité ?
  • Le nom de l’en-tête est-il correct ? (insensible à la casse, mais l’orthographe compte)
  • L’utilisateur est-il réellement authentifié au niveau du proxy ?

Un en-tête requis était absent. Vérifiez :

  • Votre configuration de proxy pour ces en-têtes spécifiques
  • Si les en-têtes sont supprimés quelque part dans la chaîne

L’utilisateur est authentifié mais n’est pas dans allowUsers. Ajoutez-le ou supprimez la liste d’autorisation.

Assurez-vous que votre proxy :

  • Prend en charge les mises à niveau WebSocket (Upgrade: websocket, Connection: upgrade)
  • Transmet les en-têtes d’identité lors des demandes de mise à niveau WebSocket (pas seulement HTTP)
  • Ne possède pas de chemin d’authentification distinct pour les connexions WebSocket

Si vous passez de l’authentification par jeton à trusted-proxy :

  1. Configurez votre proxy pour authentifier les utilisateurs et transmettre les en-têtes
  2. Test the proxy setup independently (curl with headers)
  3. Update OpenClaw config with trusted-proxy auth
  4. Restart the Gateway
  5. Test WebSocket connections from the Control UI
  6. Exécutez openclaw security audit et passez en revue les résultats