フェデレーションルールは、どの検証済みワークロード ID が特定の ChatGPT ユーザーまたはサービスアカウントとして動作できるかを定めます。OpenAI が評価するのは、Codex プロセスが指定したルールだけです。一致するルールを探してすべてのルールを調べることはありません。
各ルールの対象となるプリンシパルは 1 つですが、受け入れる上流の ID は 1 つでも複数でもかまいません。1 つのルールで複数のサブジェクトを受け入れるには、サブジェクトの末尾にワイルドカードを付けて前方一致で照合するか、CEL 条件を使います。同じプリンシパルに対して複数のルールを作成することもできます。
ルールの構成
| 構成要素 | 役割 |
|---|---|
| プロバイダー | OpenAI が信頼する発行者と署名鍵を定めます。 |
| ワークスペース | ルールによるアクセス先を、管理対象の ChatGPT ワークスペース 1 つに限定します。 |
| プリンシパル | そのワークスペースにすでに存在するユーザーまたはサービスアカウントを 1 つ指定します。 |
| ID チェック | ルールを利用できる検証済み ID トークンを限定します。 |
| スコープ | 必要に応じて、既存の Codex OAuth スコープを絞り込みます。 |
| アクセストークンの有効期間 | OpenAI アクセストークンの有効期間を 60~3,600 秒の範囲で制限します。 |
トークン交換の前に、プリンシパルが存在し、対象ワークスペースのメンバーになっている必要があります。ワークロードの接続時に、ルールがユーザーやサービスアカウントを作成したり、ワークスペースにメンバーを追加したりすることはありません。
ID チェックの組み合わせ
ルールでは次のチェックを使用できます。
| チェック | 動作 | 用途 |
|---|---|---|
| サブジェクト | sub の値を完全一致で照合するか、末尾に * を 1 つ付けて前方一致で照合します。 |
単一のワークロード ID、または管理されたサブジェクト名前空間の照合 |
| 許可するオーディエンス | オーディエンスを文字列で 1~32 個指定します。トークンにはそのうち少なくとも 1 つが含まれている必要があります。 | OpenAI 専用に発行されたトークンの照合 |
| クレームの完全一致 | トップレベルのクレームを最大 32 個まで指定し、スカラー値の完全一致を確認します。 | 値が安定している文字列、数値、真偽値、または null の照合 |
| CEL 条件 | assertion という名前の検証済みクレームマップに対して、真偽値を返す式を評価します。 |
リスト、ネストされたクレーム、または複数の許可値の照合 |
サブジェクト、クレームの完全一致、CEL 条件のうち、少なくとも 1 つを設定してください。許可するオーディエンスだけではワークロードを特定できません。複数の種類のチェックを設定した場合は、すべてに合格する必要があります。
最初にプロバイダーの検証が行われます。発行者、署名、有効期限、アサーションの有効期間、リプレイに関するプロバイダーのチェックや、プロバイダーレベルの CEL チェックをルールで上書きすることはできません。
サブジェクトの照合
固定の sub 値 1 つでワークロードを特定できる場合は、サブジェクトを完全一致で照合してください。
repo:example-company/payments:environment:production
末尾に * を 1 つ付けると、前方一致で照合します。
system:serviceaccount:production:codex-*
ワイルドカードは最後の文字にし、その前に空でないプレフィックスを指定する必要があります。OpenAI は *、repo:*:production、repo/*/main を受け付けません。
より安定したクレームで特権を持つワークロードを識別できる場合は、一致範囲の広いプレフィックスを使わないでください。たとえば GitHub 用のルールでは、ある組織が所有するすべてのリポジトリを対象にせず、リポジトリ、ワークフローファイル、ref、保護された環境のいずれかを指定して照合してください。
クレームの完全一致
完全一致チェックでは、トップレベルの JWT クレームを型変換せずに比較します。文字列は同じ文字列とだけ、真偽値は同じ真偽値とだけ一致します。数値は数値として値が等しければ一致します。完全一致で照合する値にリストやオブジェクトは指定できません。
設定例を示します。
{
"repository": "example-company/payments",
"ref": "refs/heads/main",
"environment": "production"
}
完全一致用のクレームマップに sub を含めないでください。サブジェクトのフィールドまたは CEL を使ってください。プロバイダーのネストされたクレームを照合する場合や、値がリストに含まれるかどうかを確認する場合は、CEL を使います。
CEL 条件
CEL 条件は、検証済みの JWT クレームマップ全体を assertion として受け取り、true または false を返す必要があります。OpenAI では、ルール評価の動作を予測しやすくするため、使用できる CEL の機能を限定しています。
1 つのルールで複数のサブジェクトを完全一致で許可する例です。
assertion.sub in [
"repo:example-company/payments:environment:production",
"repo:example-company/billing:environment:production"
]
特定のリポジトリに一致し、かつ 2 つの ref のいずれかに一致することを求める例です。
assertion.repository == "example-company/payments" &&
assertion.ref in ["refs/heads/main", "refs/heads/release"]
ネストされたクレームや省略可能なクレームを読み取る例です。
has(assertion.environment) &&
assertion.environment == "production"
使用できるヘルパーには has、size、contains、startsWith、endsWith があります。正規表現による照合、all や exists などのコレクションを反復処理するマクロ、任意の関数、assertion 以外の識別子は使用できません。式は短く保ち、同じポリシーを完全一致チェックで表せる場合はそちらを使ってください。
クレームが存在しない場合、未対応の操作を使った場合、結果が真偽値でない場合、または評価エラーが発生した場合は、トークン交換が拒否されます。
オーディエンスの照合
プロバイダーでは、想定するオーディエンスを 1 つ設定できます。代わりに、ルールで許可するオーディエンスを 1 つ以上設定することもできます。ルールにオーディエンスのリストがある場合、トークンの aud クレームに含まれる値のうち、少なくとも 1 つがそのリストに含まれている必要があります。
プロバイダーが対応している場合は、OpenAI 専用のオーディエンスを使ってください。SPIFFE JWT-SVID のルールでは、許可するオーディエンスの設定が必須です。OIDC のルールでも、プロバイダーレベルでオーディエンスを定義していない場合は設定が必要です。
オーディエンスの照合と ID チェックの両方を満たす必要があります。オーディエンスが一致しても、サブジェクト、クレームの完全一致、CEL 条件のいずれかのチェックに合格しなければ、トークン交換はできません。
ルールとプリンシパルの対応関係
1 つのルールに対応するプリンシパルは必ず 1 つです。
many accepted external identities -> one federation rule -> one OpenAI principal
この仕組みにより、ワークロードのレプリカ、ジョブ、または許可されたサブジェクトが、同じユーザーまたはサービスアカウントとして動作できます。1 つのルール内で、クレームに応じて異なるプリンシパルを選択することはできません。ワークロードごとに異なるプリンシパル、ワークスペース、スコープ、またはトークンの有効期間が必要な場合は、ルールを分けてください。
複数のルールで同じプリンシパルを対象にできます。ワークロードごとにライフサイクルを個別に管理したい場合や、監査時にどのワークロードによる操作かを明確にしたい場合は、ルールを分けてください。
スコープと認可
ルールでは、発行するアクセストークンの OAuth スコープを絞り込めます。対象のプリンシパルやワークスペースにない権限を付与することはできません。
スコープを省略すると、OpenAI は Codex の標準スコープである openid、profile、email、および Codex のローカルアクセスを使用します。管理 API でスコープを設定する場合は、chatgpt.workspace.feature.allow-codex-local-access.access を含めてください。指定できるのは、この 4 つの値だけです。
まず、必要最小限の権限を持つプリンシパルを選び、ワークスペースの権限も必要最小限にしてください。ルールのスコープは、認可範囲を決める主な手段ではなく、その範囲をさらに絞り込むために使ってください。
トークンの有効期間
OpenAI アクセストークンの有効期間は 60~3,600 秒の範囲で設定してください。OpenAI は次のうち短い方を使用します。
- 上流の ID トークンの有効期限までの残り時間
- ルールに設定したアクセストークンの有効期間
有効期間を短くすると、ポリシー変更後に発行済みトークンが有効なまま残る時間を短縮できますが、トークン交換の頻度は高くなります。ワークロードの要件に応じてこのバランスを調整する必要がなければ、まずは 10 分を目安に設定してください。
リプレイ防止
プロバイダーレベルのリプレイ防止には、JWT の jti クレームを使います。管理者が「アサーションのリプレイを防止」を有効にし、トークンの jti が空でない場合、OpenAI はアサーションの有効期限が切れるまで、そのプロバイダーで同じ jti を 1 回だけ受け付けます。
ワークロードは、トークン交換のたびに、新しい jti を持つ新しいアサーションを事前に取得する必要があります。交換結果が不明で再試行する場合も同様です。jti がないアサーションも使用できますが、リプレイ防止の対象にはなりません。jti が空文字列、null、または文字列以外の値の場合は、検証に失敗します。
変更、無効化、アーカイブ
ID チェック、スコープ、トークンの有効期間に対する通常の変更は、変更後のトークン交換に適用されます。変更前に発行されたアクセストークンは、発行時に定められた TTL が切れるまで有効な場合があります。
ルールまたはプロバイダーを無効にすると、そのルールまたはプロバイダーを使った新たなトークン交換ができなくなり、それを通じて発行された OpenAI アクセストークンは失効します。アーカイブした場合も同様ですが、アーカイブは取り消せません。発行者や JWKS の設定など、プロバイダーの信頼設定を変更すると、新しい設定が有効になる前に発行済みトークンが失効します。
緊急停止や一時停止には無効化を使ってください。リソースをアーカイブするのは、今後使う必要がなくなった場合だけにしてください。
制限
| リソース | 制限 |
|---|---|
| 組織あたりの未アーカイブのプロバイダー数 | 50 |
| プロバイダーあたりの未アーカイブのルール数 | 50 |
| ルールごとに完全一致で照合するクレーム数 | 32 |
| ルールごとに許可するオーディエンス数 | 重複を除いて 32 個 |
| サブジェクトの長さ | 4,096 バイト |
| 完全一致用のクレームマップまたは CEL 条件のサイズ | 16 KiB |
| アクセストークンの有効期間 | 60~3,600 秒 |
発行者、鍵、リプレイ防止、またはライフサイクルを個別に管理する必要がある場合は、信頼境界ごとにプロバイダーを作成してください。同じ信頼設定を使うワークロードでも、必要なプリンシパルやアクセスポリシーが異なる場合は、同じプロバイダー内に別々のルールを作成してください。