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

設定 AWS 的工作負載身分聯合

在下列任一情境中,使用 AWS 作為工作負載身分提供者:

  • AWS 對外身分聯合: 將透過 GetWebIdentityToken 取得、由 AWS STS 簽發的 OIDC JWT 交換為短效的 OpenAI 存取權杖。
  • Amazon EKS: 將 Amazon EKS 投射式服務帳戶 Token 交換為短效的 OpenAI 存取權杖。

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

OpenAI 支援 AWS 透過對外身分聯合簽發的 OIDC JWT,以及 Amazon EKS 簽發的 Kubernetes 投射式服務帳戶 Token。OpenAI 不支援將 SigV4 簽署的請求或 AWS STS 臨時存取金鑰憑證用作工作負載身分聯合的主體 Token。

AWS 對外身分聯合

AWS 對外身分聯合可讓 AWS 主體向 AWS STS 請求已簽署的 OIDC JWT,並將該 Token 提供給外部服務。在 OpenAI 工作負載身分聯合中,AWS 簽發的 JWT 就是主體 Token;OpenAI 會先驗證此 Token,再簽發 OpenAI 存取權杖。

設定 AWS 對外身分聯合

為將要簽發 Token 的 AWS 帳戶啟用對外身分聯合。如需設定詳細資訊,請參閱 AWS 的對外身分聯合入門指南

aws iam enable-outbound-web-identity-federation

記錄 AWS 傳回的帳戶專屬簽發者 URL。您將把此值設定為 OpenAI 工作負載身分提供者的簽發者,且此值必須與 AWS 簽發的 Token 中的 iss 宣告相符。

AWS STS GetWebIdentityToken API 無法在 STS 全域端點使用。 請將 AWS CLI 或 SDK 設定為使用區域 STS 端點。

授予工作負載呼叫 sts:GetWebIdentityToken 的權限。在 IAM 中限制對象和 Token 的最長有效期限,讓 AWS 主體只能簽發供 OpenAI 使用的 Token。此範例允許簽發對象為 https://api.openai.com/v1、最長有效期限為 300 秒的 Token:

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

請求 AWS 簽發的 OIDC Token,其對象須與您將在 OpenAI 工作負載身分提供者中設定的對象相同。除非您的環境需要相容於 RS256,否則請使用 ES384

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 簽發的 Token

設定工作負載身分聯合之前,請先將 AWS 簽發的 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 貼到第三方工具中。

AWS 簽發的 OIDC Token 解碼後會類似下列內容:

{
  "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 簽發的 Token 都包含所有 AWS 專屬宣告。https://sts.amazonaws.com/ 下的宣告取決於呼叫主體、工作階段上下文和請求標籤。

請驗證您打算在 OpenAI 中設定的宣告:

  • iss:必須與 OpenAI 工作負載身分提供者中設定的 AWS 帳戶專屬簽發者 URL 相符。
  • aud:必須與 GetWebIdentityToken 的對象及 OpenAI 工作負載身分提供者的對象相符。
  • sub:識別請求此 Token 的 IAM 主體 ARN。建議使用完整的角色 ARN 進行精確比對。
  • AWS 專屬宣告:比對帳戶、組織、主體標籤或請求標籤的值之前,請以解碼後的 Token 為準。

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

設定工作負載身分聯合

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

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

設定工作負載身分提供者

  1. 建立工作負載身分提供者。名稱 設為不重複的值,例如 aws-outbound-prod。使用 說明協助管理員識別提供者,例如填入 Production AWS outbound identity federation workloads

  2. 設定簽發者和對象。OIDC 簽發者 URL 設為啟用對外身分聯合時傳回的 AWS 帳戶專屬簽發者 URL。此值必須與 Token 的 iss 宣告相符。將 對象 設為傳遞給 GetWebIdentityToken 的相同對象。在此範例中,該值為 https://api.openai.com/v1

  3. 使用 AWS OIDC 探索。使用上傳的 JWKS 驗證 Token 保持停用。OpenAI 會使用 AWS 簽發者的 OIDC 探索中繼資料和 JWKS,驗證 AWS 簽發的 Token。

  4. 只有在需要衍生的對應屬性時,才新增屬性轉換。 原始 Token 比對支援 subaudiss 等頂層純量宣告。AWS 專屬的命名空間宣告巢狀位於 https://sts.amazonaws.com/ 之下,因此在對應中使用這些宣告前,請先透過 CEL 方括號語法建立衍生屬性。例如,輸入 aws_environment 並搭配運算式 assertion["https://sts.amazonaws.com/"]["principal_tags"]["environment"],即可從上述解碼後的 Token 範例建立 openai.aws_environment。使用前,請先在範例 Token 中確認巢狀宣告的路徑;若無法求得轉換結果,對應解析就會失敗。對於 openai. 對應鍵,除非已設定相符的轉換,否則會忽略本身就以 openai. 開頭的原始 Token 宣告。

設定服務帳戶對應

  1. 建立服務帳戶對應。名稱 設為在此工作負載身分提供者中不重複的值,例如 aws-role-openai-wif。使用 說明指出哪些工作負載可以使用此對應,例如填入 Production AWS role for OpenAI API workload

  2. 比對 AWS 主體。 設為 sub,並將 設為解碼後的 Token 中的 IAM 主體 ARN,例如 arn:aws:iam::123456789012:role/OpenAIWifRole。精確比對 sub 宣告可為 AWS 對外身分聯合提供最嚴格的隔離。

  3. 視需要新增其他宣告比對條件。 您可以比對任何可用的純量宣告或轉換後的屬性。例如,若需要額外的信任邊界,可使用從 AWS 帳戶、組織、主體標籤或請求標籤宣告衍生的轉換屬性。

  4. 選擇 OpenAI 目標。專案 設為目標服務帳戶所屬的 OpenAI 專案。將 服務帳戶 設為 AWS 工作負載可使用的 OpenAI 服務帳戶,例如 aws-outbound-prod-openai-wif

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

在程式碼中使用 Token

設定 OpenAI SDK 用戶端,向 AWS STS 請求 AWS 簽發的 OIDC Token,並將其交換為 OpenAI 簽發的存取權杖。

OPENAI_WIF_AUDIENCE 設為與 OpenAI 工作負載身分提供者中設定的對象相同的值。主體 Token 提供者會使用該對象呼叫 AWS STS GetWebIdentityToken,並將 AWS 簽發的 JWT 作為主體 Token 傳回,接著由 OpenAI SDK 將其交換為 OpenAI 簽發的存取權杖。

使用 AWS 簽發的 OIDC Token 進行驗證
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 身分。對於 AWS 對外身分聯合,使用各自獨立的 IAM 角色;對於 EKS 工作負載,使用各自獨立的 Kubernetes 服務帳戶。
  • 為 OpenAI 存取設定專屬的對象。AWS 簽發的 Token 或 EKS 投射式 Token,應與 OpenAI 工作負載身分提供者組態使用相同的對象值。
  • 將 Token 的有效期間維持在合理的短時間內。對於 AWS 對外身分聯合,使用 sts:DurationSeconds 等 IAM 條件;對於 EKS,設定適當的投射式 Token 到期時間。
  • 優先採用主體的精確比對。對於 AWS 對外 Token,比對完整的 IAM 主體 ARN;對於 EKS Token,比對完整的 Kubernetes 服務帳戶主體。
  • 將對應範圍限定在穩定的界線內。如果帳戶、組織、命名空間或轉換後的屬性能縮限存取權,且不會建立過於寬鬆的信任規則,就可使用這些屬性。
  • 交換 Token 時,請重新載入 Token。在需要時請求 AWS 對外 Token,並從掛載的檔案路徑讀取 EKS 投射式 Token,以便自動使用輪替後的 Token。
  • 僅授予工作負載所需的權限。使用對應層級的權限,進一步縮限目標 OpenAI 服務帳戶授予的存取權。