OpenClawのTrusted Proxy認証設定:リバースプロキシ連携ガイド
認証周りの設定は、開発者にとって常に悩みの種ですよね。特にリバースプロキシをすでに運用している場合、各サービスごとに個別の認証ロジックを組み込むのは非効率ですし、WebSocket でのトークン管理に苦労した経験がある方も多いのではないでしょうか。
そんな時に役立つのが、この trusted-proxy 認証モードです。既存の認証インフラを活かしつつ、Gateway へのアクセスをスマートに管理する方法を解説します。
Trusted Proxy 認証
Section titled “Trusted Proxy 認証”⚠️ セキュリティに関わる重要な機能です。 このモードは、認証のすべてをリバースプロキシに委ねます。設定を誤ると、Gateway が不正アクセスにさらされる危険があります。有効にする前に、このページを注意深く読んでください。
使用するケース
Section titled “使用するケース”以下のような場合に trusted-proxy 認証モードを使用してください。
- Pomerium、Caddy + OAuth、nginx + oauth2-proxy、Traefik + forward auth などの ID 認識プロキシ(identity-aware proxy) の背後で OpenClaw を実行する場合
- プロキシがすべての認証を処理し、ヘッダーを介してユーザー ID を渡す場合
- Kubernetes やコンテナ環境で、プロキシが Gateway への唯一の経路である場合
- ブラウザが WebSocket のペイロードでトークンを渡せないために、WebSocket の
1008 unauthorizedエラーが発生している場合
使用すべきでないケース
Section titled “使用すべきでないケース”- プロキシがユーザー認証を行わない場合(単なる TLS 終端やロードバランサーとして機能している場合)
- ファイアウォールの穴や内部ネットワーク経由など、プロキシをバイパスして Gateway にアクセスできる経路がある場合
- プロキシが転送されたヘッダーを正しく削除・上書きしているか確信が持てない場合
- 個人のシングルユーザーアクセスのみが必要な場合(よりシンプルなセットアップとして Tailscale Serve + loopback を検討してください)
- リバースプロキシがユーザーを認証します(OAuth, OIDC, SAML など)。
- プロキシは、認証されたユーザー ID を含むヘッダーを追加します(例:
x-forwarded-user: nick@example.com)。 - OpenClaw は、リクエストが 信頼されたプロキシの IP(
gateway.trustedProxiesで設定)から送信されたものであるかを確認します。 - OpenClaw は、設定されたヘッダーからユーザー ID を抽出します。
- すべての確認が取れれば、リクエストは承認されます。
Control UI のペアリング動作
Section titled “Control UI のペアリング動作”gateway.auth.mode = "trusted-proxy" が有効で、リクエストが信頼されたプロキシのチェックを通過した場合、Control UI の WebSocket セッションはデバイスのペアリング ID なしで接続できます。
これには以下の意味があります。
- このモードでは、ペアリングは Control UI アクセスの主要なゲートではなくなります。
- リバースプロキシの認証ポリシーと
allowUsersが、実質的なアクセス制御となります。 - Gateway への Ingress は、信頼されたプロキシの IP のみに制限してください(
gateway.trustedProxies+ ファイアウォール)。
{ 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) allowUsers: ["nick@example.com", "admin@company.org"], }, }, },}gateway.bind が loopback の場合は、gateway.trustedProxies にループバックプロキシアドレス(127.0.0.1、::1、または同等のループバック CIDR)を含めてください。
設定リファレンス
Section titled “設定リファレンス”| フィールド | 必須 | 説明 |
|---|---|---|
gateway.trustedProxies | はい | 信頼するプロキシの IP アドレスの配列。他の IP からのリクエストは拒否されます。 |
gateway.auth.mode | はい | "trusted-proxy" である必要があります。 |
gateway.auth.trustedProxy.userHeader | はい | 認証されたユーザー ID を含むヘッダー名。 |
gateway.auth.trustedProxy.requiredHeaders | いいえ | リクエストが信頼されるために存在する必要がある追加のヘッダー。 |
gateway.auth.trustedProxy.allowUsers | いいえ | ユーザー ID の許可リスト。空の場合は、認証されたすべてのユーザーを許可します。 |
TLS 終端と HSTS
Section titled “TLS 終端と HSTS”TLS 終端ポイントを 1 つに絞り、そこで HSTS を適用してください。
推奨パターン: プロキシでの TLS 終端
Section titled “推奨パターン: プロキシでの TLS 終端”リバースプロキシが https://control.example.com の HTTPS を処理する場合、そのドメインに対してプロキシ側で Strict-Transport-Security を設定します。
- インターネットに公開するデプロイに適しています。
- 証明書と HTTP のセキュリティ強化ポリシーを 1 か所にまとめられます。
- OpenClaw はプロキシの背後で loopback の HTTP のまま運用できます。
ヘッダー値の例:
Strict-Transport-Security: max-age=31536000; includeSubDomainsGateway での TLS 終端
Section titled “Gateway での TLS 終端”OpenClaw 自体が直接 HTTPS を提供する場合(TLS 終端プロキシがない場合)は、以下のように設定します。
{ gateway: { tls: { enabled: true }, http: { securityHeaders: { strictTransportSecurity: "max-age=31536000; includeSubDomains", }, }, },}strictTransportSecurity は文字列のヘッダー値を受け取るか、明示的に無効にする場合は false を指定します。
導入のガイダンス
Section titled “導入のガイダンス”- トラフィックを検証している間は、まず短い有効期限(例:
max-age=300)から始めてください。 - 十分に確信が持てた後にのみ、長期の有効期限(例:
max-age=31536000)に変更してください。 includeSubDomainsは、すべてのサブドメインが HTTPS に対応している場合にのみ追加してください。- preload は、ドメインセット全体でプリロードの要件を意図的に満たしている場合にのみ使用してください。
- loopback のみのローカル開発では HSTS のメリットはありません。
プロキシ設定の例
Section titled “プロキシ設定の例”Pomerium
Section titled “Pomerium”Pomerium は x-pomerium-claim-email(または他のクレームヘッダー)で ID を渡し、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: trueCaddy with OAuth
Section titled “Caddy with OAuth”caddy-security プラグインを使用した Caddy は、ユーザーを認証して ID ヘッダーを渡すことができます。
{ gateway: { bind: "lan", trustedProxies: ["127.0.0.1"], // Caddy's IP (if on same host) 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} }}nginx + oauth2-proxy
Section titled “nginx + oauth2-proxy”oauth2-proxy はユーザーを認証し、x-auth-request-email で ID を渡します。
{ 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";}Traefik with Forward Auth
Section titled “Traefik with Forward Auth”{ gateway: { bind: "lan", trustedProxies: ["172.17.0.1"], // Traefik コンテナの IP auth: { mode: "trusted-proxy", trustedProxy: { userHeader: "x-forwarded-user", }, }, },}トークン設定の混在
Section titled “トークン設定の混在”OpenClaw は、gateway.auth.token(または OPENCLAW_GATEWAY_TOKEN)と trusted-proxy モードが同時に有効になっている曖昧な設定を拒否します。トークン設定が混在していると、loopback リクエストが誤った認証パスでサイレントに認証されてしまう可能性があるためです。
起動時に mixed_trusted_proxy_token エラーが表示された場合は、以下のいずれかを行ってください。
- trusted-proxy モードを使用する場合は、共有トークンを削除する
- トークンベースの認証を意図している場合は、
gateway.auth.modeを"token"に切り替える
また、loopback の trusted-proxy 認証は「失敗時に閉じる(fail closed)」設計になっています。同一ホストからの呼び出し元は、サイレントに認証されるのではなく、信頼されたプロキシを介して設定済みの ID ヘッダーを提供する必要があります。
セキュリティ・チェックリスト
Section titled “セキュリティ・チェックリスト”trusted-proxy 認証を有効にする前に、以下を確認してください。
- プロキシが唯一の経路である: Gateway のポートが、プロキシ以外からのアクセスをファイアウォールで遮断している
- trustedProxies が最小限である: サブネット全体ではなく、実際のプロキシ IP のみを指定している
- プロキシがヘッダーを削除している: プロキシがクライアントからの
x-forwarded-*ヘッダーを(追加ではなく)上書きしている - TLS 終端: プロキシが TLS を処理し、ユーザーが HTTPS 経由で接続している
- allowUsers が設定されている(推奨): 認証された全員を許可するのではなく、既知のユーザーに制限している
- トークン設定が混在していない:
gateway.auth.tokenとgateway.auth.mode: "trusted-proxy"の両方を設定していない
セキュリティ監査
Section titled “セキュリティ監査”openclaw security audit を実行すると、trusted-proxy 認証は critical(重大)な深刻度の所見としてフラグが立てられます。これは意図的なものであり、セキュリティをプロキシ設定に委ねていることを再認識するためのリマインダーです。
監査では以下の項目がチェックされます。
trustedProxies設定の欠落userHeader設定の欠落allowUsersが空(認証されたすべてのユーザーを許可している状態)
トラブルシューティング
Section titled “トラブルシューティング””trusted_proxy_untrusted_source”
Section titled “”trusted_proxy_untrusted_source””リクエストが gateway.trustedProxies に含まれていない IP から送信されました。以下を確認してください。
- プロキシの IP は正しいですか?(Docker コンテナの IP は変わることがあります)
- プロキシの前にロードバランサーはありませんか?
docker inspectやkubectl get pods -o wideを使用して実際の IP を特定してください。
“trusted_proxy_user_missing”
Section titled ““trusted_proxy_user_missing””ユーザーヘッダーが空、または存在しません。以下を確認してください。
- プロキシが ID ヘッダーを渡すように設定されていますか?
- ヘッダー名は正しいですか?(大文字小文字は区別されませんが、スペルミスに注意してください)
- ユーザーは実際にプロキシで認証されていますか?
“trusted_proxy_missing_header_*”
Section titled ““trusted_proxy_missing_header_*””必須ヘッダーが存在しません。以下を確認してください。
- それらの特定のヘッダーに関するプロキシ設定
- チェーンのどこかでヘッダーが削除されていないか
”trusted_proxy_user_not_allowed”
Section titled “”trusted_proxy_user_not_allowed””ユーザーは認証されていますが、allowUsers に含まれていません。ユーザーを追加するか、許可リストを削除してください。
WebSocket が依然として失敗する
Section titled “WebSocket が依然として失敗する”プロキシが以下の条件を満たしているか確認してください。
- WebSocket アップグレード(
Upgrade: websocket,Connection: upgrade)をサポートしている - HTTP だけでなく、WebSocket アップグレードリクエストでも ID ヘッダーを渡している
- WebSocket 接続に対して別の認証パスが設定されていない
トークン認証からの移行
Section titled “トークン認証からの移行”トークン認証から trusted-proxy に移行する場合は、以下の手順で行ってください。
- ユーザーを認証し、ヘッダーを渡すようにプロキシを設定します。
- プロキシの設定を単体でテストします(ヘッダーを付けた curl など)。
- OpenClaw の設定を trusted-proxy 認証で更新します。
- Gateway を再起動します。
- Control UI からの WebSocket 接続をテストします。
openclaw security auditを実行し、所見を確認します。
- Security — セキュリティ完全ガイド
- Configuration — 設定リファレンス
- Remote Access — その他のリモートアクセスパターン
- Tailscale — tailnet 限定アクセスのためのよりシンプルな代替案
設定でお困りですか? AI Setup Assistant がお手伝いします。
次のステップ:
OpenClaw Expert
まだ解決しませんか?
このページで解決しない場合は、OpenClaw Expertに直接質問してください。