セルフホストの Chorus を運用する
このガイドでは、デプロイ後のセルフホスト Chorus の運用について説明します。最初のユーザーのサインイン、認証の設定、安全なアップグレード、HTTPS の背後で重要になる Cookie とリバースプロキシの設定を扱います。デプロイの構築方法については、本番環境でデプロイまたは Docker でデプロイを参照してください。
初回アクセスをブートストラップする
Section titled “初回アクセスをブートストラップする”新規のデプロイでは、ID プロバイダーなしで管理対象のローカルアカウントを利用できます。下記のスーパー管理者の資格情報を設定し、ローカルアカウント用ワークスペースを作成して最初のワークスペース管理者を招待します。これは任意の Default Auth デモ・ブートストラップ経路とは別です。従来の経路を有効にするには、両方の変数を設定します。
DEFAULT_USER='admin@example.com' \DEFAULT_PASSWORD='choose-a-strong-password'両方の変数が設定されると、指定メールで Default Auth を使えます。最初のサインイン時に必要なユーザーとワークスペースが作成されますが、管理対象のローカルアカウントやローカルのワークスペース管理者ロールにはなりません。サインインはメールまたはユーザー名から始まり、複数のロールやワークスペースが一致した場合は目的のものを選びます。
組み込みログインを無効にする
Section titled “組み込みログインを無効にする”管理対象のローカルアカウントまたは OIDC と、スーパー管理者のサインインを確認してから、アプリ環境の DEFAULT_USER と DEFAULT_PASSWORD を削除し、再作成または再起動します。無効になるのは Default Auth だけで、管理対象のローカルアカウントのパスワードログインは残ります。発行済みセッションがこれだけで失効することもありません。
インストーラー管理の Compose スタックでは、変数展開時に基底ファイルが必要とするため、非公開 env ファイルの両値を空にしないでください。代わりに、次のコンテナ環境の上書きを非公開ディレクトリの oidc-only.yml に保存します。
services: app: environment: DEFAULT_USER: "" DEFAULT_PASSWORD: ""完全な dc コマンドの "$@" の前に -f "$HOME/.config/chorus-self-host/$PROJECT/oidc-only.yml" を追加し、dc config --quiet と dc up -d --wait --force-recreate app を実行します。その後の起動・更新でも必ずこの上書きを残してください。保存済みのローカルラッパーは oidc-only.yml を読み込みません。この手順の後は未変更のラッパーを使わず、目的のアプリイメージを用意して完全な Compose 呼び出しを使ってください。ローカルガイドのトンネル例は、このファイルがあれば読み込みます。
デプロイ側の認証を設定する
Section titled “デプロイ側の認証を設定する”Default Auth とスーパー管理者の資格情報はデプロイ環境から取得します。管理対象のローカルアカウントと OIDC はワークスペースごとにデータベースで設定され、新たなローカル認証用環境変数はありません。
スーパー管理者のブートストラップ
Section titled “スーパー管理者のブートストラップ”/admin のスーパー管理者パネルは、データベースのアカウントではなく、環境変数からブートストラップされます。
| 変数 | 説明 |
|---|---|
SUPER_ADMIN_EMAIL | /admin パネルに到達できるスーパー管理者アカウントのメール。 |
SUPER_ADMIN_PASSWORD_HASH | スーパー管理者パスワードの bcrypt ハッシュ(決して平文ではありません)。 |
ハッシュを生成し、SUPER_ADMIN_PASSWORD_HASH として渡します。
node -e "console.log(require('bcryptjs').hashSync('your-password', 10))"管理対象のローカルアカウント用ワークスペース
Section titled “管理対象のローカルアカウント用ワークスペース”スーパー管理者としてローカルアカウント用ワークスペースを作成し、最初のワークスペース管理者を招待します。ワンタイムリンクは安全な非公開経路で共有してください。Chorus は招待やパスワードリセットのメールを送信しません。受信者はパスワードを設定してから別途サインインします。招待とリセットのリンクは 24 時間有効で、再発行すると古いリンクは無効になります。以後のユーザー管理とリセットは有効なローカルのワークスペース管理者が行います。このロールはデプロイのスーパー管理者とは別で、DEFAULT_USER から付与されるものではありません。
同一ワークスペースでローカルアカウントと OIDC は併用できません。作成時に適切な種類を選びます。既存ワークスペースの認証方式の変更による変換はできません。データベースと永続的な NEXTAUTH_SECRET をバックアップしてください。ローカルパスワードは bcrypt ハッシュ(コスト 12)でデータベースに保存され、ローカルセッションはこの秘密鍵で署名されます。パスワードは 8 文字以上、UTF-8 で 72 バイト以下です。共有アクセスには HTTPS と COOKIE_SECURE=true を使います。操作手順は認証設定を参照してください。
上記の従来のファイル名 oidc-only.yml は Default Auth を無効にするだけです。管理対象のローカルアカウントでも使え、OIDC を有効にするものではありません。
シングルサインオン(OIDC)
Section titled “シングルサインオン(OIDC)”シングルサインオンは環境変数では設定しません。スーパー管理者が /admin パネルからワークスペースごとに OIDC を設定し、その設定はデータベースに保存されます。各ワークスペースは独自の発行者(issuer)URL とクライアント ID を持ち、両方を設定するとそのワークスペースで SSO が有効になります。Chorus は PKCE を使い、クライアントシークレット(client secret)を必要としません。デプロイレベルのブートストラップが担うのはスーパー管理者がサインインできるようにすることだけで、その後はスーパー管理者が管理パネルから各ワークスペースの SSO を設定します。デプロイ層で別途シークレットをプロビジョニングする必要はありません。
マイグレーションの実行と安全なアップグレード
Section titled “マイグレーションの実行と安全なアップグレード”Chorus は起動時に、保留中のデータベースマイグレーションを自動的に適用します(prisma migrate deploy)。マイグレーションを手作業で実行することはありません。新しいバージョンを起動すると、Web アプリケーションがリクエストの受け付けを始める前に、未適用のマイグレーションがすべて適用されます。
アップグレードするには:
- まずデータベースをバックアップします。 外部の PostgreSQL なら、バックアップを取ります。組み込みまたはボリューム管理のデータベースなら、データボリュームをバックアップします。
- 新しいバージョンをプルします。npm パッケージなら
npm update -g @chorus-aidlc/chorus、Docker デプロイなら新しいコンテナイメージをプルします。 - Chorus を再起動します。マイグレーションは起動時に自動的に適用され、その後アプリが起動します。
ラッパーが必要なオーバーライドをすべて読み込むローカルモードでは、bash ./default_deploy_local.sh を実行します(pull モードでは先に CHORUS_IMAGE を更新)。トンネルモードや oidc-only.yml などの独自設定では、目的のアプリイメージを準備して完全な Compose 呼び出しを使ってください。更新のためにインストーラーを再実行しないでください。PostgreSQL のメジャー更新は別途オフライン移行が必要です。ローカルマシンでセルフホストするを参照してください。
0.19.1 のアップグレード順序
Section titled “0.19.1 のアップグレード順序”0.19.1 には NULL 許容の列を追加するだけのマイグレーションが含まれるため、既存のデータは変更されません。エージェントデーモンを動かしている chorus CLI をアップグレードする 前に、Chorus サーバーをアップグレードしてください。古いデーモンも新しいサーバーに対してそのまま動作し、着想の作成とリサーチのリクエストを、すでに理解できる形式で受け取ります。新しいリクエスト形式を緊急にロールバックするには、CHORUS_DEDICATED_OPERATION_WRITES=false を設定してサーバーを再起動します。新しいリクエストは古い形式を使い、すでにキューにあるものも引き続き配信されます。必要なら CLI は別途ロールバックしてください。0.19.1 が作成したリクエストが保留中または実行中のあいだは、サーバーを 0.19.1 より古いバージョンに戻さないでください。また、新しい列を削除しないでください。
0.18.1 更新時のセッション秘密鍵
Section titled “0.18.1 更新時のセッション秘密鍵”署名用の秘密鍵もデータベースと一緒にバックアップし、値を変えずに維持してください。自動生成した鍵を保持するには、
外部 PostgreSQL を使う場合も Docker に永続的な /app/data ボリュームが必要です。npm ランチャーは
既定で ~/.chorus-data/.secret を使います。以前に公開プレースホルダーを使っていた場合、置き換え後の秘密鍵では、組み込みログインのユーザーと
スーパー管理者が再度サインインする必要があります。明示的に設定した安全な秘密鍵はそのまま維持されます。CDK の再デプロイでは
同じ nextAuthSecret を指定してください。省略すると synth ごとに新しい値が生成されます。
API キーと OIDC トークンはこの変更の影響を受けません。Docker でのセッション秘密鍵の扱いを参照してください。
Cookie とリバースプロキシ
Section titled “Cookie とリバースプロキシ”Chorus が TLS 終端やリバースプロキシの背後で動作するとき、重要になる設定が二つあります。
| 変数 | 設定値 | 場合 |
|---|---|---|
COOKIE_SECURE | true | サイトが HTTPS で提供される(TLS を終端するプロキシの背後を含む)。セキュア Cookie は暗号化された接続でのみ送信されます。 |
COOKIE_SECURE | false | 信頼できる内部の HTTP のみのネットワークに限る。この場合 Cookie は暗号化されていない HTTP で送信されるため、公衆インターネットでは決して使用しないでください。 |
NEXTAUTH_URL | 対外的なベース URL | Chorus がリバースプロキシの背後で動作する。リダイレクトやリンクが正しく解決されるよう、外部から見えるアドレス(例:https://chorus.example.com)に設定します。 |
共有認証レート制限
Section titled “共有認証レート制限”Redis の用途は二つに分かれます。Pub/Sub は SSE のライブ更新を伝播し、別のリクエスト用接続が共有認証カウンターを保存します。制限を統一するには全レプリカが同じ Redis を使う必要があります。SSE が正常でも認証カウンターの正常性は保証されません。
- 識別子の照合は 60 秒あたり 30 回、ローカルパスワードログインと招待・リセットの確定はそれぞれ 60 秒あたり 10 回です。これらは固定値で、環境変数では変更できません。
- 信頼できるクライアントアドレスがない場合、正規化した識別子、ローカルログインのワークスペースと識別子の組、または確定する資格情報トークンごとに制限します。全ユーザー共通の一つの枠ではありません。信頼できるアドレスがある場合、操作ごとにアドレスと識別子の組、およびアドレス単独の両方を制限し、識別子を変えてもアドレス制限を回避できません。
- 超過時は HTTP
429、RATE_LIMITED、秒単位のRetry-After(切り上げ、最小 1)を返します。すべてのログイン・API を保護するものではないため、認証経路全体にエッジ側の制限も適用してください。
設定とデフォルト:
- 空でない
REDIS_URLが優先されます。それ以外はREDIS_HOSTで TLS(rediss)を有効にし、REDIS_PORTは6379、REDIS_USERNAMEはdefault、REDIS_PASSWORDは任意です。ユーザー名はパスワード指定時に使われます。非 TLS Redis には明示的なredis://URL を使います。URL と host の両方が未設定なら Redis は未構成です。 AUTH_TRUST_PROXYは値が厳密にtrueの場合だけ有効です。AUTH_TRUST_PROXY_HOPSのデフォルトは1、有効範囲は 1~16 の整数です。X-Forwarded-Forの右から数えます。ヘッダーの欠落、長さ不足、不正なチェーンではアドレス制限だけが無効になり、識別子制限は残ります。追記・上書きを強制するプロキシチェーンで、直接・途中の迂回を防いだ場合にだけ信頼を有効にします。HTTPS だけでは十分ではありません。- 同梱 CDK の ALB モードは信頼
true、ホップ数1、CloudFront モードは信頼false、ホップ数2です。VPC トラフィックが CloudFront を迂回してプライベートオリジンへ到達できるため、その迂回を閉じるまで 2 ホップの信頼を有効にしないでください。
障害時の境界
Section titled “障害時の境界”Redis 未構成時はプロセス内カウンターを使い、警告を記録します。構成済み Redis が接続中、利用不能、または READONLY/OOM などでコマンドを拒否した場合、共有ではなくプロセスごとのメモリ内予備カウンターに切り替わります。コマンドのタイムアウトは 500 ms、未完了コマンドへの応答がないソケットは 2,000 ms 後に再接続されます。再接続時に未完了コマンドは再送されません。500 ms はコマンドごとの上限で、リクエスト全体の応答時間の保証ではありません。
auth-throttle ログで縮退と復旧を監視します。予備カウンターの警告は 60 秒に 1 回まで、初回接続時は 5 秒の猶予があります。メモリ内カウンターは合計 10,000 キーを上限とし、最も長く使われていないキーを削除するベストエフォート方式です。再起動でリセットされ、復旧時に Redis へ統合されません。通常の予備処理以外の予期しない制限バックエンドエラーは記録され、そのチェックは許可側に倒れます(fail-open)。Redis 障害だけで全サインインを意図的に拒否するわけではありません。
アカウント検証は別で、失敗時は拒否します(fail-closed)。無効化・削除されたローカルユーザー、非互換のワークスペース認証方式、古いセッションバージョンは認可されません。アカウント状態の読み取り失敗もアクセス許可にはなりません。予備カウンターはインスタンス間 SSE を復旧しません。ローカルイベントが動いていてもインスタンス間更新は停止し得ます。Redis 復旧後は認証カウンターとライブ更新の両方を確認してください。