コンテンツにスキップ

認証と権限

Chorus はすべてのリクエストを認証して一つの統一された AuthContext に解決し、そのうえで、きめ細かな権限 セットに照らしてエージェントに何ができるかを制御します。本ページは、認証方式、エージェント API キーの 仕様、そして MCP ツールの可視性と REST アクセスの両方を駆動する権限モデルを説明します。

引用できる安定したアンカー:#統一された-authcontext、 #解決カスケード、#agent-api-key、 #権限モデル、#ロールプリセット、 #カスタム権限と有効な権限セット。

認証されたすべてのリクエストは、三つのコンテキスト種別のいずれかへ解決されます。マルチテナンシーは companyUuid を通じて強制されます。すべてのデータアクセスはその範囲に限定され、複数のワークスペースにまたがって 操作できるのはスーパー管理者だけです。

コンテキスト種別type主なフィールド生成元
UserusercompanyUuid、actorUuid、email、nameOIDC、Default Auth
AgentagentcompanyUuid、actorUuid、roles[](プリセット選択子)、permissions[](有効セット)、agentName、ownerUuidAPI キー
スーパー管理者super_adminemail(companyUuid なし)スーパー管理者セッション

エージェントの認可は、その permissions[]、つまりフラットな有効セットからすべて生じます。roles[] フィールドはプリセットの選択子にすぎず、認可の源ではありません。

単一の入口が、優先順位に従って各方式を順に試し、最初の成功で返します。

1. Authorization: Bearer <token>
├─ cho_… 接頭辞 → API key の検証 → Agent コンテキスト
├─ RS*/ES* JWT → OIDC トークンの検証 → User コンテキスト
└─ HS256 JWT → Chorus JWT の検証 → User コンテキスト
2. セッション Cookie
└─ user_session → User
3. OIDC Cookie(SSE / EventSource 用、Authorization ヘッダーなし)
└─ oidc_access_token cookie → User コンテキスト
4. 一致なし → 未認証

ステップ 1 のトークンは形状で分類されます。cho_ 接頭辞は API キーです。それ以外の 3 つの部分からなる JWT は、 ヘッダーのアルゴリズムが非対称(RS*/ES*)なら OIDC、HS256 なら Chorus の自己署名セッション トークンです。

NEXTAUTH_SECRET は Default Auth の user_session とスーパー管理者の admin_session JWT に署名します。スーパー管理者ルートは通常のユーザー認証とは別に admin_session を検証します。 OIDC トークンはプロバイダーの鍵で、エージェントの API キーは保存されたハッシュで検証します。 NEXTAUTH_SECRET を変更すると Chorus が署名したセッションは無効になりますが、API キーや OIDC トークンには影響しません。

npm ランチャーは生成した鍵を既定で ~/.chorus-data/.secret に保存し、Docker は /app/data/.secret を使います。どちらも環境変数の既知の公開プレースホルダーを無視し、保存済みの鍵が公開プレースホルダー なら起動を停止します。直接起動する場合は鍵を自分で設定してください。 0.18.1 での移行、永続化、レプリカの設定は Docker のセッション秘密鍵を参照してください。

エージェントは、すべての MCP と REST リクエストで bearer の API キーにより認証します。

Authorization: Bearer cho_<random>

その仕様は次のとおりです。

  • cho_ 接頭辞。 すべてのキーは cho_ で始まり、その後に base64url エンコードされたランダム バイトが続きます。解決カスケードはこの接頭辞でキーと JWT を見分けます。
  • 一度だけ表示。 生のキーは作成時にのみ返されます。そのとき控えてください。あとから取得はできません。
  • 保存時は SHA-256 ハッシュ。 保存されるのはキーの SHA-256 ハッシュだけです。データベースは生の値を 決して保持しないため、データベースのダンプから使える認証情報が漏れることはありません。
  • タイミング安全な比較。 検証は提示されたトークンをハッシュ化し、ハッシュどうしを定数時間で比較します。 そのため、先頭が何文字一致しても、不一致にかかる時間は同じです。
  • ローテーション、失効、有効期限。 キーは失効させたり、任意の有効期限を与えたりできます。失効した キーや期限切れのキーは検証に失敗します。ローテーションは、置き換えのキーを作り、古いものを失効させて 行います。権限はキーではなくエージェントに設定されているため、キーをローテーションしてもエージェントの 権限は保たれます。権限を変えるにはエージェントを編集します。

キーの作成、編集、ローテーション、失効は API 呼び出しではなく 設定 画面で行います。認証情報の作成 手順はエージェントのアクセスを準備する、編集と失効は エージェントと API キーを管理する、キーをエージェントに組み込む方法は エージェントランタイムを接続するをご覧ください。

以下は人間のユーザーとプラットフォーム管理者向けです。ここでは要点をまとめます。設定は運用ガイドが扱います。

人間のユーザー向けのエンタープライズ SSO で、スーパー管理者がワークスペースごとに設定します(issuer、client ID、 有効化トグル)。サインインは PKCE 付きの認可コードフローを使い、client secret は不要です。プロバイダーが リダイレクトで戻したあと、Chorus は (companyUuid, oidcSub) でユーザーを検索または作成し、HTTP-only の Cookie を設定します。

Cookie用途
oidc_access_tokenAPI 呼び出し用のアクセストークン(約 1 時間)
oidc_refresh_tokenサイレント更新用のリフレッシュトークン(約 30 日)
oidc_client_idトークン更新時に使う client ID
oidc_issuerJWKS 発見に使う issuer

アクセストークンはプロバイダーの JWKS(キャッシュ済み)に照らして検証され、edge middleware はリクエストが アプリに届く前に、期限切れ間近のアクセストークンを透過的に更新します。

OIDC のない開発・デモ向けの、単一のメール/パスワードによるサインインです。DEFAULT_USER と DEFAULT_PASSWORD の両方が設定されているときにのみ有効になります。

Terminal window
DEFAULT_USER="dev@example.local"
DEFAULT_PASSWORD="change-me"

サインイン時、Chorus はワークスペースとユーザーを自動プロビジョニングし、長寿命の自己署名 JWT を一つ、user_session Cookie に発行します。更新フローはなく、期限が切れたらユーザーが再度サインインします。本番では Default Auth を 有効にしないでください。

すべてのワークスペースにまたがるプラットフォームレベルの管理(ワークスペースの管理、ワークスペースごとの OIDC 設定)です。環境変数に、 メールと bcrypt のパスワードハッシュを設定します。

Terminal window
SUPER_ADMIN_EMAIL="admin@example.com"
SUPER_ADMIN_PASSWORD_HASH="$2b$10$…" # bcrypt ハッシュ

サインインに成功すると admin_session Cookie が設定されます。スーパー管理者コンテキストは companyUuid を持たないため、ワークスペースによる範囲の制限を受けません。テナントをまたいで読める唯一のコンテキストです。

エージェントの認可は権限ビットの集合です。エージェントが持つ有効セットが、あらゆる層で、それに何が できるかを決めます。

権限は {resource}:{action} と書きます。五つの資源に三つの動作を掛けて、15 個の可能なビットになります。

readwriteadmin
idea着想を閲覧着想の作成 / 担当 / 解除 / 更新;要件詳細化の実行着想のクローズ / 削除
proposal提案とドラフトを閲覧作成 / 提出 / 却下 / 撤回;ドラフトの管理;課題の一括作成;課題 DAG の管理;課題の割り当て提案の承認 / クローズ
document文書を閲覧文書の作成 / 更新文書の削除
task課題を閲覧担当 / 解除 / 提出 / 報告;受け入れ基準の自己確認課題の検証 / 再オープン / クローズ / 削除;受け入れ基準のマーク
projectプロジェクトとグループを閲覧プロジェクトとグループの作成 / 更新 / 削除;プロジェクトの移動予約済み(admin_agent に含まれるが、現時点でこれを必要とする操作はない)

各動作は通常まとめて付与されますが、どの動作も他の動作を含意しません。task:admin を付与しても task:read や task:write は含まれないため、各ビットを明示的に付与します。

三つの名前付きプリセットは、15 個のビットの固定された部分集合に展開されます。プリセットは近道であって、 独立した認可のしくみではありません。

プリセット個数展開される権限
developer_agent6*:read + task:write
pm_agent10*:read + idea:write + proposal:write + document:write + task:write + project:write
admin_agent15すべてのビット(*:read + *:write + *:admin)

展開すると、各プリセットは次のようになります。

developer_agent (6):
idea:read proposal:read document:read project:read task:read
task:write
pm_agent (10):
idea:read idea:write
proposal:read proposal:write
document:read document:write
task:read task:write
project:read project:write
admin_agent (15):
idea:read idea:write idea:admin
proposal:read proposal:write proposal:admin
document:read document:write document:admin
task:read task:write task:admin
project:read project:write project:admin

カスタム権限と有効な権限セット

Section titled “カスタム権限と有効な権限セット”

プリセットに加えて、エージェントはカスタムの権限ビットを持てます。有効セットは、展開されたプリセットと カスタムビットの和集合です。

effective = expand(preset) ∪ custom

順序は関係ありません。純粋な集合の和です。よくある形は次のとおりです。

  • 読み取り専用の監査者 — プリセットなし、カスタムは *:read のみ:すべてを閲覧できるが、何も変更できない。
  • 自己検証する開発者 — developer_agent + task:admin:管理者を待たずに課題を検証できる。
  • 承認権を持つ PM — pm_agent + proposal:admin:提案を直接承認できる。

有効セットがどうアクセスを制御するか

Section titled “有効セットがどうアクセスを制御するか”

同じ有効セットが、次の二つの経路でアクセスを決定します。

  • MCP ツールの可視性。 権限で制限される各 MCP ツールは、必要な権限をちょうど一つ宣言します。接続時、 ツールの必要な権限が有効セットに含まれる場合にのみ、そのツールはエージェントのサーバーに登録されます。 そうでなければ、そのツールは単にエージェントのツール一覧に現れません。共通ツール(discover / read / list / search / comment / session、そして chorus_create_tasks / chorus_update_task)は制限されず、 すべてのエージェントに現れます。
  • REST のアクセス制御。 権限で制限される各 REST ルートは、呼び出し元のエージェントが 特定の {resource}:{action} ビットを一つ持っているかを検査します。そのビットを欠くエージェントは 403 Missing permission を受け取ります。人間のユーザーはこのエージェント権限検査の対象ではなく (人間のアクセスはセッションを通じて検査されます)、スーパー管理者はすべての権限検査を素通りします。