Com a federação de identidades de cargas de trabalho via X.509, uma carga de trabalho pode trocar a identidade obtida de um certificado de cliente TLS por um token de acesso de curta duração da OpenAI. Em seguida, a carga de trabalho chama a API da OpenAI usando tanto o token de acesso quanto um certificado de cliente aceito. Nesse fluxo, o token substitui a chave de API. O certificado de cliente continua obrigatório.
A federação de identidades de cargas de trabalho via X.509 está disponível para a API da OpenAI. O Codex não oferece suporte a esse recurso. Para o Codex, use um token OIDC ou um JWT-SVID do SPIFFE.
Para consultar os detalhes da solicitação e da resposta de troca de tokens, veja a referência de troca de tokens de identidade de cargas de trabalho. Para saber mais sobre permissões de TLS mútuo, requisitos e ativação de certificados, hosts mTLS e rotação de certificados, consulte o guia de TLS mútuo.
Como funciona
A troca de identidade de uma carga de trabalho via X.509 tem cinco etapas:
- Sua organização carrega e ativa um certificado raiz confiável nas configurações existentes de TLS mútuo.
- Um provedor de identidade de cargas de trabalho X.509 deriva atributos
openai.*do certificado de cliente verificado. Ele deve derivar um único valor não vazio paraopenai.subject. - Um mapeamento de conta de serviço autoriza a identidade derivada a usar uma conta de serviço da OpenAI em um projeto.
- A carga de trabalho apresenta o certificado ao endpoint de tokens X.509 em
mtls.auth.openai.come solicita um token de portador de curta duração. O certificado vem da conexão TLS. O corpo da solicitação não contém umsubject_token. - A carga de trabalho apresenta o token de portador e um certificado de cliente a uma rota da API em
mtls.api.openai.compara obter autorização.
A API verifica de forma independente se o token de portador e o certificado estão autorizados para a solicitação. O certificado, por si só, não autoriza uma chamada à API da OpenAI.
Antes de começar
Você precisa de:
- Permissão para gerenciar certificados de TLS mútuo e provedores de identidade de cargas de trabalho na sua organização.
- Um projeto e uma conta de serviço para a carga de trabalho.
- Um certificado de cliente, a chave privada correspondente e todos os certificados intermediários necessários para formar uma cadeia até a raiz confiável.
- Um certificado raiz confiável ativo no nível da organização ou do projeto.
Mantenha as chaves privadas fora do controle de versão. Permita que apenas a carga de trabalho que as utiliza tenha acesso a elas. Não registre em logs as chaves privadas, o conteúdo dos certificados nem os tokens de acesso retornados.
Configure a confiança nos certificados de TLS mútuo
Os provedores de identidade de cargas de trabalho X.509 reutilizam a configuração de certificados de TLS mútuo da sua organização. Esses provedores não carregam certificados nem mantêm um repositório separado de certificados confiáveis.
Consulte o guia de TLS mútuo para conferir os requisitos dos certificados, os hosts mTLS, o funcionamento da ativação dos certificados, os filtros CEL e a configuração do cliente. Em seguida, abra Configurações da organização > Segurança > TLS mútuo, carregue o certificado confiável em formato PEM e ative-o para a organização ou para cada projeto que usará a federação de identidades de cargas de trabalho via X.509.
Se a cadeia do certificado de cliente passar por um certificado intermediário, configure a âncora de confiança estável. Durante a negociação TLS, apresente primeiro o certificado folha e depois os certificados intermediários atuais. A OpenAI usa os certificados intermediários fornecidos na solicitação e não busca os que faltam nas URLs dos certificados.
Configure um provedor X.509
Para configurar um provedor X.509:
- Abra Configurações da organização > Segurança > Provedor de identidade de cargas de trabalho e selecione Criar provedor de identidade.
- Escolha X.509 em Tipo de provedor e insira um nome. A descrição é opcional. Provedores X.509 não usam as configurações de emissor, público, descoberta ou JWKS do OIDC. Depois de criar o provedor, você não pode alterar o tipo.
- Em Avançado, você pode adicionar uma expressão CEL em Condições de atributos para rejeitar certificados antes de determinar o mapeamento aplicável.
- Em Transformações de atributos, insira uma expressão não vazia para a transformação obrigatória
openai.subject. Quando você seleciona X.509, o painel adiciona a linhasubject, exibe o prefixoopenai.e o aplica. Escolha uma característica estável do certificado que identifique a carga de trabalho. - Se quiser, adicione transformações com outros nomes exclusivos no formato
openai.*. Em seguida, selecione Criar.
Por exemplo, esta configuração usa o nome comum do certificado como identificador canônico do titular e disponibiliza a unidade organizacional como atributo adicional para o mapeamento:
[
{
"attribute": "openai.subject",
"expression": "assertion.subject.common_name"
},
{
"attribute": "openai.environment",
"expression": "assertion.subject.organizational_unit"
}
]
Os dados do certificado estão disponíveis em assertion.subject e assertion.subject_alt_names. As transformações usadas nos mapeamentos devem retornar valores escalares. Cada transformação adicional deve ter um nome exclusivo no formato openai.*.
Por exemplo, uma expressão em Condições de atributos pode fazer com que o provedor aceite apenas certificados de produção:
assertion.subject.organizational_unit == "Production"
Crie um mapeamento de conta de serviço
- Na página de detalhes do provedor X.509, selecione Criar mapeamento.
- Selecione o projeto e a conta de serviço de destino e conceda apenas as permissões de API necessárias para a carga de trabalho.
- Use os campos Chave e Valor para exigir uma correspondência exata com o valor de
openai.subject. Os mapeamentos X.509 aceitam um objeto vazio ({}) quando não há asserções. Quando há asserções, suas chaves devem começar comopenai.. - Selecione Criar.
Por exemplo:
| Chave | Valor |
|---|---|
openai.subject |
payments-service-prod |
Os mapeamentos X.509 usam atributos derivados no formato openai.*. Eles não comparam diretamente declarações de JWT, como sub, iss ou aud.
A lista de provedores exibe o ID do provedor. Os detalhes do mapeamento mostram a conta de serviço selecionada e seu ID. Anote os dois identificadores. A carga de trabalho os envia durante a troca de tokens.
Use a identidade de carga de trabalho X.509 com um SDK
Defina as variáveis de ambiente para a cadeia de certificados, a chave privada, o provedor e a conta de serviço:
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"
O arquivo da cadeia de certificados deve conter primeiro o certificado folha e, em seguida, os certificados intermediários, se houver. Não inclua dados do certificado nem um subject_token no corpo da solicitação.
Configure um cliente do SDK da OpenAI com esses valores. O SDK apresenta o certificado de cliente durante a troca de tokens e nas solicitações à API, encaminha essas solicitações ao endpoint mTLS e renova automaticamente os tokens de acesso de curta duração.
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();
}Estes exemplos exigem versões dos SDKs da OpenAI que ofereçam suporte à configuração X.509 apresentada aqui: JavaScript 7.8.0 ou posterior com undici instalado como peer dependency, Python 3.6.0 ou posterior, Go 3.54.0 ou posterior, Java 4.55.0 ou posterior e Ruby 0.83.0 ou posterior.
O exemplo em Java carrega um repositório de chaves PKCS12 para criar o X509ExtendedKeyManager e usa o repositório padrão de certificados confiáveis da plataforma para criar o X509TrustManager. Defina OPENAI_X509_KEYSTORE_PATH, OPENAI_X509_KEYSTORE_PASSWORD e OPENAI_X509_CERTIFICATE_ALIAS para este exemplo. Como alternativa, você pode fornecer ao SDK gerenciadores que usem arquivos PEM ou hardware.
Troque o certificado manualmente
Para examinar ou implementar diretamente o protocolo de troca de tokens, apresente o certificado ao endpoint de tokens 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
Uma troca bem-sucedida retorna um token de portador comum de curta duração:
{
"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"
}
A resposta só inclui a propriedade scope quando o mapeamento de conta de serviço correspondente tem permissões.
Os valores de expiração são apenas exemplos. O prazo de validade do token retornado pode ser menor se o certificado de cliente verificado expirar antes. Consulte os campos da resposta de troca de tokens para saber as unidades e o significado de expires_in e expires_at.
Após uma troca bem-sucedida, leia o valor de access_token na resposta e armazene-o no repositório de credenciais do aplicativo ou em uma variável de ambiente, como OPENAI_WIF_ACCESS_TOKEN. Trate esse valor como segredo. Não o imprima, registre em logs ou inclua em commits.
Chame a API da OpenAI manualmente
Defina OPENAI_MODEL como gpt-6-astra, o modelo padrão atual, ou escolha outro modelo disponível para o projeto de destino. Em seguida, envie o token de portador e um certificado de cliente aceito ao endpoint mTLS da API:
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 o token de portador no lugar da chave de API e continue apresentando um certificado de cliente aceito na solicitação à API.
Não há vínculo criptográfico entre o token de portador e o certificado. A configuração mais simples é reutilizar na solicitação à API o certificado apresentado na troca. A solicitação também pode usar outro certificado que, por si só, atenda à mesma política mTLS vigente da API.
Validade e renovação do token
Um token de identidade de carga de trabalho X.509 tem validade máxima de uma hora e nunca permanece válido após a expiração do certificado de cliente verificado. A troca não retorna um token de atualização. Repita a troca do certificado para obter outro token de acesso.
Nas trocas manuais, armazene expires_at junto com o token de acesso e agende uma nova troca para antes do horário indicado. Leve em conta as diferenças entre os relógios e a latência das solicitações. Consulte as orientações sobre renovação de tokens para ver um exemplo.
Ao trocar um certificado intermediário, não é necessário alterar a raiz configurada. Apresente a nova cadeia completa nas próximas trocas e solicitações à API.
Resolva problemas na troca de tokens
A troca de tokens X.509 retorna erros genéricos de OAuth e não revela detalhes do certificado, da raiz, do provedor nem do mapeamento.
| Resultado | Causas comuns |
|---|---|
HTTP 403 |
O método ou o caminho da solicitação não corresponde exatamente a POST /oauth/token em mtls.auth.openai.com. |
invalid_subject_token |
O certificado de cliente TLS está ausente ou é inválido, a cadeia apresentada não chega a uma raiz ativa, o certificado está fora do período de validade ou uma regra de TLS mútuo para admissão de certificados o rejeita. |
invalid_grant |
O provedor ou o mapeamento é inválido ou está desativado, uma expressão em Condições de atributos do provedor rejeita a identidade, nenhuma raiz aplicável está ativa ou nenhum mapeamento corresponde à identidade. |
| Erro do servidor | A OpenAI retornou um erro temporário do servidor. Tente novamente de acordo com sua política habitual para erros transitórios. |
A troca via X.509 nunca recorre a um fluxo OIDC ou a um fluxo OAuth convencional como alternativa.
Limitações
- Os provedores de identidade de cargas de trabalho X.509 não mantêm um repositório separado de certificados confiáveis.
- O token de portador não tem vínculo com o certificado e não usa DPoP nem uma declaração
cnf. - A troca do certificado não autoriza o acesso à API apenas com o certificado. As solicitações à API continuam exigindo o token de portador e um certificado de cliente aceito.
- A OpenAI não busca certificados intermediários ausentes em URLs de AIA. Apresente a cadeia completa durante a negociação TLS.
- Durante esse fluxo, a OpenAI não consulta listas de revogação de certificados (CRL) nem realiza verificações via OCSP. Ao planejar a resposta a incidentes com certificados, leve em conta os controles de raiz do TLS mútuo, os controles de provedor e de mapeamento e a curta validade dos tokens emitidos.
- Esse fluxo não adiciona suporte a X.509-SVIDs do SPIFFE. O guia do SPIFFE continua usando JWT-SVIDs.