X.509 工作負載身分聯合可讓工作負載以 TLS 用戶端憑證中的身分換取短效 OpenAI 存取權杖。接著,工作負載會同時使用存取權杖和受接受的用戶端憑證呼叫 OpenAI API。這個流程取代的是 API 金鑰,而非用戶端憑證。
X.509 工作負載身分聯合適用於 OpenAI API。 Codex 不支援此功能。若使用 Codex,請使用 OIDC Token 或 SPIFFE JWT-SVID,並參閱 Codex 工作負載身分指南。
如需權杖交換請求與回應的詳細資訊,請參閱工作負載身分權杖交換參考資料。如需雙向 TLS 權限、憑證需求、啟用方式、mTLS 主機和輪替的相關資訊,請參閱雙向 TLS 指南。
運作方式
X.509 工作負載身分交換包含五個部分:
- 您的組織在現有的雙向 TLS 設定中上傳並啟用受信任的根憑證。
- X.509 工作負載身分提供者會從經過驗證的用戶端憑證衍生出
openai.*屬性。其中必須衍生出一個非空白的openai.subject值。 - 服務帳戶對應會授權衍生出的身分使用專案中的一個 OpenAI 服務帳戶。
- 工作負載會向
mtls.auth.openai.com上的 X.509 權杖端點提供憑證,並請求短效持有者權杖。憑證來自 TLS 連線;請求本文不包含subject_token。 - 工作負載會向
mtls.api.openai.com上的 API 路由提供持有者權杖和用戶端憑證,以取得 API 授權。
在 API 請求中,持有者權杖和憑證會分別接受獨立的授權檢查。僅憑憑證無法授權 OpenAI API 呼叫。
開始之前
您需要:
- 管理組織雙向 TLS 憑證和工作負載身分提供者的權限。
- 供工作負載使用的專案和服務帳戶。
- 用戶端憑證、其私密金鑰,以及建立通往受信任根憑證之路徑所需的任何中繼憑證。
- 在組織或專案層級已啟用的受信任根憑證。
請勿將私密金鑰納入原始碼版本控制,並將存取權限限制為僅供使用該金鑰的工作負載存取。請勿在記錄中寫入私密金鑰、憑證內容或傳回的存取權杖。
設定雙向 TLS 憑證信任
X.509 工作負載身分提供者會沿用組織現有的雙向 TLS 憑證組態,不會上傳憑證或維護獨立的憑證信任存放區。
請參閱雙向 TLS 指南,瞭解憑證 需求、mTLS 主機、憑證啟用行為、CEL 篩選器及 用戶端組態。接著開啟組織設定 > 安全性 > 雙向 TLS,上傳 PEM 格式的受信任憑證,並為整個組織 或每個將使用 X.509 工作負載身分聯合的專案啟用該憑證。
如果用戶端憑證的憑證鏈經過中繼憑證,請設定穩定的信任錨點,並在 TLS 交握期間先提供末端憑證,再提供目前的中繼憑證。OpenAI 會使用請求提供的中繼憑證,不會從憑證 URL 擷取缺少的中繼憑證。
設定 X.509 提供者
若要設定 X.509 提供者:
- 開啟組織設定 > 安全性 > 工作負載身分提供者,然後選取 建立身分提供者。
- 在 提供者類型中選擇 X.509 ,然後輸入名稱及選填的說明。X.509 提供者不使用 OIDC 簽發者、對象、探索或 JWKS 設定。建立提供者後,便無法變更其類型。
- 在 進階下,您可以視需要新增 屬性條件 CEL 運算式,在判定對應關係之前拒絕憑證。
- 在 屬性轉換下,為必要的
openai.subject轉換輸入非空白的運算式。當您選取 X.509 時,控制台會新增subject列,並顯示及套用openai.前綴。請選擇可識別工作負載且保持穩定的憑證資訊。 - 您可以視需要新增其他具有不重複
openai.*名稱的轉換,然後選取 建立。
例如,下列組態使用憑證的一般名稱作為標準主體,並提供組織單位作為額外的對應屬性:
[
{
"attribute": "openai.subject",
"expression": "assertion.subject.common_name"
},
{
"attribute": "openai.environment",
"expression": "assertion.subject.organizational_unit"
}
]
您可以在 assertion.subject 和 assertion.subject_alt_names 下取得憑證資訊。用於對應的轉換結果必須是純量值。其他轉換必須使用不重複的 openai.* 名稱。
例如, 屬性條件 運算式可將提供者限制為僅接受正式環境憑證:
assertion.subject.organizational_unit == "Production"
建立服務帳戶對應
- 在 X.509 提供者詳細資料頁面中,選取 建立對應。
- 選取目標專案和服務帳戶,並僅授予工作負載所需的 API 權限。
- 在 鍵 和 值 欄位中,設定必須完全相符的
openai.subject值。X.509 對應支援不含任何斷言的情況,以空物件({})表示;也支援鍵以openai.開頭的斷言。 - 選取 建立。
例如:
| 鍵 | 值 |
|---|---|
openai.subject | payments-service-prod |
X.509 對應使用衍生出的 openai.* 屬性,不會比對 sub、iss 或 aud 等原始 JWT 宣告。
提供者清單會顯示提供者 ID,對應詳細資料則會顯示所選服務帳戶及其服務帳戶 ID。請記下這兩個識別碼;工作負載會在權杖交換期間傳送這些識別碼。
透過 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 會在權杖交換和 API 請求期間提供用戶端憑證,將 API 請求導向 mTLS 端點,並自動更新短效存取權杖。
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_PATH、OPENAI_X509_KEYSTORE_PASSWORD 和 OPENAI_X509_CERTIFICATE_ALIAS。您也可以改為向 SDK 提供以 PEM 或硬體為基礎的管理器。
手動以憑證進行交換
若要直接檢查或實作權杖交換協定,請向 X.509 權杖端點提供憑證:
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
交換成功後會傳回一般的短效持有者權杖:
{
"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_in 和 expires_at 的單位與含義,請參閱 Token 交換回應欄位。
從成功回應中讀取 access_token 值,並存入應用程式的認證存放區,或 OPENAI_WIF_ACCESS_TOKEN 之類的環境變數。請將此值視為機密,不要列印、寫入記錄或提交至版本控制。
手動呼叫 OpenAI API
將 OPENAI_MODEL 設為目前的預設模型 gpt-6-astra,或目標專案可用的其他模型。接著,將持有者權杖和受接受的用戶端憑證傳送至 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"
使用持有者權杖取代 API 金鑰,並繼續在 API 請求中提供受接受的用戶端憑證。
持有者權杖並未透過密碼學方式與憑證綁定。在 API 請求中沿用交換時所用的憑證,是最直接的設定方式;不過,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_token | TLS 用戶端憑證遺失或無效、提供的憑證鏈無法連結至已啟用的根憑證、憑證不在有效期間內,或雙向 TLS 憑證准入規則拒絕該憑證。 |
invalid_grant | 提供者或對應無效或已停用、提供者的 屬性條件 運算式拒絕該身分、沒有已啟用且適用的根憑證,或沒有相符的對應。 |
| 伺服器錯誤 | OpenAI 傳回了暫時性的伺服器錯誤。請依照平常處理暫時性錯誤的原則重試。 |
X.509 交換絕不會改用 OIDC 或一般 OAuth 流程。
限制
- X.509 工作負載身分提供者不會維護獨立的憑證信任存放區。
- Bearer Token 未與憑證繫結,也不使用 DPoP 或
cnf宣告。 - 憑證交換並不代表僅憑憑證即可取得 API 授權。API 請求仍需提供 bearer Token 和受接受的用戶端憑證。
- OpenAI 不會從 AIA URL 擷取缺少的中繼憑證。請在 TLS 交涉期間提供完整的憑證鏈。
- OpenAI 不會在此流程中執行憑證撤銷清單(CRL)或 OCSP 檢查。請依據雙向 TLS 根憑證、提供者和對應的控制機制,以及已核發 Token 的短有效期限,規劃憑證事件應變措施。
- 此流程並未新增對 SPIFFE X.509-SVIDs 的支援。SPIFFE 指南仍使用 JWT-SVIDs。