OpenClawの信頼済みプロキシ認証
Gatewayの認証をPomerium、Caddy、oauth2-proxy付きのnginx、Traefikに委任する方法、評価順のランタイムルール、ループバックとローカルインターフェースのガード、アイデンティティによるスコープ付与、デバイスの自動承認、セキュリティチェックリスト
信頼済みプロキシ認証は、アイデンティティを認識するプロキシの背後に置かれたgatewayのためのモードです。プロキシが本人を認証し、そのアイデンティティを載せたヘッダーを追加し、gatewayはそのヘッダーを信頼します。ただし、信頼するのはプロキシから届いた場合だけです。ドキュメントは、設定を誤るとgatewayが露出するという警告から始まり、ページの大部分はその信頼を安全にするためのチェックの一覧になっています。以下に、gatewayが評価する順序で紹介します。
使う場面と仕組み
- Pomerium、OAuth付きのCaddy、oauth2-proxy付きのnginx、Traefikのforward authの背後で使うほか、プロキシが唯一の経路であるコンテナ環境や、ブラウザがハンドシェイクでトークンを渡せないためにWebSocketのunauthorizedエラーが発生する場合にも使います。一方、プロキシがTLSを終端するだけの場合、プロキシを迂回する経路が一つでもある場合、プロキシが転送ヘッダーを除去するか確信が持てない場合、tailnetとループバックの組み合わせのほうが簡単な個人の単一ユーザーアクセスの場合には使いません。
- 流れは次のとおりです。プロキシがユーザーを認証し、forwarded-userヘッダーなどのアイデンティティヘッダーを追加します。gatewayはリクエストが信頼済みプロキシのアドレスから来たことを検証し、必須ヘッダーとユーザーのアイデンティティを読み取り、ユーザー許可リストが設定されている場合はそこにユーザーが含まれていれば認可します。設定では、ローカルネットワークにバインドし、プロキシのアドレスまたはアドレス範囲だけを登録し、認証モード、ユーザーヘッダー、任意の必須ヘッダー、任意のユーザー許可リストを指定します。ループバックはデフォルトでオフ、デバイスの自動承認もデフォルトでオフです。
- ランタイムルールを順に示します。プロキシ経由に見えるトラフィックはgateway認証の前に帰属が判定され、非ループバックのクライアントに解決されるクライアントアドレスヘッダーを伴って信頼済みプロキシから届く必要があります。そうでなければ、gateway認証を使うルートはプロキシの帰属情報がないとして拒否します。プロキシはforwarded-forチェーンを安全に上書きする必要があり、real-addressヘッダーはそのフォールバックが有効な場合にのみ受け入れられます。ループバックの送信元は、オプトインがtrueであり、かつループバックも信頼済みプロキシとして登録されている場合を除き、拒否されます。ホスト自身のインターフェースアドレスのいずれかに一致する送信元はなりすまし対策として拒否され、インターフェースの検出に失敗した場合も拒否されます。そのうえで、必須ヘッダーとユーザーヘッダーが存在して空でないこと、ユーザー許可リストにユーザーが含まれていることが求められます。
- ループバックのリクエストに転送ヘッダーの痕跡があると、ローカル直接接続のパスワードフォールバックとデバイスアイデンティティによるゲーティングの対象から外れ、しかもtrusted-proxy認証にも失敗します。プロキシを経由しない内部クライアントはgatewayのパスワードを使い、statusコマンドはURLを上書きしなくてもそれを自動的に選択します。信頼済みプロキシのリストはアドレス範囲をそのままの形でもマップされた形でも受け付けますが、すべてを包含するマップ形式のプレフィックスであっても、ループバックにはループバックのオプトインが必要です。
Gatewayトークンは、プロキシ認証の代わりにはなりません。
付与、自動承認、スコープヘッダー
アイデンティティスコープは、選ばれた検証済みユーザーに、デバイスの付与範囲を広げることなくセッション限定のスコープを与えます。キーはプロキシのアイデンティティまたはtailnetのログインで、メールアドレスは大文字と小文字を区別せずに照合されます。付与はデバイスで認可されたスコープと合算されたうえで明示的なスコープヘッダーによって上限が設けられ、トークン、パスワード、認証なしの接続には決して付与されません。デバイスの自動承認はデフォルトでオフで、新しいブラウザとネイティブのオペレーターデバイス、および同じキーでのスコープ拡張について、プロキシのアイデンティティを承認の境界として使います。対象になるのは、空でないアイデンティティを持ち許可リストを通過したtrusted-proxy接続だけで、nodeロールの接続とロールの昇格は決して対象になりません。要求されたスコープは設定されたリスト(未設定の場合はread、write、approvals、questions)との共通部分に絞られて広げられることはなく、プロキシのスコープヘッダーは永続的な付与にも上限を設けます。また、リストにadminを含めると、すべてのプロキシユーザーがフル管理者権限のデバイスを受け取れるようになり、セキュリティ監査はこれをcriticalとして報告し、gatewayは起動時に警告します。デバイスを持たないコントロールインターフェースのセッションはスコープを自己申告できず、そのリストは消去されて、一致するアイデンティティの付与が適用されます。接続に成功した後でスコープ不足により失敗する場合は、再読み込みしてブラウザにデバイスアイデンティティをペアリングさせる必要があります。スコープヘッダーは、存在する場合はスコープを宣言し、存在するが空の場合は何も宣言せず、存在しない場合はデフォルトのオペレーターセットにフォールバックします。一方、gateway認証を使うプラグインのルートはwriteのみにフォールバックします。
TLS、トークンの混在、監査
- TLSの終端は一か所だけにし、strict transportヘッダーもそこで設定します。インターネットに公開するデプロイではプロキシで終端してその背後のgatewayをループバックに置き、gateway自身がHTTPSを提供する場合はTLSを有効にしたgatewayでstrict transport securityヘッダーとともに終端します。max ageは短い値から始めて確信が持ててから引き上げ、サブドメインのフラグはすべてのサブドメインの準備が整ってから追加し、ループバックのみの開発では設定を省きます。
- 共有トークンも設定されている場合、起動時にtrusted-proxy認証は拒否されます。トークンがあると、同じホスト上の呼び出し元が、プロキシで検証されたアイデンティティとは別の経路で認証できてしまうためです。トークンを削除するかモードを切り替えてください。また、ループバックのアイデンティティヘッダーは引き続きフェイルクローズになること、トークンへのフォールバックは意図的にサポートされていないことも覚えておいてください。
- セキュリティ監査は設計上このモードをcriticalとして報告し、信頼済みプロキシのリストの欠落、ユーザーヘッダーの欠落、空のユーザー許可リスト、ループバックのオプトインの有効化、デバイスの自動承認の有効化をチェックします。チェックリストではさらに、プロキシが唯一の経路であること、信頼済みリストが最小限であること、プロキシが転送ヘッダーを上書きしてforwarded-forチェーンを再構築すること、非ループバックのコントロールインターフェースでは許可するオリジンを明示していること、ローカルのパスワードフォールバックがある場合はファイアウォールの内側で非公開に保たれていることを確認します。
これらの付与が反映されるスコープモデルについてはOpenClawのオペレータースコープを、tailnet内に限定したアクセス向けのより簡単な代替手段についてはTailscale上のOpenClawをご覧ください。
拒否コードの読み方
トラブルシューティングのセクションは、拒否の種類ごとに原因を対応付けています。信頼されていない送信元は、リクエストが登録済みのプロキシアドレスから来なかったことを意味し、このアドレスはコンテナが再起動すると変わります。ループバックの送信元は、意図的なオプトインなしに同じホスト上でプロキシが動いていることを意味します。ローカルインターフェースの送信元は、gatewayホスト上のプロセスがアイデンティティヘッダーを直接送っているか、プロキシがホストのネットワーク名前空間を共有していることを意味します。ユーザーの欠落は、ヘッダーが存在しないか名前が間違っていることを意味します。許可されていないユーザーは、アカウントは認証済みでも許可リストに含まれていないことを意味し、ドキュメントは回避策として許可リストを削除しないよう述べています。許可されていないオリジンは、ブラウザのオリジンがコントロールインターフェースのチェックを通過しなかったことを意味します。プロキシ認証が必要だというメッセージはアイデンティティが拒否されたことを示すもので、ネットワーク障害ではありません。対処法は、ブラウザからヘッダーを送ることではなく、プロキシでログインすることです。トークン認証からの移行は6ステップで、プロキシを設定し、単独でテストし、gatewayの設定を更新し、再起動し、コントロールインターフェースからWebSocketをテストし、監査を実行します。ほかのリモートアクセスのパターンの比較はOpenClawのリモートアクセスで、自動承認が置き換えるデバイスのフローはOpenClawのペアリングで解説しています。
Dialiでは
Dialiでは、各顧客のgatewayにはプラットフォームのイングレスを通じて到達し、ランタイムの設定はダッシュボードから生成されてリリースのたびに置き換えられます。そのため、このモードを顧客が手作業で組み立てる必要はありません。ホスト型のアシスタントについてはDialiのマネージドOpenClawホスティングを、各ランタイムを囲む境界についてはDialiのセキュリティをご覧ください。
- ヘッダーは登録済みのプロキシアドレスから届いた場合にのみ信頼します。
- ループバックと自身のインターフェースからの送信元はフェイルクローズになります。
- スコープヘッダーは絞り込み、アイデンティティによる付与はセッション限定で追加します。
読むだけでなく、作ってみましょう
エージェントを設定してチャネルを選べば、いつも開いているアプリの中でエージェントが働き始めます。
