Skip to content
Add tools and services

Configure OpenAI

Set up credential brokering so workloads call the OpenAI API with Keycard-issued tokens instead of static API keys

Configure workload identity federation between Keycard and OpenAI. Your applications get Keycard tokens that OpenAI exchanges for short-lived access tokens, so no OpenAI API key exists anywhere.

Before starting:

  • A Keycard account
  • The Owner role in your OpenAI organization. Workload identity is configured at the organization level, so a project owner can’t set it up.
  • An OpenAI project to hold the service account your workloads act as
  1. Create the OpenAI Resource

    In Keycard Console, navigate to Resources → Add Resource → Add Manually.

    Field Value
    Identifier https://api.openai.com/v1
    Credential Provider Zone Provider
    Credential Lifetime 1h (under Advanced options)

    The Identifier becomes the aud claim of the tokens Keycard issues for this Resource, and OpenAI checks it against the audience you set on its side.

  2. Create an Application

    Navigate to Applications → Add Application.

    Field Value
    Name for example openai-workload
    Identifier for example openai-workload

    Note the Application Identifier. Keycard puts it in the sub and keycard_app_id claims of the tokens this Application requests for itself, and OpenAI maps that sub to a service account. It is not the ID in the browser URL.

  3. Link the Resource

    Open the Application → Dependencies → Add dependency → select https://api.openai.com/v1.

  4. Create application credentials (local development only)

    Open the Application → Application Credentials → Add credential → Client ID & Secret.

    Note the Client ID and Client Secret. The secret is shown once.

  5. Note your Issuer URL

    Copy your Issuer URL from Keycard Console under Settings → Connection. OpenAI needs this as the issuer URL.

  1. Create a workload identity provider

    In OpenAI Platform, go to Organization Settings → Security → Workload Identity Provider → Create workload identity provider.

    Field Value
    Name for example keycard-prod
    Provider type OIDC
    OIDC Issuer URL your Keycard Issuer URL, for example <keycard-issuer-url>
    Audience https://api.openai.com/v1, the Resource Identifier from Keycard. The field suggests https://api.openai.com; replace it.

    Leave everything under Advanced off. Keycard publishes standard OIDC discovery metadata and signing keys, so OpenAI needs no custom discovery URL, uploaded JWKS or attribute transformations.

    Note the provider ID (idp_...).

  2. Map the Application to a service account

    Open the provider → Create mapping.

    Field Value
    Name for example keycard-workload
    Key sub
    Value your Keycard Application Identifier
    Project the OpenAI project your workload uses
    Service account select Create a new service account in this project and name it, for example keycard-workload
    Permissions All, or Restricted to limit it to the endpoints your workload calls

    Note the service account ID (user-...).

Every OpenAI SDK takes a workload identity option with a callback that returns a subject token. Point that callback at Keycard and the SDK exchanges the Keycard token for an OpenAI token on its own.

from keycardai.oauth import BasicAuth, Client
from openai import OpenAI
# 1. A Keycard client for this Application.
keycard = Client(
"<keycard-issuer-url>", # from Settings → Connection
auth=BasicAuth("<your-client-id>", "<your-client-secret>"),
)
# 2. The OpenAI SDK calls this for a fresh Keycard token whenever it
# exchanges or renews its OpenAI token.
def keycard_token() -> str:
return keycard.client_credentials_grant(resource="https://api.openai.com/v1").access_token
client = OpenAI(
workload_identity={
"identity_provider_id": "<idp_...>",
"service_account_id": "<user-...>",
"provider": {"token_type": "jwt", "get_token": keycard_token},
},
)
response = client.responses.create(
model="gpt-5-mini",
input="Hello from a Keycard workload",
)
print(response.output_text)

In Keycard Console, open Audit Log. Look for:

Event Description
credentials:issue Token issued for https://api.openai.com/v1

In your terminal, the code sample prints the model’s reply. A reply means OpenAI accepted the exchange.

apiKey and workloadIdentity are mutually exclusive The TypeScript and Ruby SDKs read OPENAI_API_KEY from the environment and refuse to start when it’s set alongside workload identity. Unset OPENAI_API_KEY.

Keycard returns access_denied: the Application “is not allowed to access” the Resource Add https://api.openai.com/v1 as a dependency of the Application. If your Zone runs its own policy set, it also needs a permit for this Application and Resource.

OpenAI rejects the exchange Check that the provider’s Audience is https://api.openai.com/v1, exactly the Keycard Resource Identifier, and that the OIDC Issuer URL matches your Keycard Issuer URL. The mapping’s Value must be the Application Identifier, not the ID in the browser URL. Only one enabled mapping can match an exchange.

No Workload Identity Provider settings in OpenAI Platform Workload identity is configured at the organization level. Ask an OpenAI organization owner to set it up, or to give you the Owner role.