Autenticación con proxy de confianza
Funcionalidad sensible para la seguridad. Este modo delega la autenticación completamente a tu proxy reverso. Una configuración incorrecta puede exponer tu Gateway a acceso no autorizado. Lee esta página detenidamente antes de habilitarlo.
Cuándo usarlo
Usa el modo de autenticación trusted-proxy cuando:
- Ejecutas OpenClaw detrás de un proxy con reconocimiento de identidad (Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + forward auth)
- Tu proxy maneja toda la autenticación y pasa la identidad del usuario vía headers
- Estás en un entorno Kubernetes o de contenedores donde el proxy es el único camino al Gateway
- Estás experimentando errores WebSocket
1008 unauthorizedporque los navegadores no pueden pasar tokens en payloads WS
Cuándo NO usarlo
- Si tu proxy no autentica usuarios (solo un terminador TLS o balanceador de carga)
- Si existe algún camino al Gateway que omita el proxy (agujeros de firewall, acceso de red interna)
- Si no estás seguro de que tu proxy quita/sobrescribe correctamente los headers de reenvío
- Si solo necesitas acceso personal de un solo usuario (considera Tailscale Serve + loopback para una configuración más simple)
Cómo funciona
- Tu proxy reverso autentica a los usuarios (OAuth, OIDC, SAML, etc.)
- El proxy agrega un header con la identidad del usuario autenticado (ej.,
x-forwarded-user: [email protected]) - OpenClaw verifica que la solicitud provino de una IP de proxy de confianza (configurada en
gateway.trustedProxies) - OpenClaw extrae la identidad del usuario del header configurado
- Si todo coincide, la solicitud se autoriza
Comportamiento de emparejamiento en la UI de control
Cuando gateway.auth.mode = "trusted-proxy" está activo y la solicitud pasa las
verificaciones de proxy de confianza, las sesiones WebSocket de la UI de control pueden conectarse sin
identidad de emparejamiento de dispositivo.
Implicaciones:
- El emparejamiento ya no es la compuerta principal para el acceso a la UI de control en este modo.
- La política de autenticación de tu proxy reverso y
allowUsersse convierten en el control de acceso efectivo. - Mantén el ingreso al gateway bloqueado solo a las IPs de proxy de confianza (
gateway.trustedProxies+ firewall).
Configuración
{
gateway: {
// Usa loopback para configuraciones de proxy en el mismo host; usa lan/custom para hosts de proxy remotos
bind: "loopback",
// FUNDAMENTAL: Solo agrega las IP(s) de tu proxy aquí
trustedProxies: ["10.0.0.1", "172.17.0.1"],
auth: {
mode: "trusted-proxy",
trustedProxy: {
// Header que contiene la identidad del usuario autenticado (obligatorio)
userHeader: "x-forwarded-user",
// Opcional: headers que DEBEN estar presentes (verificación del proxy)
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
// Opcional: restringir a usuarios específicos (vacío = permitir todos)
allowUsers: ["[email protected]", "[email protected]"],
},
},
},
}
Si gateway.bind es loopback, incluye una dirección de proxy loopback en
gateway.trustedProxies (127.0.0.1, ::1, o un CIDR loopback equivalente).
Referencia de configuración
| Campo | Obligatorio | Descripción |
|---|---|---|
gateway.trustedProxies | Sí | Array de direcciones IP de proxy a confiar. Las solicitudes de otras IPs se rechazan. |
gateway.auth.mode | Sí | Debe ser "trusted-proxy" |
gateway.auth.trustedProxy.userHeader | Sí | Nombre del header que contiene la identidad del usuario autenticado |
gateway.auth.trustedProxy.requiredHeaders | No | Headers adicionales que deben estar presentes para que la solicitud sea confiable |
gateway.auth.trustedProxy.allowUsers | No | Lista de identidades de usuario permitidas. Vacío significa permitir todos los usuarios autenticados. |
Terminación TLS y HSTS
Usa un punto de terminación TLS y aplica HSTS allí.
Patrón recomendado: terminación TLS en el proxy
Cuando tu proxy reverso maneja HTTPS para https://control.example.com, configura
Strict-Transport-Security en el proxy para ese dominio.
- Buena opción para despliegues expuestos a internet.
- Mantiene el certificado + la política de endurecimiento HTTP en un solo lugar.
- OpenClaw puede permanecer en HTTP loopback detrás del proxy.
Ejemplo de valor del header:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Terminación TLS en el Gateway
Si OpenClaw mismo sirve HTTPS directamente (sin proxy que termine TLS), configura:
{
gateway: {
tls: { enabled: true },
http: {
securityHeaders: {
strictTransportSecurity: "max-age=31536000; includeSubDomains",
},
},
},
}
strictTransportSecurity acepta un valor de string de header, o false para deshabilitar explícitamente.
Guía de implementación
- Comienza con un max age corto primero (por ejemplo
max-age=300) mientras validas el tráfico. - Aumenta a valores de larga duración (por ejemplo
max-age=31536000) solo después de tener confianza. - Agrega
includeSubDomainssolo si cada subdominio está listo para HTTPS. - Usa preload solo si cumples intencionalmente los requisitos de preload para todo tu conjunto de dominios.
- El desarrollo local solo en loopback no se beneficia de HSTS.
Ejemplos de configuración de proxy
Pomerium
Pomerium pasa la identidad en x-pomerium-claim-email (u otros headers de claims) y un JWT en x-pomerium-jwt-assertion.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // IP de Pomerium
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-pomerium-claim-email",
requiredHeaders: ["x-pomerium-jwt-assertion"],
},
},
},
}
Fragmento de configuración de Pomerium:
routes:
- from: https://openclaw.example.com
to: http://openclaw-gateway:18789
policy:
- allow:
or:
- email:
is: [email protected]
pass_identity_headers: true
Caddy con OAuth
Caddy con el plugin caddy-security puede autenticar usuarios y pasar headers de identidad.
{
gateway: {
bind: "lan",
trustedProxies: ["127.0.0.1"], // IP de Caddy (si está en el mismo host)
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Fragmento 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}
}
}
nginx + oauth2-proxy
oauth2-proxy autentica usuarios y pasa la identidad en x-auth-request-email.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"], // IP de nginx/oauth2-proxy
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-auth-request-email",
},
},
},
}
Fragmento de configuración de 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 con Forward Auth
{
gateway: {
bind: "lan",
trustedProxies: ["172.17.0.1"], // IP del contenedor de Traefik
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
Lista de verificación de seguridad
Antes de habilitar la autenticación con proxy de confianza, verifica:
- El proxy es el único camino: El puerto del Gateway está protegido por firewall de todo excepto tu proxy
- trustedProxies es mínimo: Solo las IPs reales de tu proxy, no subredes completas
- El proxy quita headers: Tu proxy sobrescribe (no agrega) los headers
x-forwarded-*de los clientes - Terminación TLS: Tu proxy maneja TLS; los usuarios se conectan vía HTTPS
- allowUsers está configurado (recomendado): Restringe a usuarios conocidos en lugar de permitir cualquier persona autenticada
Auditoría de seguridad
openclaw security audit marcará la autenticación con proxy de confianza con un hallazgo de severidad crítica. Esto es intencional: es un recordatorio de que estás delegando la seguridad a tu configuración de proxy.
La auditoría verifica:
- Configuración de
trustedProxiesfaltante - Configuración de
userHeaderfaltante allowUsersvacío (permite cualquier usuario autenticado)
Solución de problemas
”trusted_proxy_untrusted_source”
La solicitud no provino de una IP en gateway.trustedProxies. Verifica:
- ¿La IP del proxy es correcta? (Las IPs de contenedores Docker pueden cambiar)
- ¿Hay un balanceador de carga frente a tu proxy?
- Usa
docker inspectokubectl get pods -o widepara encontrar las IPs reales
”trusted_proxy_user_missing”
El header del usuario estaba vacío o faltaba. Verifica:
- ¿Tu proxy está configurado para pasar headers de identidad?
- ¿El nombre del header es correcto? (insensible a mayúsculas, pero la ortografía importa)
- ¿El usuario está realmente autenticado en el proxy?
“trustedproxy_missing_header*”
Un header requerido no estaba presente. Verifica:
- Tu configuración del proxy para esos headers específicos
- Si los headers se están quitando en algún punto de la cadena
”trusted_proxy_user_not_allowed”
El usuario está autenticado pero no está en allowUsers. Agrégalo o elimina la lista de permitidos.
WebSocket sigue fallando
Asegúrate de que tu proxy:
- Soporta upgrades de WebSocket (
Upgrade: websocket,Connection: upgrade) - Pasa los headers de identidad en las solicitudes de upgrade de WebSocket (no solo en HTTP)
- No tiene una ruta de autenticación separada para conexiones WebSocket
Migración desde autenticación por token
Si estás migrando de autenticación por token a proxy de confianza:
- Configura tu proxy para autenticar usuarios y pasar headers
- Prueba la configuración del proxy independientemente (curl con headers)
- Actualiza la configuración de OpenClaw con autenticación por proxy de confianza
- Reinicia el Gateway
- Prueba las conexiones WebSocket desde la UI de control
- Ejecuta
openclaw security audity revisa los hallazgos
Relacionado
- Seguridad — guía completa de seguridad
- Configuración — referencia de configuración
- Acceso remoto — otros patrones de acceso remoto
- Tailscale — alternativa más simple para acceso solo por tailnet