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

Google Cloud 向けワークロード ID 連携の設定

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

  • Google のワークロード ID: ワークロードにアタッチされた Google サービスアカウント向けに Google が署名・発行した OIDC トークンを、有効期間の短い OpenAI アクセストークンと交換します。
  • Google Kubernetes Engine: ボリュームに投影された GKE サービスアカウントトークンを、有効期間の短い OpenAI アクセストークンと交換します。

Google のワークロード ID

Google Cloud のワークロードは、有効期間の長いサービスアカウントキーを保存せずに、Google メタデータサーバーから署名済みの OIDC ID トークンを取得できます。OpenAI のワークロード ID 連携では、Google の ID トークンをサブジェクトトークンとして使用します。OpenAI はこのトークンを検証してから、OpenAI アクセストークンを発行します。この方式は、Compute Engine、Cloud Run、アタッチされた Google サービスアカウントを使用する GKE ワークロード、およびメタデータサーバーの ID エンドポイントを利用できるその他の Google 管理のランタイムで使用できます。

Google のワークロード ID の設定

OpenAI API を呼び出すワークロード用に、Google サービスアカウントを作成します。設定手順の詳細は、Google のガイド「サービスアカウントの作成」を参照してください。

たとえば、Google Cloud CLI でサービスアカウントを作成するには、次のコマンドを実行します。

gcloud iam service-accounts create openai-wif \
  --description="Service account for OpenAI workload identity federation" \
  --display-name="OpenAI workload identity federation"

サービスアカウントをアタッチした Compute Engine VM を作成するか、アプリケーションを実行する Google Cloud リソースにサービスアカウントをアタッチします。このリソースは、実行時に Google メタデータサーバーにアクセスできる必要があります。VM の設定については、Google のガイド「ユーザー管理のサービスアカウントを使用する VM の作成」を参照してください。

この方式では、サービスアカウントキーを作成したり、ダウンロードしたりしないでください。ワークロードは、アタッチされたサービスアカウントを使用して、メタデータサーバーに有効期間の短い OIDC トークンをリクエストします。

Google の ID トークンの取得

サービスアカウントをアタッチした Google Cloud リソースから、設定済みのオーディエンスを指定して、メタデータサーバーに OIDC ID トークンをリクエストします。OpenAI はこのトークンをサブジェクトトークンとして受け取り、OpenAI アクセストークンと交換します。

AUDIENCE="https://api.openai.com/v1"

TOKEN=$(curl -sS -G -H "Metadata-Flavor: Google" \
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity" \
  --data-urlencode "audience=${AUDIENCE}")
export TOKEN

メタデータサーバーは Google が署名した JWT を返します。メタデータサーバーの ID エンドポイントについては、Google のガイド「VM の ID の検証」を参照してください。

トークンの確認

ワークロード ID 連携を設定する前に、Google の ID トークンを環境変数 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 のペイロードをデコードします。本番環境のトークンはローカルのデコーダーで処理し、サードパーティ製のツールに貼り付けないでください。

Google メタデータサーバーの ID トークンをデコードすると、次のようなペイロードが得られます。

{
  "iss": "https://accounts.google.com",
  "aud": "https://api.openai.com/v1",
  "azp": "110123456789012345678",
  "sub": "110123456789012345678",
  "email": "openai-wif@my-project.iam.gserviceaccount.com",
  "email_verified": true,
  "iat": 1716235422,
  "exp": 1716239022
}

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

ワークロード ID 連携の設定

OpenAI で、Google が発行する ID トークン用のワークロード ID プロバイダーを作成します。次に、トークン内の値が変わらないクレームと照合するサービスアカウントマッピングを追加します。

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

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

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

  2. 発行者とオーディエンスを設定します。 OIDC 発行者 URL を https://accounts.google.com に設定します。オーディエンスには、ワークロードが Google メタデータサーバーへのリクエストで指定するカスタムオーディエンス(https://api.openai.com/v1 など)を設定します。この値は、トークンの aud クレームと一致する必要があります。

  3. Google の OIDC ディスカバリを使用します。 トークンの検証にアップロード済みの JWKS を使用は無効のままにします。OpenAI は、Google の OIDC ディスカバリメタデータと JWKS を使用して、Google が署名した ID トークンを検証します。

  4. クレームから導出した属性をマッピングに使う場合は、属性変換を追加します。 たとえば、属性名に subject、式に assertion.sub を入力すると、サブジェクトクレームから openai.subject が作成されます。ダッシュボードが openai. プレフィックスを自動で付加します。元のトークンに openai. で始まるクレームがあっても、対応する変換を設定しない限り、openai. で始まるマッピングキーの照合には使用されません。

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

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

  2. Google サービスアカウントを識別するには、値が変わらないクレームを照合します。 一致を必須とするクレームごとに、キーと値の組を 1 行ずつ追加します。sub は値が変わらず一意であるため、ID を紐付ける主な識別子として使用します。識別しやすくするために、email も照合対象に追加できます。

  3. 紐付け先の OpenAI サービスアカウントを選択します。 プロジェクトには、対象のサービスアカウントが属する OpenAI プロジェクトを設定します。サービスアカウントには google-workload-identity-prod-openai-wif など、Google Cloud ワークロードに使用を許可する OpenAI サービスアカウントを設定します。

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

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

メタデータサーバーから Google の ID トークンを取得し、OpenAI が発行するアクセストークンと交換するように OpenAI SDK クライアントを設定します。

OPENAI_WIF_AUDIENCE には、ワークロード ID プロバイダーで設定したカスタムオーディエンスを指定します。SDK はそのオーディエンス向けの Google の ID トークンをリクエストし、OpenAI が発行するアクセストークンと交換します。API リクエストの認証には、この OpenAI アクセストークンを使用します。

Google メタデータサーバーの ID トークンを使った認証
import OpenAI from "openai";

const metadataEndpoint =
  "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity";

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 googleMetadataIdentityTokenProvider(audience) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const url = new URL(metadataEndpoint);
      url.searchParams.set("audience", audience);
      url.searchParams.set("format", "full");

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

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

      const token = (await response.text()).trim();
      if (!token) {
        throw new Error(
          "Google metadata server did not return an identity token."
        );
      }

      return token;
    },
  };
}

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

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

console.log(response.output_text);

Google Cloud のベストプラクティス

  • ワークロードごとに専用の Google サービスアカウントを使用します。関連のないサービスや環境でサービスアカウントを共有しないでください。
  • 有効期間の長いサービスアカウントキーの代わりに、ワークロード ID による認証を使用します。メタデータサーバーの ID トークンまたは GKE Workload Identity を使用できるワークロードでは、JSON キーファイルの配布やローテーションは避けてください。
  • 各 ID を使用できるワークロードの範囲は、運用上可能な限り小さくします。アプリケーションごとにサービスアカウントを分けると、監査時にどのアプリケーションがアクセスしたかを把握しやすくなり、アクセス権限を必要最小限に抑えられます。
  • 属性に基づくマッピングは慎重に設定します。可能な限り、変更される可能性のあるメタデータよりも、サービスアカウントのサブジェクトクレームなど、値が変わらない識別子を優先してください。
  • 本番環境とそれ以外の環境でプロジェクトを分けます。プロジェクトを分けると、意図せず権限を共有するリスクが減り、監査も容易になります。
  • 必要な IAM 権限だけを付与します。Google の ID に付与する権限は、そのワークロードに必要なものに限定してください。
  • サービスアカウントの使用状況を監視します。想定外のトークン交換は、実際の設定が意図した状態からずれていることや、ワークロードが侵害されたことを示す場合があります。