ドキュメント/ 運用

セキュリティと本番運用

本番運用する前に、このページを最初から最後まで確認してください。多くの事故は二つの原因によって発生します:キーのバックアップがないこと、またはサービスがインターネットに公開されていることです。

2つのキー§

GPT-Load には用途がまったく異なる2つのキーがあります:

キー機能紛失した場合はどうなるか
AUTH_KEY管理画面にログイン交換するだけで、データには影響しません
ENCRYPTION_KEYアップストリームの認証情報を暗号化して保存暗号化済みの認証情報は永久に復元できません

2つのキーは.envで明示的に設定できます。未設定の場合は初回起動時にauth.keyとencryption.keyが生成され、データディレクトリへ保存されます。

主キーのローテーションをサポートしない

このリリースはENCRYPTION_KEYの変更には対応していません。キーを変更または紛失すると、保存済みチャネル認証情報を復号できず、すべて再入力する必要があります。つまり、この鍵はデータベースと同等に扱われなければなりません。

バックアップ§

データベースと暗号化キーは必ずセットでバックアップしてください。自動生成されたauth.keyとencryption.keyはデータディレクトリにあります。明示的に設定したAUTH_KEYとENCRYPTION_KEYは、元の環境変数またはシークレット管理サービスから別途バックアップします。

Compose を停止してバックアップする

SQLite は WAL を使用するため、サービスの稼働中にデータボリュームをそのままアーカイブできません。Compose の実際のボリューム名もプロジェクト名によって変わるため、gpt-load-dataという固定値にしないでください。データベースとバックアップに記載された手順をすべて実行してください。

バックアップファイル自体に復号可能な認証情報が含まれています。機密データとして扱い、暗号化して保管してください。公開のクラウドストレージやリポジトリには置かないでください。

データベースドライバーの変更やサーバー移行前にデータベースとバックアップを参照してください。

ネットワーク境界§

サービスは127.0.0.1だけをリッスンするため、ローカルマシンからだけアクセスできます。これは意図したデフォルトです。管理画面を公開すると、AUTH_KEYを取得した人がすべてのアップストリーム認証情報を表示できます。

手間を省くために直接公開しないでください

HOSTを0.0.0.0へ変更し、ポートをパブリック IP に直接公開する方法は一般的ですが危険です。正しい方法はリバースプロキシを経由し、TLSとアクセス制御を追加することです。

リモートアクセスは、リスクの低い順に次から選びます:

  1. SSH ポートフォワーディング — 最も安全で、サービス設定の変更は不要です:
リモートサービスをローカルにマッピングする
ssh -L 3001:127.0.0.1:3001 user@your-server
# それからこのマシンのブラウザで http://127.0.0.1:3001 を開く
  1. 内部ネットワーク / VPN — 管理されたネットワーク内だけに公開します。
  2. 逆プロキシ + TLS + アクセス制御 — インターネットからのアクセスが本当に必要な場合だけ使います。次の節を参照してください。

逆プロキシ§

Nginx、Caddy などのリバースプロキシを前段に置き、少なくともHTTPSを有効にし、アクセス元を制限し、管理画面とデータ面を同時に無防備にしないこと。

Nginx 例:管理画面のアクセス制限
server {
    listen 443 ssl;
    server_name gateway.example.com;

    # 証明書設定は省略

    # 管理面:信頼できるソースのみ許可
    location /api/ {
        allow 203.0.113.0/24;
        deny all;
        proxy_pass http://127.0.0.1:3001;
    }

    # データ面:必要に応じて開放、ストリームレスポンスはバッファを閉じることに注意
    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_buffering off;
        proxy_read_timeout 600s;
    }
}

proxy_buffering offと十分に長い読み取りタイムアウトが必要です。プロキシがストリーミング応答をバッファすると、クライアントは逐次出力を受け取れません。

既定のクライアント IP は接続元です。リバースプロキシ配下で実際の IP が必要なら、CLIENT_IP_HEADER を設定し、TRUSTED_PROXIES を実際のプロキシの IP/CIDR に限定して再起動してください。クライアントが送ったヘッダーを直接信頼しないでください。このアドレスはログ、IP 制限、セキュリティイベントで共通です。

信頼するプロキシ一覧を指定すると、X-Forwarded-For を右から左へ確認し、信頼するプロキシを除いた最初のアドレスを採用します。すべて信頼済みなら最左端です。ヘッダーが欠落または無効なら接続元に戻ります。TRUSTED_PROXIES が空欄の場合は指定ヘッダーを直接信頼します(X-Forwarded-For は最左端)。入口プロキシによる上書きや無害化が保証される環境に限って使用してください。

ファイル権限§

管理対象のデータディレクトリは、実行アイデンティティに適したアクセス権へ制限されます。起動時に自動処理され、通常は手動操作不要です:

  • データディレクトリ:0700(所有者だけが読み書き・実行可能)。
  • データベースファイルと2つのキー:0600(所有者だけが読み書き可能)。
  • Windows の前面実行では現在のユーザー ACL を使い、インストーラー管理サービスではサービス SID とローカル Administrators ACL を使います

ディレクトリ所有者やリンク種別を確認できない場合、プログラムはチェックを弱めず、起動を拒否します。権限が不明な場所へ認証情報を書き込まないための意図的な動作です。

保護すべき機密情報§

業務リクエストの送信前に機密テキストを隠したり、ルールで転送可否を判定したりするには、以下の 2 つを設定できます。このページで説明するアクセス制御やバックアップの代わりにはなりません。

  • 2つのキー — リポジトリへコミットしたり、Issue やグループチャットへ貼り付けたりしないでください。
  • バックアップファイル — 復号可能な認証情報が含まれます。
  • スクリーンショット — 管理画面にはアカウントのメールアドレスやキーの末尾が写る場合があります。共有前にマスクしてください。
  • AccessKey — 失効できますが、漏洩中に発生した使用量には実際のコストがかかります。

セキュリティ問題はSECURITY.mdの手順で非公開に報告し、公開 issue を開かないでください。

元のリクエスト本文記録は既定でオフです。有効にすると秘匿化前のクライアント内容が保存され、個人情報、パスワード、キー、営業秘密を含む可能性があります。秘匿化ルールはこの記録を保護しません。管理者と該当キーの所持者が閲覧できるため、データベースとバックアップも機密情報として保護してください。記録の権限を得て利用者に通知したうえで有効にし、終了後は無効にします。保存済みの記録は引き続きログ保持期間に従います。

本番運用チェックリスト§

すべて確認してから本番トラフィックを流してください:

  • キー — AUTH_KEYとENCRYPTION_KEYを明示的に設定するか、自動生成値がバックアップ済みであることを確認します。
  • バックアップ — データベースとencryption.keyを一緒にバックアップし、復元できることを検証済みです。
  • ネットワーク — サービスを0.0.0.0へ直接バインドしてインターネットへ公開しません。SSH 転送、プライベートネットワーク、または TLS 対応リバースプロキシを使います。
  • 管理画面 — /apiはアクセス元を制限し、インターネットへ公開しません。
  • AccessKey — アプリケーションごとに発行し、適切なレート制限とコスト上限を設定します。
  • 監視 — 健全性とリクエストログの確認場所を把握します。監視とトラブルシュートを参照してください。
  • 境界認知 — コストは見積値であり、2.0 は単一インスタンス向けであることを理解します。
単一インスタンスでの運用

2.0 が正しさを保証するのは単一のアプリケーションインスタンスだけで、インスタンス間では状態を共有しません。複数インスタンスをロードバランサー配下に置かないでください。スケジューリング、クールダウン、レート制限が個別に計算されます。規模を拡大する場合は、ワークロードごとに独立したデプロイへ分割します。

2.0 の既知の制限をすべて確認 →

セキュリティと本番運用 - GPT-Load