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

為 Kubernetes 設定工作負載身分聯合

將投射的 Kubernetes 服務帳戶 Token 交換為短效的 OpenAI 存取權杖,即可使用 Kubernetes 作為工作負載身分提供者。

若使用 Codex,請依照本頁取得並檢查投射的 Token,然後設定 Codex 工作負載身分,讓 Codex 指向已掛載的 Token 檔案。本頁的服務帳戶對應與 SDK 範例適用於 OpenAI API。

設定 Kubernetes

本指南假設已啟用 Kubernetes 服務帳戶 Token 投射功能;新版 Kubernetes 預設提供此功能。OpenAI 工作負載身分聯合需要相容於 OIDC 的投射式服務帳戶 Token,不支援儲存在 Secrets 中的舊式 Kubernetes 服務帳戶 Token。

為需要呼叫 OpenAI API 的工作負載使用 Kubernetes ServiceAccount。如果尚未建立,請先建立:

kubectl create serviceaccount openai-wif --namespace default

取得 Kubernetes 叢集的 OIDC 簽發者:

kubectl get --raw /.well-known/openid-configuration | jq -r .issuer

即使您上傳了 JWKS,且 OpenAI 不會向 OIDC 簽發者執行 JWKS 探索,此簽發者仍必須與工作負載身分提供者中設定的簽發者一致。

取得叢集的 JWKS,並儲存傳回的金鑰集。設定工作負載身分提供者時會用到:

kubectl get --raw /openid/v1/jwks

為投射式服務帳戶 Token 設定 OpenAI 預期的對象,以及適合工作負載的有效期限。OpenAI 會驗證 Token 的簽發者、簽章、對象和有效期限。在此範例中,Token 檔案掛載於 /var/run/secrets/tokens/token,使用的對象為 https://api.openai.com/v1,並在 3600 秒後到期。您也可以使用其他對象,只要投射式 Token 的對象與 OpenAI 工作負載身分提供者的對象一致即可:

apiVersion: v1
kind: Pod
metadata:
  name: openai-wif-app
  namespace: default
spec:
  serviceAccountName: openai-wif
  containers:
    - name: app
      image: my-image
      volumeMounts:
        - name: ksa-token
          mountPath: /var/run/secrets/tokens
          readOnly: true
  volumes:
    - name: ksa-token
      projected:
        sources:
          - serviceAccountToken:
              path: token
              audience: "https://api.openai.com/v1"
              expirationSeconds: 3600

驗證 Token

設定工作負載身分聯合之前,請先在本機解碼一個投射式服務帳戶 Token 範例,並檢查其宣告。從已掛載投射式 Token 且正在執行的 Pod 中取得 Token,並將其匯出為 TOKEN

TOKEN=$(kubectl exec -n default openai-wif-app -- cat /var/run/secrets/tokens/token)
export 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 貼入第三方工具。

解碼後的 Kubernetes 投射式服務帳戶 Token 會類似以下內容:

{
  "iss": "https://kubernetes.example.com",
  "aud": ["https://api.openai.com/v1"],
  "sub": "system:serviceaccount:default:openai-wif",
  "iat": 1716235422,
  "exp": 1716239022,
  "kubernetes.io": {
    "namespace": "default",
    "serviceaccount": {
      "name": "openai-wif",
      "uid": "11111111-2222-3333-4444-555555555555"
    }
  }
}

使用解碼後的承載資料,將收到的 Token 與 OpenAI 中設定的簽發者、對象和對應值進行比對。在交換 Token 之前,就能從 issaudsub 宣告中看出大多數組態問題。

設定工作負載身分聯合

在 OpenAI 中為 Kubernetes 簽發者建立工作負載身分提供者,然後新增服務帳戶對應,讓對應條件符合投射式 Token 中的屬性。

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

設定工作負載身分提供者

  1. 建立工作負載身分提供者。名稱 設為唯一值,例如 kubernetes-prod。使用 說明協助管理員識別叢集,例如 Production Kubernetes cluster

  2. 設定簽發者和對象。OIDC 簽發者 URL 設為 kubectl get --raw /.well-known/openid-configuration | jq -r .issuer 傳回的簽發者。此值必須與投射式 Token 中的 iss 宣告一致。將 對象 設為投射式服務帳戶 Token 磁碟區中設定的相同不透明對象字串。在此範例中,該值為 https://api.openai.com/v1

  3. 上傳 Kubernetes JWKS。 啟用 使用已上傳的 JWKS 驗證 Token,然後將 JWKS JSON 設為 kubectl get --raw /openid/v1/jwks 的輸出。OpenAI 會使用此公開金鑰集驗證投射的 Kubernetes 服務帳戶 Token。請上傳完整的金鑰集,包括外層的 keys

    注意: 對於自行託管的 Kubernetes 叢集,OpenAI 僅支援本機 JWKS 模式。請上傳叢集傳回的 JWKS;OpenAI 不會向設定的簽發者執行 OIDC 探索。OpenAI 仍會將設定的簽發者與 Token 中的 iss 欄位進行比對。

    如果叢集輪替了服務帳戶簽署金鑰,請更新工作負載身分提供者組態中已上傳的 JWKS。若簽署 Token 的金鑰未列於設定的 JWKS 中,該 Token 就會遭到拒絕。如果 JWKS 包含多個使用中的公開金鑰,請包含完整的 keys 陣列。

  4. 僅在需要衍生的對應屬性時,才新增屬性轉換。 原始 Token 宣告(例如 subaudiss)可直接用於對應判斷條件。如果您打算使用轉換後的屬性,而非原始 Token 宣告來比對,儀表板會自動加上 openai. 前綴;例如,輸入 workload_subject 並使用運算式 assertion.sub,即可建立 openai.workload_subject。對於 openai. 對應鍵,除非已設定相符的轉換,否則會忽略原本就以 openai. 開頭的原始 Token 宣告。

設定服務帳戶對應

  1. 建立服務帳戶對應。名稱 設為在該工作負載身分提供者內唯一的值,例如 openai-mapping-kubernetes。使用 說明指出哪些工作負載可以使用此對應,例如 Workload Identity Provider Mapping for Kubernetes Workloads

  2. 比對 Kubernetes 服務帳戶主體。 設為 sub,並將 設為 system:serviceaccount:default:openai-wif。Kubernetes 服務帳戶的主體格式為 system:serviceaccount:<namespace>:<service-account-name>

  3. 選擇 OpenAI 目標。專案 設為目標服務帳戶所屬的 OpenAI 專案。將 服務帳戶 設為 Kubernetes 工作負載可以使用的 OpenAI 服務帳戶,例如 kubernetes-prod-openai-wif。如果您想為此對應建立新的服務帳戶,而非重複使用現有帳戶,請勾選 Create a new service account in this project

  4. 視需要縮限 API 權限。 選取適當的 權限 ,例如 api.model.requestapi.vector_store.read,進一步限制透過此對應簽發的存取權杖。若不想新增 WIF 專屬的範圍限制,請將權限留空;Token 仍會以對應的服務帳戶身分取得授權。

在程式碼中使用 Token

設定 OpenAI SDK 用戶端,讓它讀取投射的 Kubernetes Token,並將其交換為 OpenAI 簽發的存取權杖。

使用掛載的 Token 路徑(例如 /var/run/secrets/tokens/token),作為 SDK 工作負載身分聯合提供者的主體 Token 來源。SDK 會將該 Kubernetes Token 交換為 OpenAI 簽發的存取權杖,再使用 OpenAI Token 驗證 API 請求的身分。

以下範例使用自訂的主體 Token 提供者來初始化 OpenAI 用戶端。此提供者會從掛載的檔案路徑讀取投射的 Kubernetes 服務帳戶 Token,並將其用作工作負載身分聯合的主體 Token。

使用 Kubernetes 投射式服務帳戶 Token 進行身分驗證
import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const tokenPath = "/var/run/secrets/tokens/token";
const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;

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

function mountedServiceAccountTokenProvider(path) {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const token = (await readFile(path, "utf8")).trim();
      if (!token) {
        throw new Error("The mounted service account token file is empty.");
      }
      return token;
    },
  };
}

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

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

console.log(response.output_text);

Kubernetes 最佳實務

  • 使用穩定的 OIDC 簽發者。簽發者 URL 必須與投射式服務帳戶 Token 的 iss 宣告一致,且應在叢集升級和維護作業期間保持不變。
  • 妥善保護簽署金鑰。任何能存取叢集服務帳戶簽署金鑰的人,都能簽發可能被 OpenAI 接受的 Token。
  • 為 OpenAI 整合使用專用的服務帳戶。避免重複使用同時用於存取其他無關基礎架構或應用程式的服務帳戶。
  • 確保已上傳的 JWKS 維持最新狀態。在本機 JWKS 模式下,OpenAI 會使用設定的 JWKS 驗證工作負載身分 Token,因此請在輪替至新的簽署金鑰之前,先更新工作負載身分提供者。
  • 盡量降低自訂宣告的複雜度。優先使用標準宣告(例如 subaud)進行比對,或使用直接由這些宣告轉換而來的屬性。
  • 將命名空間的擁有權納入安全性模型。如果命名空間管理員可以建立服務帳戶,請確保對應的範圍設定得當,以防止非預期的權限提升。
  • 監控簽發者與簽署金鑰的變更。如果輪替簽署金鑰卻未更新工作負載身分提供者的 JWKS,可能會導致 Token 交換失敗。