For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション
Theme

AWS 向けワークロード ID フェデレーションの設定

AWS をワークロード ID プロバイダーとして利用する方法は 2 つあります。

  • AWS のアウトバウンド ID フェデレーション: GetWebIdentityToken で取得した AWS STS 発行の OIDC JWT を、有効期間の短い OpenAI アクセストークンと交換します。
  • Amazon EKS: Amazon EKS の Pod に投影されたサービスアカウントトークンを、有効期間の短い OpenAI アクセストークンと交換します。

OpenAI は、AWS がアウトバウンド ID フェデレーションで発行する OIDC JWT と、Amazon EKS が発行して Kubernetes の Pod に投影するサービスアカウントトークンに対応しています。SigV4 で署名したリクエストや AWS STS の一時アクセスキー認証情報は、ワークロード ID フェデレーションのサブジェクトトークンとして使用できません。

AWS のアウトバウンド ID フェデレーション

AWS のアウトバウンド ID フェデレーションを使うと、AWS プリンシパルは AWS STS に署名済み OIDC JWT をリクエストし、そのトークンを外部サービスに提示できます。OpenAI のワークロード ID フェデレーションでは、AWS が発行した JWT をサブジェクトトークンとして使用します。OpenAI はこのトークンを検証してから OpenAI アクセストークンを発行します。

AWS のアウトバウンド ID フェデレーションの設定

トークンを発行する AWS アカウントでアウトバウンド ID フェデレーションを有効にします。設定手順の詳細は、AWS ガイドのアウトバウンド ID フェデレーションの開始手順を参照してください。

aws iam enable-outbound-web-identity-federation

AWS が返すアカウント固有の発行者 URL を控えておきます。この URL は、OpenAI のワークロード ID プロバイダーに発行者として設定します。AWS が発行するトークンの iss クレームと一致している必要があります。

AWS STS の GetWebIdentityToken API は、STS のグローバルエンドポイントでは利用できません。リージョン別の STS エンドポイントを使用するように AWS CLI または SDK を設定してください。

ワークロードに sts:GetWebIdentityToken を呼び出す権限を付与します。AWS プリンシパルが OpenAI 向けのトークンのみを発行できるように、IAM でオーディエンスとトークンの最大有効期間を制限します。次の例では、オーディエンスが https://api.openai.com/v1 で、有効期間が 300 秒以内のトークンを許可します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:GetWebIdentityToken",
      "Resource": "*",
      "Condition": {
        "ForAllValues:StringEquals": {
          "sts:IdentityTokenAudience": "https://api.openai.com/v1"
        },
        "NumericLessThanEquals": {
          "sts:DurationSeconds": 300
        }
      }
    }
  ]
}

OpenAI のワークロード ID プロバイダーに設定するオーディエンスと同じ値を指定して、AWS に OIDC トークンをリクエストします。署名アルゴリズムには ES384 を使用してください。ただし、RS256 との互換性が必要な環境は例外です。

TOKEN=$(aws sts get-web-identity-token \
  --audience "https://api.openai.com/v1" \
  --signing-algorithm ES384 \
  --duration-seconds 300 \
  --tags Key=environment,Value=production \
         Key=workload,Value=batch-ingest \
  --query "WebIdentityToken" \
  --output text)
export TOKEN

AWS が発行したトークンの確認

ワークロード ID フェデレーションを設定する前に、AWS が発行したトークンを環境変数 TOKEN にエクスポートし、次のスクリプトをローカルで実行してクレームを確認します。

const parts = process.env.TOKEN?.split(".") ?? [];
if (parts.length !== 3) {
  throw new Error("Expected a compact JWT with three segments");
}
if (!/^[A-Za-z0-9_-]+$/.test(parts[1]) || parts[1].length % 4 === 1) {
  throw new Error("JWT payload is not valid Base64URL");
}

const bytes = Buffer.from(parts[1], "base64url");
if (bytes.toString("base64url") !== parts[1]) {
  throw new Error("JWT payload is not valid Base64URL");
}
const decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
const claims = JSON.parse(decoded);
if (claims === null || Array.isArray(claims) || typeof claims !== "object") {
  throw new Error("JWT payload is not a JSON object");
}
console.log(decoded);

このコマンドは JWT のペイロードをデコードしますが、トークンの署名は検証しません。本番環境のトークンはローカルでデコードし、サードパーティ製のツールには貼り付けないでください。

AWS が発行した OIDC トークンをデコードすると、次のようなペイロードが得られます。

{
  "iss": "https://abc123-def456-ghi789-jkl012.tokens.sts.global.api.aws",
  "aud": "https://api.openai.com/v1",
  "sub": "arn:aws:iam::123456789012:role/OpenAIWifRole",
  "iat": 1716235422,
  "exp": 1716235722,
  "jti": "jwt-id-example",
  "https://sts.amazonaws.com/": {
    "aws_account": "123456789012",
    "source_region": "us-west-2",
    "org_id": "o-exampleorgid",
    "principal_tags": {
      "environment": "production"
    },
    "request_tags": {
      "environment": "production",
      "workload": "batch-ingest"
    }
  }
}

AWS が発行する各トークンに、AWS 固有のクレームがすべて含まれるとは限りません。https://sts.amazonaws.com/ 配下のクレームは、呼び出し元のプリンシパル、セッションコンテキスト、リクエストタグによって異なります。

OpenAI で設定する予定のクレームを確認します。

  • iss:OpenAI のワークロード ID プロバイダーに設定する AWS アカウント固有の発行者 URL と一致する必要があります。
  • aud:GetWebIdentityToken に指定したオーディエンス、および OpenAI のワークロード ID プロバイダーに設定するオーディエンスと一致する必要があります。
  • sub:トークンをリクエストした IAM プリンシパルの ARN を示します。照合にはロールの ARN 全体を使用することを推奨します。
  • AWS 固有のクレーム:アカウント、組織、プリンシパルタグ、リクエストタグを照合する際は、デコードしたトークンで実際の値を確認してから照合条件を設定します。

デコードしたペイロードを使って、受け取ったトークンの内容を、OpenAI に設定した発行者、オーディエンス、マッピングの値と比較します。設定上の問題の多くは、トークンを交換する前に iss、aud、sub の各クレームを確認することで特定できます。

ワークロード ID フェデレーションの設定

AWS アカウントの発行者に対応するワークロード ID プロバイダーを OpenAI に作成し、サービスアカウントのマッピングを追加します。照合条件には、AWS が発行するトークンに含まれる、値が安定したクレームを使用します。

先にワークロード ID プロバイダーを設定してから、サービスアカウントのマッピングを作成します。

ワークロード ID プロバイダーの設定

  1. ワークロード ID プロバイダーを作成します。 名前には aws-outbound-prod などの一意の値を設定します。説明には Production AWS outbound identity federation workloads など、管理者がプロバイダーを識別できる情報を入力します。

  2. 発行者とオーディエンスを設定します。 OIDC 発行者 URL には、アウトバウンド ID フェデレーションを有効にした際に返された AWS アカウント固有の発行者 URL を設定します。この値はトークンの iss クレームと一致する必要があります。オーディエンスには GetWebIdentityToken に渡したオーディエンスと同じ値を設定します。この例では https://api.openai.com/v1 です。

  3. AWS の OIDC ディスカバリを使用します。 トークンの検証にアップロード済みの JWKS を使用は無効のままにします。OpenAI は AWS の発行者が提供する OIDC ディスカバリメタデータと JWKS を使って、AWS が発行したトークンを検証します。

  4. マッピングに派生属性が必要な場合のみ、属性変換を追加します。 トークンを変換せずに照合する場合は、sub、aud、iss などのトップレベルのスカラークレームを使用できます。AWS 固有の名前空間に属するクレームは https://sts.amazonaws.com/ 配下にネストされているため、マッピングで使用する前に CEL の角括弧記法で派生属性を作成します。たとえば、属性名に aws_environment、式に assertion["https://sts.amazonaws.com/"]["principal_tags"]["environment"] を入力すると、先ほどデコードしたトークンの例から openai.aws_environment を作成できます。ネストされたクレームのパスは、使用する前にサンプルトークンで確認してください。変換式を評価できない場合、マッピングの解決に失敗します。トークンに元から含まれる openai. で始まるクレームは、対応する変換を設定しない限り、openai. で始まるマッピングキーとの照合では無視されます。

サービスアカウントのマッピング設定

  1. サービスアカウントのマッピングを作成します。 名前には aws-role-openai-wif など、ワークロード ID プロバイダー内で一意の値を設定します。説明には Production AWS role for OpenAI API workload など、このマッピングを使用できるワークロードがわかる情報を入力します。

  2. AWS プリンシパルを照合します。 キーを sub に設定し、値には arn:aws:iam::123456789012:role/OpenAIWifRole など、デコードしたトークンに含まれる IAM プリンシパルの ARN を設定します。AWS のアウトバウンド ID フェデレーションでは、sub クレームの完全一致を条件にすると、アクセスを最も厳密に分離できます。

  3. 必要に応じてクレームの照合条件を追加します。 利用可能なスカラークレームや変換後の属性は、いずれも照合に使用できます。たとえば、信頼境界を追加する必要がある場合は、AWS アカウント、組織、プリンシパルタグ、リクエストタグのクレームから派生させた属性を使用します。

  4. OpenAI 側の対象を選択します。 プロジェクトには、対象のサービスアカウントが属する OpenAI プロジェクトを設定します。サービスアカウントには aws-outbound-prod-openai-wif など、AWS ワークロードが使用できる OpenAI サービスアカウントを設定します。

  5. 必要に応じて API 権限を絞り込みます。 権限で api.model.request や api.vector_store.read などの適切な項目を選択すると、このマッピングで発行されるアクセストークンの権限をさらに制限できます。WIF 固有のスコープ制限を追加しない場合は、権限を空欄にします。その場合も、トークンにはマッピング先のサービスアカウントの権限が適用されます。

コードでのトークンの使用

AWS STS に OIDC トークンをリクエストし、取得したトークンを OpenAI が発行するアクセストークンと交換するように、OpenAI SDK クライアントを設定します。

OPENAI_WIF_AUDIENCE には、OpenAI のワークロード ID プロバイダーに設定したオーディエンスと同じ値を設定します。サブジェクトトークンプロバイダーは、そのオーディエンスを指定して AWS STS の GetWebIdentityToken を呼び出し、AWS が発行した JWT をサブジェクトトークンとして返します。OpenAI SDK はそのトークンを OpenAI が発行するアクセストークンと交換します。

AWS が発行した OIDC トークンを使った認証
import { GetWebIdentityTokenCommand, STSClient } from "@aws-sdk/client-sts";
import OpenAI from "openai";

const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;
const audience = process.env.OPENAI_WIF_AUDIENCE;
const awsRegion = process.env.AWS_REGION;

if (!identityProviderId || !serviceAccountId || !audience || !awsRegion) {
  throw new Error(
    "Set OPENAI_IDENTITY_PROVIDER_ID, OPENAI_SERVICE_ACCOUNT_ID, OPENAI_WIF_AUDIENCE, and AWS_REGION"
  );
}
const wifAudience = audience;

const sts = new STSClient({ region: awsRegion });

function awsOutboundWebIdentityTokenProvider() {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const response = await sts.send(
        new GetWebIdentityTokenCommand({
          Audience: [wifAudience],
          SigningAlgorithm: "ES384",
          DurationSeconds: 300,
        })
      );

      if (!response.WebIdentityToken) {
        throw new Error("AWS STS did not return a web identity token.");
      }

      return response.WebIdentityToken;
    },
  };
}

const client = new OpenAI({
  workloadIdentity: {
    identityProviderId,
    serviceAccountId,
    provider: awsOutboundWebIdentityTokenProvider(),
  },
});

const response = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Say hello from AWS outbound workload identity federation.",
});

console.log(response.output_text);

AWS のベストプラクティス

  • ワークロードごとに専用の AWS ID を使用します。AWS のアウトバウンド ID フェデレーションでは IAM ロールを、EKS ワークロードでは Kubernetes サービスアカウントを、それぞれワークロードごとに分けます。
  • OpenAI へのアクセス専用のオーディエンスを設定します。AWS が発行するトークンまたは EKS の Pod に投影するトークンと、OpenAI のワークロード ID プロバイダーに、同じオーディエンスの値を設定します。
  • トークンの有効期間は、用途に応じて短めに設定します。AWS のアウトバウンド ID フェデレーションでは sts:DurationSeconds などの IAM 条件を使用し、EKS では Pod に投影するトークンに適切な有効期限を設定します。
  • サブジェクトの照合には完全一致を推奨します。AWS のアウトバウンドトークンには IAM プリンシパルの ARN 全体を、EKS トークンには Kubernetes サービスアカウントのサブジェクト全体を使用します。
  • マッピングの適用範囲は、安定した境界に沿って設定します。信頼範囲の広いルールを作らずにアクセスを絞り込める場合は、アカウント、組織、名前空間、変換後の属性を使用します。
  • トークンを交換するたびに最新のトークンを取得します。AWS のアウトバウンドトークンは必要なときにリクエストします。EKS の Pod に投影されたトークンはマウント先のファイルから読み取ることで、ローテーション後のトークンを自動的に使用できます。
  • ワークロードに必要な権限のみを付与します。マッピング単位の権限設定を使うと、マッピング先の OpenAI サービスアカウントが付与するアクセス権限をさらに絞り込めます。