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

使用 X.509 证书配置工作负载身份联合

将经过验证的客户端证书身份交换为短期 OpenAI 访问令牌。

X.509 工作负载身份联合允许工作负载将 TLS 客户端证书中的身份交换为短期 OpenAI 访问令牌。随后,工作负载同时使用访问令牌和受认可的客户端证书调用 OpenAI API。此流程替代的是 API 密钥,而非客户端证书。

OpenAI API 支持 X.509 工作负载身份联合。 Codex 不支持此功能。对于 Codex,请使用 OIDC Token 或 SPIFFE JWT-SVID,并按照 Codex 工作负载身份指南操作。

有关 Token 交换请求和响应的详细信息,请参阅工作负载身份 Token 交换参考资料。有关双向 TLS 权限、证书要求、激活、mTLS 主机和轮换的信息,请参阅双向 TLS 指南

工作原理

X.509 工作负载身份交换包含五个部分:

  1. 您的组织在现有的双向 TLS 设置中上传并激活受信任的根证书。
  2. X.509 工作负载身份提供方从经过验证的客户端证书中派生 openai.* 属性。它必须派生出一个非空的 openai.subject 值。
  3. 服务账户映射授权派生的身份使用项目中的一个 OpenAI 服务账户。
  4. 工作负载向 mtls.auth.openai.com 上的 X.509 Token 端点出示其证书,并请求短期持有者 Token。证书来自 TLS 连接;请求体中不包含 subject_token
  5. 工作负载向 mtls.api.openai.com 上的 API 路由出示持有者 Token 和客户端证书,以获得 API 授权。

API 请求中的持有者 Token 和证书分别接受独立的授权检查。仅凭证书无法获得 OpenAI API 调用授权。

开始之前

您需要:

  • 管理组织的双向 TLS 证书和工作负载身份提供方的权限。
  • 供工作负载使用的项目和服务账户。
  • 客户端证书、其私钥,以及构建通向受信任根证书的路径所需的所有中间证书。
  • 在组织或项目级别处于激活状态的受信任根证书。

请勿将私钥纳入源代码版本控制,并将私钥访问权限限制为仅供使用它们的工作负载访问。请勿在日志中记录私钥、证书内容或返回的访问令牌。

配置双向 TLS 证书信任

X.509 工作负载身份提供方复用您组织现有的双向 TLS 证书配置。它们不会上传证书,也不会维护单独的证书信任库。

请参阅双向 TLS 指南,了解证书要求、 mTLS 主机、证书激活行为、CEL 过滤器和 客户端配置。然后打开组织设置 > 安全 > 双向 TLS,上传 PEM 格式的受信任证书,并为组织或 每个将使用 X.509 工作负载身份联合的项目激活该证书。

如果您的客户端证书通过中间证书构成证书链,请配置稳定的信任锚,并在 TLS 握手期间按顺序出示叶证书和当前的中间证书。OpenAI 使用请求中提供的中间证书,不会从证书 URL 获取缺失的中间证书。

配置 X.509 提供方

要配置 X.509 提供方,请执行以下操作:

  1. 打开组织设置 > 安全 > 工作负载身份提供方,然后选择 创建身份提供方
  2. 提供方类型选为 X.509 ,然后输入名称和可选的描述。X.509 提供方不使用 OIDC 签发者、受众、发现或 JWKS 设置。创建后,您无法更改提供方类型。
  3. 高级下,您可以选择添加 属性条件 CEL 表达式,以在解析映射之前拒绝不符合条件的证书。
  4. 属性转换下,为必需的 openai.subject 转换输入非空表达式。当您选择 X.509 时,控制台会添加 subject 行,并显示和应用 openai. 前缀。请选择一项稳定且能标识工作负载的证书信息。
  5. 您可以选择添加其他具有唯一 openai.* 名称的转换,然后选择 创建

例如,以下配置将证书的通用名称用作规范主体,并将组织单位作为额外的映射属性提供:

[
  {
    "attribute": "openai.subject",
    "expression": "assertion.subject.common_name"
  },
  {
    "attribute": "openai.environment",
    "expression": "assertion.subject.organizational_unit"
  }
]

证书信息可通过 assertion.subjectassertion.subject_alt_names 获取。用于映射的转换结果必须是标量值。额外的转换必须具有唯一的 openai.* 名称。

例如, 属性条件 表达式可以将提供方限制为仅接受生产环境证书:

assertion.subject.organizational_unit == "Production"

创建服务账户映射

  1. 在 X.509 提供方详情页面,选择 创建映射
  2. 选择目标项目和服务账户,并仅授予工作负载所需的 API 权限。
  3. 字段中,设置需要精确匹配的 openai.subject 值。X.509 映射支持不含断言(以空对象 {} 表示),或仅包含键以 openai. 开头的断言。
  4. 选择 创建

例如:

openai.subjectpayments-service-prod

X.509 映射使用派生的 openai.* 属性。它们不匹配 subissaud 等原始 JWT 声明。

提供方列表显示提供方 ID,映射详情显示所选服务账户及其服务账户 ID。请记录这两个标识符;工作负载会在 Token 交换期间发送它们。

通过 SDK 使用 X.509 工作负载身份

为证书链、私钥、提供方和服务账户设置环境变量:

export OPENAI_MTLS_CERT_CHAIN="/path/to/client-chain.pem"
export OPENAI_MTLS_KEY="/path/to/client-key.pem"
export OPENAI_IDENTITY_PROVIDER_ID="idp_example"
export OPENAI_SERVICE_ACCOUNT_ID="svc_acct_example"

证书链文件应首先包含叶证书,随后是所有中间证书。请勿在请求体中包含证书材料或 subject_token

使用这些值配置 OpenAI SDK 客户端。SDK 会在 Token 交换和 API 请求期间出示客户端证书,将 API 请求路由到 mTLS 端点,并自动续期短期访问令牌。

使用 X.509 客户端证书进行身份验证
import { readFile } from "node:fs/promises";

import OpenAI from "openai";
import { workloadIdentity } from "openai/auth/x509-transport";

const certificatePath = process.env.OPENAI_MTLS_CERT_CHAIN;
const privateKeyPath = process.env.OPENAI_MTLS_KEY;
const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;

if (
  !certificatePath ||
  !privateKeyPath ||
  !identityProviderId ||
  !serviceAccountId
) {
  throw new Error(
    "Set OPENAI_MTLS_CERT_CHAIN, OPENAI_MTLS_KEY, OPENAI_IDENTITY_PROVIDER_ID, and OPENAI_SERVICE_ACCOUNT_ID"
  );
}

const credential = workloadIdentity.fromX509({
  certificateChain: await readFile(certificatePath, "utf8"),
  privateKey: await readFile(privateKeyPath, "utf8"),
  identityProviderId,
  serviceAccountId,
});

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

  console.log(response.output_text);
} finally {
  await credential.close();
}

这些示例要求使用支持此处所示 X.509 配置的 OpenAI SDK 版本:JavaScript 7.8.0 或更高版本(需安装 undici 对等依赖项)、Python 3.6.0 或更高版本、Go 3.54.0 或更高版本、Java 4.55.0 或更高版本,以及 Ruby 0.83.0 或更高版本。

Java 示例加载 PKCS12 密钥库来构造 X509ExtendedKeyManager,并使用平台默认信任库来构造 X509TrustManager。请为此示例设置 OPENAI_X509_KEYSTORE_PATHOPENAI_X509_KEYSTORE_PASSWORDOPENAI_X509_CERTIFICATE_ALIAS。您也可以改为向 SDK 提供基于 PEM 或硬件的管理器。

手动使用证书进行交换

要直接检查或实现 Token 交换协议,请向 X.509 Token 端点出示证书:

curl --cert "$OPENAI_MTLS_CERT_CHAIN" \
  --key "$OPENAI_MTLS_KEY" \
  --request POST "https://mtls.auth.openai.com/oauth/token" \
  --header "Content-Type: application/json" \
  --data @- <<JSON
{
  "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
  "subject_token_type": "urn:openai:params:oauth:token-type:x509",
  "identity_provider_id": "${OPENAI_IDENTITY_PROVIDER_ID}",
  "service_account_id": "${OPENAI_SERVICE_ACCOUNT_ID}"
}
JSON

交换成功后会返回一个普通的短期持有者 Token:

{
  "access_token": "eyJ...",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": 1789045200,
  "scope": "api.model.read api.model.request"
}

只有匹配的服务账户映射具有权限时,才会返回 scope 属性。

到期相关数值仅作示例。若已验证的客户端证书更早到期,返回的有效期可能会更短。有关 expires_inexpires_at 的单位及含义,请参阅 Token 交换响应字段

从成功响应中读取 access_token 值,并将其存入应用程序的凭据存储或 OPENAI_WIF_ACCESS_TOKEN 等环境变量中。请将其作为机密信息处理,不要打印、记录到日志或提交到代码仓库。

手动调用 OpenAI API

OPENAI_MODEL 设置为当前默认模型 gpt-6-astra,或目标项目可用的其他模型。然后,将持有者 Token 和受认可的客户端证书发送到 API mTLS 端点:

curl --request POST \
  --cert "$OPENAI_MTLS_CERT_CHAIN" \
  --key "$OPENAI_MTLS_KEY" \
  --header "Authorization: Bearer $OPENAI_WIF_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data "{\"model\":\"$OPENAI_MODEL\",\"input\":\"Say hello in one sentence.\"}" \
  "https://mtls.api.openai.com/v1/responses"

使用持有者 Token 替代 API 密钥,并继续在 API 请求中出示受认可的客户端证书。

持有者 Token 与证书之间没有密码学绑定。API 请求复用交换时的证书是最直接的配置方式,但也可以使用另一张证书,前提是该证书能独立满足当前相同的 API mTLS 策略。

Token 有效期与续期

X.509 工作负载身份 Token 的有效期最长为一小时,且不会晚于已验证的客户端证书到期。交换操作不会返回刷新 Token。请再次执行证书交换,以获取新的访问 Token。

手动交换时,请将 expires_at 与访问 Token 一同保存,并安排在该时间戳所指的时间之前再次执行交换。请为时钟偏差和请求延迟预留时间。示例请参阅 Token 续期指南

轮换中间证书无需更改已配置的根证书。请在后续交换和 API 请求中提供新的完整证书链。

排查 Token 交换问题

X.509 Token 交换会返回通用的 OAuth 错误,不会透露证书、根证书、提供方或映射的详细信息。

结果常见原因
HTTP 403请求使用的方法或路径与 mtls.auth.openai.com 上要求的 POST /oauth/token 不完全一致。
invalid_subject_tokenTLS 客户端证书缺失或无效,提供的证书链无法追溯到已激活的根证书,证书不在有效期内,或双向 TLS 证书准入规则拒绝了该证书。
invalid_grant提供方或映射无效或已禁用,提供方的 属性条件 表达式拒绝了该身份,没有已激活的适用根证书,或没有匹配的映射。
服务器错误OpenAI 返回了临时服务器错误。请按照您常用的临时错误处理策略重试。

X.509 交换绝不会回退到 OIDC 或常规 OAuth 流程。

限制

  • X.509 工作负载身份提供方不会维护单独的证书信任存储。
  • 持有者 Token 不与证书绑定,也不使用 DPoP 或 cnf 声明。
  • 证书交换并不意味着仅凭证书即可获得 API 授权。API 请求仍需提供持有者 Token 和可被接受的客户端证书。
  • OpenAI 不会从 AIA URL 获取缺失的中间证书。请在 TLS 协商期间提供完整的证书链。
  • OpenAI 在此流程中不会执行证书吊销列表(CRL)或 OCSP 检查。请结合双向 TLS 根证书、提供方和映射的控制措施,以及已签发 Token 有效期较短这一特点,制定证书安全事件响应方案。
  • 此流程并未新增对 SPIFFE X.509-SVIDs 的支持。SPIFFE 指南仍使用 JWT-SVIDs。