Skip to main content

Documentation Index

Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt

Use this file to discover all available pages before exploring further.

安全敏感功能。 此模式将认证完全委托给你的反向代理。配置错误可能会使你的 Gateway 暴露给未授权访问。启用前请仔细阅读本页。

何时使用

在以下情况下使用 trusted-proxy 认证模式:
  • 你在 身份感知代理(Pomerium、Caddy + OAuth、nginx + oauth2-proxy、Traefik + forward auth)后运行 OpenClaw。
  • 你的代理处理所有认证,并通过请求头传递用户身份。
  • 你处于 Kubernetes 或容器环境中,代理是到 Gateway 的唯一路径。
  • 由于浏览器无法在 WS 负载中传递令牌,你遇到了 WebSocket 1008 unauthorized 错误。

何时不要使用

  • 如果你的代理不负责用户认证(只是 TLS 终止器或负载均衡器)。
  • 如果有任何绕过代理到达 Gateway 的路径(防火墙漏洞、内部网络访问)。
  • 如果你不确定代理是否正确剥离/覆盖了转发头。
  • 如果你只需要个人单用户访问(可考虑使用 Tailscale Serve + loopback 以获得更简单的配置)。

工作原理

1

代理认证用户

你的反向代理对用户进行认证(OAuth、OIDC、SAML 等)。
2

代理添加身份头

代理添加一个包含已认证用户身份的请求头(例如 x-forwarded-user: nick@example.com)。
3

Gateway 验证受信任来源

OpenClaw 会检查请求是否来自 受信任的代理 IP(在 gateway.trustedProxies 中配置)。
4

Gateway 提取身份

OpenClaw 从配置的请求头中提取用户身份。
5

授权

如果所有检查都通过,请求就会被授权。

Control UI 配对行为

gateway.auth.mode = "trusted-proxy" 处于活动状态且请求通过 trusted-proxy 检查时,Control UI 的 WebSocket 会话可以在没有设备配对身份的情况下连接。 影响:
  • 在此模式下,配对不再是 Control UI 访问的主要门禁。
  • 你的反向代理认证策略和 allowUsers 将成为实际的访问控制。
  • 将 gateway ingress 仅锁定为受信任代理 IP(gateway.trustedProxies + 防火墙)。

配置

{
  gateway: {
    // 默认情况下,trusted-proxy 认证期望请求来自非 loopback 的受信任代理源
    bind: "lan",

    // 关键:这里只添加你的代理 IP
    trustedProxies: ["10.0.0.1", "172.17.0.1"],

    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        // 包含已认证用户身份的请求头(必需)
        userHeader: "x-forwarded-user",

        // 可选:必须存在的请求头(代理验证)
        requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],

        // 可选:限制为特定用户(空值 = 允许所有)
        allowUsers: ["nick@example.com", "admin@company.org"],

        // 可选:在明确启用后允许同主机 loopback 代理
        allowLoopback: false,
      },
    },
  },
}
重要运行规则
  • 默认情况下,Trusted-proxy 认证会拒绝来自 loopback 源的请求(127.0.0.1::1、loopback CIDR)。
  • 同主机 loopback 反向代理不会满足 trusted-proxy 认证,除非你明确设置 gateway.auth.trustedProxy.allowLoopback = true 并将 loopback 地址加入 gateway.trustedProxies
  • allowLoopback 会将 Gateway 主机上的本地进程视为与反向代理同等受信任。仅当 Gateway 仍通过防火墙阻止直接远程访问,且本地代理会剥离或覆盖客户端提供的身份头时才启用它。
  • 不经过反向代理的内部 Gateway 客户端应使用 gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD,而不是 trusted-proxy 身份头。
  • 非 loopback 的 Control UI 部署仍需要显式设置 gateway.controlUi.allowedOrigins
  • 转发头证据会覆盖 loopback 本地性,用于本地直接回退。 如果请求到达 loopback,但携带的 X-Forwarded-For / X-Forwarded-Host / X-Forwarded-Proto 请求头指向非本地来源,那么这些证据会使本地直接密码回退和设备身份门控失效。在 allowLoopback: true 下,trusted-proxy 认证仍可将该请求作为同主机代理请求接受,而 requiredHeadersallowUsers 仍然生效。

配置参考

gateway.trustedProxies
string[]
required
要信任的代理 IP 地址数组。来自其他 IP 的请求将被拒绝。
gateway.auth.mode
string
required
必须是 "trusted-proxy"
gateway.auth.trustedProxy.userHeader
string
required
包含已认证用户身份的请求头名称。
gateway.auth.trustedProxy.requiredHeaders
string[]
请求被信任时必须存在的额外请求头。
gateway.auth.trustedProxy.allowUsers
string[]
用户身份的允许列表。为空表示允许所有已认证用户。
gateway.auth.trustedProxy.allowLoopback
boolean
为同主机 loopback 反向代理提供的可选支持。默认值为 false
仅当本地反向代理是预期的信任边界时才启用 allowLoopback。任何能够连接到 Gateway 的本地进程都可以尝试发送代理身份头,因此应将对 Gateway 的直接访问限制为仅本机,并要求使用代理拥有的请求头,例如 x-forwarded-proto,或者在代理支持的情况下使用签名断言头。

TLS 终止和 HSTS

使用一个 TLS 终止点,并在那里应用 HSTS。
当你的反向代理为 https://control.example.com 处理 HTTPS 时,请在该域名的代理上设置 Strict-Transport-Security
  • 适用于面向互联网的部署。
  • 将证书 + HTTP 加固策略集中在一处管理。
  • OpenClaw 可以在代理后方保持为 loopback HTTP。
示例请求头值:
Strict-Transport-Security: max-age=31536000; includeSubDomains

部署建议

  • 先从较短的 max age 开始,例如 max-age=300,以便在验证流量时使用。
  • 只有在确认充分后,才增加到较长的值,例如 max-age=31536000
  • 只有当所有子域名都已准备好使用 HTTPS 时,才添加 includeSubDomains
  • 只有当你确实为整个域名集合满足 preload 要求时,才使用 preload。
  • 仅用于本地 loopback 的开发不会从 HSTS 中获益。

代理设置示例

Pomerium 通过 x-pomerium-claim-email(或其他 claim 请求头)传递身份,并在 x-pomerium-jwt-assertion 中传递 JWT。
{
  gateway: {
    bind: "lan",
    trustedProxies: ["10.0.0.1"], // Pomerium 的 IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-pomerium-claim-email",
        requiredHeaders: ["x-pomerium-jwt-assertion"],
      },
    },
  },
}
Pomerium 配置片段:
routes:
  - from: https://openclaw.example.com
    to: http://openclaw-gateway:18789
    policy:
      - allow:
          or:
            - email:
                is: nick@example.com
    pass_identity_headers: true
caddy-security 插件的 Caddy 可以对用户进行认证并传递身份请求头。
{
  gateway: {
    bind: "lan",
    trustedProxies: ["10.0.0.1"], // Caddy/sidecar 代理 IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-forwarded-user",
      },
    },
  },
}
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 对用户进行认证,并在 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 配置片段:
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 容器 IP
    auth: {
      mode: "trusted-proxy",
      trustedProxy: {
        userHeader: "x-forwarded-user",
      },
    },
  },
}

混合令牌配置

gateway.auth.token(或 OPENCLAW_GATEWAY_TOKEN)与 trusted-proxy 模式同时启用时,OpenClaw 会拒绝模糊不清的配置。混合令牌配置可能导致 loopback 请求在错误的认证路径上静默通过认证。 如果启动时看到 mixed_trusted_proxy_token 错误:
  • 在使用 trusted-proxy 模式时移除共享令牌,或
  • 如果你打算使用基于令牌的认证,请将 gateway.auth.mode 切换为 "token"
loopback 的 trusted-proxy 身份头仍然会安全失败:同主机调用者不会被静默认证为代理用户。不经过代理的内部 OpenClaw 调用者可以改为使用 gateway.auth.password / OPENCLAW_GATEWAY_PASSWORD 进行认证。在 trusted-proxy 模式下,令牌回退仍然被有意不支持。

Operator scopes header

受信任代理认证是一种 带身份 的 HTTP 模式,因此调用方可以选择使用 x-openclaw-scopes 声明 operator scopes。 示例:
  • x-openclaw-scopes: operator.read
  • x-openclaw-scopes: operator.read,operator.write
  • x-openclaw-scopes: operator.admin,operator.write
行为:
  • 当该头存在时,OpenClaw 会遵循所声明的 scope 集合。
  • 当该头存在但为空时,请求声明 没有 operator scopes。
  • 当该头不存在时,常规带身份的 HTTP API 会回退到标准的 operator 默认 scope 集合。
  • Gateway-auth 插件 HTTP 路由 默认更窄:当 x-openclaw-scopes 不存在时,它们运行时的 scope 会回退到 operator.write
  • 即使受信任代理认证成功,来自浏览器的 HTTP 请求仍然必须通过 gateway.controlUi.allowedOrigins(或有意启用的 Host-header 回退模式)。
实用规则:当你希望受信任代理请求比默认值更窄,或者当某个 gateway-auth 插件路由需要比 write scope 更强的权限时,请显式发送 x-openclaw-scopes

安全检查清单

在启用受信任代理认证之前,请确认:
  • 代理是唯一入口:Gateway 端口已通过防火墙限制,除你的代理外其他来源均无法访问。
  • trustedProxies 尽量最小化:只填写实际代理的 IP,不要包含整个子网。
  • 回环代理来源是有意为之:对于来自 loopback 源的请求,受信任代理认证默认会失败关闭,除非为同主机代理显式启用 gateway.auth.trustedProxy.allowLoopback
  • 代理会剥离头部:你的代理会覆盖(不是追加)来自客户端的 x-forwarded-* 头。
  • TLS 终止:你的代理负责处理 TLS;用户通过 HTTPS 连接。
  • allowedOrigins 是显式配置的:非 loopback 的 Control UI 使用显式的 gateway.controlUi.allowedOrigins
  • 已设置 allowUsers(推荐):限制为已知用户,而不是允许任何已认证用户。
  • 没有混用 token 配置:不要同时设置 gateway.auth.tokengateway.auth.mode: "trusted-proxy"
  • 本地密码回退是私有的:如果你为内部直接调用者配置了 gateway.auth.password,请保持 Gateway 端口受防火墙保护,以免非代理远程客户端直接访问。

安全审计

openclaw security audit 会将受信任代理认证标记为 critical 级别发现。这是有意为之——它是在提醒你,安全性已经委托给你的代理配置。 审计会检查:
  • 基础的 gateway.trusted_proxy_auth 警告/critical 提示
  • 缺少 trustedProxies 配置
  • 缺少 userHeader 配置
  • allowUsers 为空(允许任何已认证用户)
  • 为同主机代理来源启用了 allowLoopback
  • 暴露的 Control UI 表面存在通配或缺失的浏览器来源策略

故障排查

请求并非来自 gateway.trustedProxies 中的 IP。请检查:
  • 代理 IP 是否正确?(Docker 容器 IP 可能会变化。)
  • 你的代理前面是否还有负载均衡器?
  • 使用 docker inspectkubectl get pods -o wide 查找实际 IP。
OpenClaw 拒绝了来自 loopback 源的受信任代理请求。请检查:
  • 代理是否正从 127.0.0.1 / ::1 连接?
  • 你是否在尝试对同主机 loopback 反向代理使用受信任代理认证?
解决方法:
  • 对于不经过代理的内部同主机客户端,优先使用 token/password 认证,或者
  • 通过非 loopback 的受信任代理地址进行路由,并将该 IP 保留在 gateway.trustedProxies 中,或者
  • 对于有意使用的同主机反向代理,将 gateway.auth.trustedProxy.allowLoopback = true,把 loopback 地址保留在 gateway.trustedProxies 中,并确保代理会剥离或覆盖身份头。
用户头为空或缺失。请检查:
  • 你的代理是否配置为传递身份头?
  • 头名称是否正确?(大小写不敏感,但拼写必须正确)
  • 用户是否真的已在代理端完成认证?
某个必需的头不存在。请检查:
  • 你的代理对这些特定头的配置。
  • 是否在链路中的某处被剥离了头部。
用户已通过认证,但不在 allowUsers 中。请将其加入,或者移除允许列表。
受信任代理认证已成功,但浏览器的 Origin 头未通过 Control UI 的来源检查。请检查:
  • gateway.controlUi.allowedOrigins 是否包含精确的浏览器 origin。
  • 除非你有意启用全放行行为,否则不要依赖通配来源。
  • 如果你确实在使用 Host-header 回退模式,请明确设置 gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true
请确保你的代理:
  • 支持 WebSocket 升级(Upgrade: websocket, Connection: upgrade)。
  • 在 WebSocket 升级请求中传递身份头(不仅仅是 HTTP 请求)。
  • 没有为 WebSocket 连接设置单独的认证路径。

从 token auth 迁移

如果你要从 token auth 迁移到受信任代理:
1

配置代理

配置你的代理以认证用户并传递头部。
2

独立测试代理

独立测试代理配置(使用带头部的 curl)。
3

更新 OpenClaw 配置

使用受信任代理认证更新 OpenClaw 配置。
4

重启 Gateway

重启 Gateway。
5

测试 WebSocket

从 Control UI 测试 WebSocket 连接。
6

审计

运行 openclaw security audit 并检查发现。

相关