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

Configure workload identity federation with X.509 certificates (beta)

Exchange a verified client certificate identity for a short-lived OpenAI access token.

X.509 workload identity federation lets a workload exchange an identity from a TLS client certificate for a short-lived OpenAI access token. The workload then calls the OpenAI API with both the access token and an accepted client certificate. This flow replaces the API key, not the client certificate.

X.509 workload identity federation is available in beta. If X.509 doesn’t appear as a provider type, contact your system administrator. Your administrator can work with OpenAI to enable the beta for your organization.

For token exchange request and response details, see the workload identity token exchange reference. For Mutual TLS certificate requirements and supported API endpoints, see the OpenAI Mutual TLS Beta Program.

How it works

An X.509 workload identity exchange has five parts:

  1. Your organization uploads and activates a trusted root certificate in its existing Mutual TLS settings.
  2. An X.509 Workload Identity Provider derives openai.* attributes from the verified client certificate. It must derive one non-empty openai.subject value.
  3. A service account mapping authorizes the derived identity to use one OpenAI service account within a project.
  4. The workload presents its certificate to the X.509 token endpoint on mtls.auth.openai.com and requests a short-lived bearer token. The certificate comes from the TLS connection; the request body doesn’t contain a subject_token.
  5. The workload presents the bearer token and a client certificate to an API route on mtls.api.openai.com for API authorization.

The bearer token and the certificate are authorized independently on the API request. A certificate by itself doesn’t authorize an OpenAI API call.

Before you begin

You need:

  • Access to the X.509 workload identity federation beta for your organization.
  • Permission to manage Mutual TLS certificates and Workload Identity Providers for your organization.
  • A project and service account for the workload.
  • A client certificate, its private key, and any intermediate certificates required to build a path to your trusted root.
  • An active trusted root certificate at the organization or project level.

Keep private keys outside source control and restrict access to the workload that uses them. Don’t log private keys, certificate contents, or returned access tokens.

Configure Mutual TLS certificate trust

X.509 Workload Identity Providers reuse your organization’s existing Mutual TLS certificate configuration. They don’t upload certificates or maintain a separate certificate trust store.

Follow the OpenAI Mutual TLS Beta Program to review CA certificate requirements, supported endpoints, certificate activation behavior, and client configuration. Then open Organization settings > Security > Mutual TLS, upload the trusted CA certificate in PEM format, and activate it for the organization or for each project that will use X.509 workload identity federation.

If your client certificate chains through an intermediate certificate, configure the stable trust anchor and present the leaf followed by the current intermediate certificates during the TLS handshake. OpenAI uses intermediates provided by the request and doesn’t retrieve missing intermediates from certificate URLs. The Mutual TLS beta article documents the current chain-support and endpoint restrictions.

Configure an X.509 provider

After X.509 workload identity federation is enabled for your organization:

  1. Open Organization settings > Security > Workload Identity Provider, then select Create identity provider.
  2. Choose X.509 for Provider type, then enter a name and optional description. X.509 providers don’t use OIDC issuer, audience, discovery, or JWKS settings. You can’t change the provider type after you create it.
  3. Under Advanced, optionally add an Attribute conditions CEL expression to reject certificates before mapping resolution.
  4. Under Attribute transformations, enter a non-empty expression for the required openai.subject transformation. The dashboard adds the subject row when you select X.509 and displays and applies the openai. prefix. Choose a stable certificate fact that identifies the workload.
  5. Optionally add transformations with other unique openai.* names, then select Create.

For example, this configuration uses the certificate common name as the canonical subject and exposes the organizational unit as an additional mapping attribute:


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

Certificate facts are available under assertion.subject and assertion.subject_alt_names. Transformation results used for mappings must be scalar values. Additional transformations must have unique openai.* names.

For example, an Attribute conditions expression can restrict the provider to production certificates:


      
      assertion.subject.organizational_unit == "Production"
    

Create a service account mapping

  1. From the X.509 provider details page, select Create mapping.
  2. Select the target project and service account, and grant only the API permissions the workload needs.
  3. In the Key and Value fields, require an exact openai.subject value. X.509 mappings support either no assertions, represented as an empty object ({}), or assertions whose keys start with openai.. During the beta, don’t leave the assertions empty.
  4. Select Create.

For example:

KeyValue
openai.subjectpayments-service-prod

X.509 mappings use derived openai.* attributes. They don’t match raw JWT claims such as sub, iss, or aud.

The provider list displays the provider ID, and the mapping details display the selected service account and its service account ID. Record both identifiers; the workload sends them during token exchange.

Exchange the certificate for an access token

Set environment variables for the certificate chain, private key, provider, and service account:


      
      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"
    

The certificate-chain file should contain the leaf certificate first, followed by any intermediate certificates. Don’t include certificate material or a subject_token in the request body.


      
      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
    

A successful exchange returns an ordinary short-lived bearer token:


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

The scope property is returned only when the matching service account mapping has permissions.

The expires_in value of 3600 is illustrative. The returned lifetime can be shorter when the verified client certificate expires sooner.

Read the access_token value from the successful response into your application’s credential store or an environment variable such as OPENAI_WIF_ACCESS_TOKEN. Treat it as a secret and don’t print, log, or commit it.

Call the OpenAI API

Set OPENAI_MODEL to gpt-5.6, the current default, or another model available to the target project. Then send the bearer token and an accepted client certificate to the API mTLS endpoint:


      
      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"
    

Use the bearer token instead of an API key, and continue to present an accepted client certificate on the API request.

The bearer isn’t cryptographically bound to the certificate. Reusing the exchange certificate for the API request is the most direct configuration, but the API request can use another certificate that independently satisfies the same current API mTLS policy.

Token lifetime and renewal

An X.509 workload identity token expires after at most one hour and never outlives the verified client certificate. The exchange doesn’t return a refresh token. Repeat the certificate exchange to obtain another access token.

Rotating an intermediate certificate doesn’t require changing the configured root. Present the new complete chain on subsequent exchanges and API requests.

Troubleshoot token exchange

X.509 token exchange returns generic OAuth errors and doesn’t expose certificate, root, provider, or mapping details.

ResultTypical causes
HTTP 403The request used a method or path other than exact POST /oauth/token on mtls.auth.openai.com.
invalid_subject_tokenThe TLS client certificate is missing or invalid, the presented chain can’t reach an active root, the certificate is outside its validity period, or a Mutual TLS certificate-admission rule rejects it.
invalid_grantThe X.509 flow isn’t enabled, the provider or mapping is invalid or disabled, a provider Attribute conditions expression rejects the identity, no applicable roots are active, or no mapping matches.
Server errorOpenAI returned a temporary server error. Retry according to your normal transient-error policy.

An X.509 exchange never falls back to an OIDC or ordinary OAuth flow.

Limitations

  • X.509 Workload Identity Providers don’t maintain a separate certificate trust store.
  • The bearer token isn’t certificate-bound and doesn’t use DPoP or a cnf claim.
  • The certificate exchange isn’t certificate-only API authorization. API requests still require the bearer token and an accepted client certificate.
  • OpenAI doesn’t fetch missing intermediate certificates from AIA URLs. Present the complete chain during TLS negotiation.
  • OpenAI doesn’t perform certificate revocation list (CRL) or OCSP checks during this flow. Plan certificate incident response around Mutual TLS root, provider, and mapping controls and the short lifetime of issued tokens.
  • This flow doesn’t add support for SPIFFE X.509-SVIDs. The SPIFFE guide continues to use JWT-SVIDs.