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

Microsoft Azure 向けワークロード ID フェデレーションの構成

Microsoft Azure は、次のいずれかの方法でワークロード ID プロバイダーとして使用できます。

  • Azure マネージド ID: マネージド ID に対して発行された Microsoft Entra ID アクセストークンを、有効期間の短い OpenAI アクセストークンと交換します。
  • AKS: Azure Kubernetes Service(AKS)で Pod に投影されたサービスアカウントトークンを、有効期間の短い OpenAI アクセストークンと交換します。

Azure マネージド ID

Azure マネージド ID を使うと、Azure 上で実行されるワークロードは、有効期間の長いシークレットを保存せずに Microsoft Entra トークンを要求できます。OpenAI のワークロード ID フェデレーションでは、マネージド ID トークンをサブジェクトトークンとして使用します。OpenAI はこのトークンを検証してから OpenAI アクセストークンを発行します。

Azure マネージド ID の設定

OpenAI が信頼するトークンの対象者(オーディエンス)を表す Microsoft Entra アプリケーションを新規登録するか、既存の登録を使用します。そのアプリケーションのアプリケーション ID URI を設定します。この URI は、ワークロードが Azure Instance Metadata Service(IMDS)にトークンを要求するときに指定する resource の値で、発行されたトークンの aud クレームにも含まれます。Microsoft Entra での設定手順は、新しい Entra ID アプリケーションとサービスプリンシパルの作成を参照してください。

Microsoft Entra ID で設定したアプリケーション ID URI、IMDS の resource パラメーター、発行されたトークンの aud クレーム、OpenAI のワークロード ID プロバイダーで設定したオーディエンスは、すべて一致している必要があります。

マネージド ID を作成し、仮想マシンなど、アプリケーションを実行する Azure リソースに割り当てます。このリソースは、実行時に IMDS を呼び出せる必要があります。Azure での設定の詳細は、Microsoft のマネージド ID の概要と、対象の Azure リソースのドキュメントに記載されている ID の割り当て手順を参照してください。

Azure マネージド ID トークンの取得

マネージド ID を割り当てた Azure リソースから、アプリケーション ID URI を resource パラメーターに指定して IMDS にトークンを要求します。OpenAI は、取得したトークンをサブジェクトトークンとして受け取り、OpenAI アクセストークンを発行します。

APPLICATION_ID_URI="api://<application-client-id>"

TOKEN=$(curl -sS -G -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token" \
  --data-urlencode "api-version=2018-02-01" \
  --data-urlencode "resource=${APPLICATION_ID_URI}" \
  | jq -r .access_token)
export TOKEN

リソースに複数のユーザー割り当てマネージド ID がある場合は、使用するマネージド ID を示す client_id、object_id、または msi_res_id クエリパラメーターを追加します。IMDS のトークン要求パラメーターについては、Microsoft の仮想マシンでマネージド ID を使用してアクセストークンを取得する方法を参照してください。

トークンの確認

ワークロード ID フェデレーションを構成する前に、Microsoft Entra トークンを環境変数 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 ペイロードをデコードします。本番環境のトークンはローカルのデコーダーで確認し、サードパーティーのツールに貼り付けないでください。

Microsoft Entra ID のマネージド ID トークンをデコードすると、次のようなペイロードが得られます。

{
  "iss": "https://login.microsoftonline.com/11111111-2222-3333-4444-555555555555/v2.0",
  "aud": "api://00000000-1111-2222-3333-444444444444",
  "tid": "11111111-2222-3333-4444-555555555555",
  "appid": "22222222-3333-4444-5555-666666666666",
  "oid": "33333333-4444-5555-6666-777777777777",
  "sub": "33333333-4444-5555-6666-777777777777",
  "xms_mirid": "/subscriptions/<subscription-id>/resourcegroups/my-resource-group/providers/Microsoft.Compute/virtualMachines/openai-wif-vm",
  "iat": 1716235422,
  "exp": 1716239022
}

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

  • iss:トークンに記載された発行者の値をそのまま使用します。発行者の例は https://login.microsoftonline.com/<tenant-id>/v2.0 ですが、末尾が常に /v2.0 とは限りません。
  • aud:アプリケーション ID URI、IMDS の resource パラメーター、OpenAI のワークロード ID プロバイダーのオーディエンスと一致している必要があります。
  • tid:Microsoft Entra のテナント ID
  • appid:このクレームが含まれる場合は、マネージド ID のアプリケーション ID(クライアント ID)
  • iat と exp:exp - iat を計算し、トークンの発行から有効期限までの期間を秒単位で確認します。

Codex では、プロバイダーの max_assertion_lifetime_seconds に、発行者が発行するトークンの想定有効期間をすべて含む、承認済みの上限値を設定します。トークンの有効期限までの残り時間を使ったり、すべての Entra トークンの有効期間を 1 時間と仮定したりしないでください。Microsoft のドキュメントでは、アクセストークンの有効期間は一定ではないと説明されています。また、Microsoft はマネージド ID トークンの有効期間の設定をサポートしていません。

マネージド ID トークンには、azp、oid、sub、xms_mirid などのクレームが含まれることもあります。デコードしたトークンの実際の値を基に、信頼するマネージド ID とリソースの範囲を正確に特定できるクレームを選びます。

デコードしたペイロードを使い、受け取ったトークンの値を、OpenAI で設定した発行者、オーディエンス、マッピングの値と照合します。設定上の問題の大半は、トークンを交換する前に iss、aud、tid、およびマネージド ID に関するクレームを確認することで特定できます。

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

Microsoft Entra ID の発行者に対応するワークロード ID プロバイダーを OpenAI で作成し、マネージド ID トークンの安定したクレームに一致するサービスアカウントマッピングを追加します。

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

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

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

  2. 発行者とオーディエンスを設定します。 OIDC 発行者 URL には、トークンの iss クレームの値をそのまま設定します。あらかじめサンプルのマネージド ID トークンを取得し、クレームを確認してください。発行者の例は https://login.microsoftonline.com/<tenant-id>/v2.0 です。オーディエンスには、Microsoft Entra で設定したアプリケーション ID URI(例:api://<application-client-id>)を指定します。この値はトークンの aud クレームと一致している必要があります。

  3. Microsoft Entra によるトークン検証を使用します。 アップロードした JWKS をトークン検証に使用は無効のままにします。OpenAI は Microsoft Entra の発行者メタデータと JWKS を使ってマネージド ID トークンを検証します。

  4. マッピングに派生属性が必要な場合は、属性変換を追加します。 たとえば、属性名に managed_identity_client_id、式に assertion.appid を入力すると、マネージド ID のアプリケーション ID(クライアント ID)を示すクレームから openai.managed_identity_client_id が作成されます。ダッシュボードは openai. プレフィックスを自動的に付与します。元のトークンに openai. で始まるクレームが含まれていても、対応する変換を設定しない限り、そのクレームは openai. で始まるマッピングキーには使用されません。

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

  1. サービスアカウントマッピングを作成します。 名前には vm-openai-wif など、このワークロード ID プロバイダー内で一意の値を設定します。説明には Production VM Azure managed identity workload のように、このマッピングを使用できるワークロードを記載します。

  2. マネージド ID の安定したクレームを照合します。 一致を必須とするクレームごとに、キーと値の組を 1 行ずつ追加します。トークンに appid が含まれている場合は、キーを appid に、値をマネージド ID のクライアント ID に設定します。appid クレームはマネージド ID のアプリケーション ID(クライアント ID)を示し、通常、マッピングを特定のマネージド ID に関連付けるうえで最も安定したクレームです。トークンに appid が含まれていない場合は、デコードしたトークンから azp、oid、sub、xms_mirid など、別の安定したクレームを選びます。マッピングを 1 つのテナントに限定するには、さらにキーを tid に、値を Microsoft Entra のテナント ID に設定します。IMDS から取得したサンプルトークンをデコードし、信頼するマネージド ID とリソースに対して値が安定しているクレームを使用してください。

  3. OpenAI 側の対象を選択します。 プロジェクトには、対象のサービスアカウントを所有する OpenAI プロジェクトを設定します。サービスアカウントには、azure-managed-identity-prod-openai-wif など、Azure ワークロードが使用できる OpenAI サービスアカウントを設定します。

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

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

IMDS に Azure マネージド ID トークンを要求し、OpenAI が発行するアクセストークンと交換するように OpenAI SDK クライアントを構成します。

OPENAI_WIF_AUDIENCE には、ワークロード ID プロバイダーのオーディエンスとして設定した Microsoft Entra のアプリケーション ID URI を指定します。SDK はそのオーディエンス向けのマネージド ID トークンを要求し、OpenAI が発行するアクセストークンと交換します。その後、OpenAI トークンを使って API リクエストを認証します。

Azure マネージド ID トークンを使った認証
import OpenAI from "openai";

const imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";

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

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

function azureManagedIdentityTokenProvider(resource) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const url = new URL(imdsEndpoint);
      url.searchParams.set("api-version", "2018-02-01");
      url.searchParams.set("resource", resource);

      const clientId = process.env.AZURE_CLIENT_ID;
      if (clientId) {
        url.searchParams.set("client_id", clientId);
      }

      const response = await fetch(url, {
        headers: { Metadata: "true" },
      });

      if (!response.ok) {
        throw new Error(
          `Azure IMDS token request failed with status ${response.status}.`
        );
      }

      const body = await response.json();
      if (!body.access_token) {
        throw new Error("Azure IMDS did not return an access token.");
      }

      return body.access_token;
    },
  };
}

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

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

console.log(response.output_text);

Microsoft Azure のベストプラクティス

  • 可能な限りマネージド ID を使用します。マネージド ID を使うと、資格情報を手動で配布するよりも簡単かつ安全に認証できます。
  • アプリケーションや環境ごとに、マネージド ID、Microsoft Entra アプリケーション、OpenAI のマッピングを分けます。開発、ステージング、本番のワークロード間で同じ ID を共有しないでください。
  • 受け入れるオーディエンスを制限します。OpenAI のワークロード ID フェデレーションに必要なオーディエンスだけを設定してください。
  • セキュリティ境界ごとに専用の Microsoft Entra ID アプリケーションを使用します。アプリケーションを分けると、管理責任が明確になり、監査やアクセス管理がしやすくなります。
  • ワークロードごとのマッピングを優先します。テナント全体に共通する属性ではなく、ワークロード固有のクレームを照合してください。
  • フェデレーション資格情報の設定を定期的に見直します。古い資格情報を残しておくと、ワークロードを廃止してから長期間にわたって意図せずアクセスを許可し続けることがあります。
  • 本番環境と非本番環境で ID を分けます。本番ワークロードの認証には、本番専用のフェデレーション ID と OpenAI サービスアカウントを使用してください。