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 会先验证它,再签发 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 生成 Token,最长有效期为 300 秒:

{
  "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,请使用本地解码器,并避免将其粘贴到第三方工具中。

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 签发的令牌或 EKS 投射令牌中,以及 OpenAI 工作负载身份提供方配置中,使用相同的受众值。
  • 将令牌有效期保持在合理的较短范围内。对于 AWS 出站身份联合,使用 sts:DurationSeconds 等 IAM 条件;对于 EKS,为投射令牌设置适当的过期时间。
  • 优先使用精确的主体匹配。对于 AWS 出站令牌,匹配完整的 IAM 主体 ARN;对于 EKS 令牌,匹配完整的 Kubernetes 服务账户主体。
  • 将映射范围限定在稳定的边界内。如果账户、组织、命名空间或转换后属性能缩小访问范围,且不会造成过于宽泛的信任规则,就使用这些属性。
  • 交换令牌时重新加载令牌。按需请求 AWS 出站令牌,并从挂载的文件路径读取 EKS 投射令牌,以便自动使用轮换后的令牌。
  • 仅授予工作负载所需的权限。使用映射级别的权限,进一步缩小目标 OpenAI 服务账户授予的访问范围。