For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主要導覽

設定 Google Cloud 的工作負載身分聯合

在以下任一情境中,可使用 Google Cloud 作為工作負載身分提供者:

  • Google 工作負載身分: 使用核發給已連結 Google 服務帳戶、由 Google 簽署的 OIDC Token,交換短效 OpenAI 存取權杖。
  • Google Kubernetes Engine: 使用投射的 GKE 服務帳戶 Token,交換短效 OpenAI 存取權杖。

若要搭配 Codex 使用,請按照本頁說明取得並檢查 Google Token。接著設定 Codex 工作負載身分,將該 Token 寫入檔案,並讓 Codex 指向該檔案。本頁的服務帳戶對應與 SDK 範例適用於 OpenAI API。

Google 工作負載身分

Google Cloud 工作負載可向 Google 中繼資料伺服器要求已簽署的 OIDC 身分 Token,無須儲存長效服務帳戶金鑰。在 OpenAI 工作負載身分聯合中,Google 身分 Token 就是主體 Token;OpenAI 會先驗證此 Token,再核發 OpenAI 存取權杖。此流程適用於 Compute Engine、Cloud Run、使用已連結 Google 服務帳戶的 GKE 工作負載,以及其他提供中繼資料伺服器身分端點的 Google 代管執行環境。

設定 Google 工作負載身分

為需要呼叫 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 Token。

取得 Google 身分 Token

從已連結服務帳戶的 Google Cloud 資源,使用已設定的對象向中繼資料伺服器要求 OIDC 身分 Token。這個 Token 就是用來向 OpenAI 交換 OpenAI 所核發存取權杖的主體 Token。

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。如需中繼資料伺服器身分端點的詳細資訊,請參閱 Google 的驗證 VM 身分指南。

驗證 Token

設定工作負載身分聯合前,請先將 Google 身分 Token 匯出為環境變數 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 酬載,但不會驗證 Token 簽章。請使用本機解碼器處理正式環境的 Token,並避免將正式環境的 Token 貼入第三方工具。

解碼後的 Google 中繼資料伺服器身分 Token 會類似以下內容:

{
  "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
}

使用解碼後的酬載,將收到的 Token 與 OpenAI 中設定的核發者、對象和對應值進行比較。在交換 Token 前,大多數組態問題都能從 issaudemailsub 宣告中看出。

設定工作負載身分聯合

在 OpenAI 中為 Google 核發的身分 Token 建立工作負載身分提供者,然後新增服務帳戶對應,以比對 Token 中穩定不變的宣告。

請先設定工作負載身分提供者,再建立服務帳戶對應。

設定工作負載身分提供者

  1. 建立工作負載身分提供者。名稱 設為不重複的值,例如 google-workload-identity-prod。填寫 描述(例如 Production Google Cloud workloads),協助管理員識別此提供者。

  2. 設定核發者與對象。OIDC 核發者 URL 設為 https://accounts.google.com。將 對象 設為工作負載向 Google 中繼資料伺服器要求的自訂對象,例如 https://api.openai.com/v1。此值必須與 Token 的 aud 宣告相符。

  3. 使用 Google OIDC 探索。使用已上傳的 JWKS 驗證 Token 維持停用。OpenAI 會使用 Google 的 OIDC 探索中繼資料和 JWKS,驗證由 Google 簽署的身分 Token。

  4. 若需要衍生的對應屬性,請新增屬性轉換。 例如,輸入 subject 並搭配運算式 assertion.sub,即可根據主體宣告建立 openai.subject。儀表板會自動加上 openai. 前置字串。比對 openai. 對應鍵時,會忽略原始 Token 中已以 openai. 開頭的宣告,除非已設定相應的轉換。

設定服務帳戶對應

  1. 建立服務帳戶對應。名稱 設為在此工作負載身分提供者中不重複的值,例如 compute-openai-wif。填寫 描述(例如 Production Compute Engine OpenAI API workload),說明哪些工作負載可以使用此對應。

  2. 比對穩定不變的 Google 服務帳戶宣告。 為每個必須相符的宣告新增一列 。請使用 sub 作為主要身分繫結,因為它穩定且唯一。你也可以額外比對 email,以提高可讀性。

  3. 選擇 OpenAI 目標。專案 設為目標服務帳戶所屬的 OpenAI 專案。將 服務帳戶 設為 Google Cloud 工作負載可使用的 OpenAI 服務帳戶,例如 google-workload-identity-prod-openai-wif

  4. 視需要縮小 API 權限範圍。 選擇適當的 權限 ,例如 api.model.requestapi.vector_store.read,進一步限縮透過此對應核發的存取權杖權限。將權限留白,即可避免新增 WIF 專屬的範圍限制;Token 仍會以所對應服務帳戶的身分取得授權。

在程式碼中使用 Token

設定 OpenAI SDK 用戶端,讓它向中繼資料伺服器要求 Google 身分 Token,並交換 OpenAI 核發的存取權杖。

OPENAI_WIF_AUDIENCE 設為工作負載身分提供者中設定的自訂對象。SDK 會要求以該對象為目標的 Google 身分 Token,將其交換為 OpenAI 核發的存取權杖,再使用該 OpenAI Token 驗證 API 請求。

使用 Google 中繼資料伺服器身分 Token 進行驗證
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 服務帳戶。避免在不相關的服務或環境之間共用服務帳戶。
  • 使用工作負載身分流程,取代長效服務帳戶金鑰。若工作負載可使用中繼資料伺服器的身分 Token 或 GKE 工作負載身分,請避免為其分發及輪替 JSON 金鑰檔案。
  • 將身分的適用範圍限制在實務上可行的最小工作負載邊界。為個別應用程式使用獨立的服務帳戶,可讓稽核更清楚,並實現最小權限存取。
  • 謹慎使用屬性式對應。盡可能優先採用穩定的識別碼,例如服務帳戶主體宣告,而非可變動的中繼資料。
  • 將正式環境與非正式環境的專案分開。使用不同的專案可降低意外共用權限的風險,並簡化稽核。
  • 僅授予必要的 IAM 權限。將 Google 身分的權限限制為工作負載所需的權限。
  • 監控服務帳戶的使用情況。非預期的 Token 交換可能表示組態偏移,或工作負載已遭入侵。