167)167)
168```168```
169 169
170#### X.509 workload identity (mutual TLS)
171
172For X.509 workload identity federation, configure the client certificate and
173server trust on an HTTPX2 client, then pass only the identity-provider and
174service-account IDs to the SDK:
175
176```python
177import os
178import ssl
179
180from openai import OpenAI, DefaultHttpx2Client
181from openai.auth import x509_workload_identity
182
183tls_context = ssl.create_default_context(
184 cafile=os.getenv("OPENAI_MTLS_CA_BUNDLE"),
185)
186tls_context.load_cert_chain(
187 certfile=os.environ["OPENAI_MTLS_CERTIFICATE_CHAIN"],
188 keyfile=os.environ["OPENAI_MTLS_PRIVATE_KEY"],
189 password=os.getenv("OPENAI_MTLS_PRIVATE_KEY_PASSWORD"),
190)
191
192client = OpenAI(
193 workload_identity=x509_workload_identity(
194 identity_provider_id=os.environ["OPENAI_IDENTITY_PROVIDER_ID"],
195 service_account_id=os.environ["OPENAI_SERVICE_ACCOUNT_ID"],
196 # refresh_buffer_seconds=120.0,
197 ),
198 http_client=DefaultHttpx2Client(
199 verify=tls_context,
200 follow_redirects=False,
201 ),
202)
203```
204
205X.509 mode defaults to `https://mtls.api.openai.com/v1` when neither `base_url`
206nor `OPENAI_BASE_URL` is set. The same configured HTTP client presents its
207certificate to the fixed mTLS token-exchange endpoint and to the API. Tokens
208are exchanged lazily, cached, and refreshed automatically. Certificate files,
209private keys, passwords, server trust, proxies, and rotation remain application
210and transport concerns.
211
212X.509 API requests require HTTPS and must stay on the configured API origin.
213The effective HTTP Host authority must match that origin.
214Provider API-key and proxy-only headers cannot be sent to the API alongside
215X.509 authentication.
216Token exchanges do not inherit API request hooks, authentication, or cookies.
217Identity settings are captured when the client is constructed; create a new
218client to change the identity. Azure clients do not support X.509 workload
219identity.
220
221For asynchronous requests, use `AsyncOpenAI` with
222`DefaultAsyncHttpx2Client`. See the complete [sync rollout-toggle
223example](examples/x509_workload_identity.py) and [async rollout-toggle
224example](examples/x509_workload_identity_async.py), which select API-key or
225X.509 authentication with the application-owned `OPENAI_AUTH_MODE`
226environment variable. X.509 workload identity currently supports HTTP APIs;
227Realtime and WebSockets are not included.
228
170### Vision229### Vision
171 230
172With an image URL:231With an image URL:
950See the complete [sync HTTPX2](examples/mtls_httpx2.py) and1009See the complete [sync HTTPX2](examples/mtls_httpx2.py) and
951[async HTTPX2](examples/mtls_httpx2_async.py) examples.1010[async HTTPX2](examples/mtls_httpx2_async.py) examples.
952 1011
953The certificate-bearing HTTP client is transport-wide. Dedicate it to the1012The certificate-bearing HTTP client is transport-wide. For API-key mTLS,
954selected mTLS origin; do not reuse it for other services or pass it through1013dedicate it to the selected API origin; X.509 workload identity also uses the
955`with_options()` with a different `base_url`. If redirects are required, add an1014fixed OpenAI mTLS token-exchange origin. Do not reuse the client for unrelated
1015services or pass it through `with_options()` with a different `base_url`.
1016If redirects are required for API-key mTLS, add an
956HTTPX2 request hook that rejects requests whose scheme, host, or port differs1017HTTPX2 request hook that rejects requests whose scheme, host, or port differs
957from the configured mTLS origin before enabling `follow_redirects`.1018from the configured mTLS origin before enabling `follow_redirects`.
958 1019
969client after its in-flight requests finish. Do not assume existing TLS1030client after its in-flight requests finish. Do not assume existing TLS
970connections will renegotiate.1031connections will renegotiate.
971 1032
972This recipe applies to ordinary API-key HTTP traffic. It does not implement1033This recipe applies to ordinary API-key HTTP traffic. For certificate-backed
973certificate-only X.509 workload identity, token exchange, or Realtime WebSocket1034token exchange, use the X.509 workload identity configuration described above.
974mTLS.1035Realtime WebSocket mTLS is not included.
975 1036
976### Managing HTTP resources1037### Managing HTTP resources
977 1038
1073 1134
1074You can also pass `access_key_id` and `secret_access_key`, with an optional `session_token`, or a refreshable `credential_provider` that returns botocore-compatible credentials. Explicit bearer and AWS credential options are mutually exclusive.1135You can also pass `access_key_id` and `secret_access_key`, with an optional `session_token`, or a refreshable `credential_provider` that returns botocore-compatible credentials. Explicit bearer and AWS credential options are mutually exclusive.
1075 1136
1076Pass `base_url` to `bedrock(...)` or set `AWS_BEDROCK_BASE_URL` to override the derived `https://bedrock-mantle.<region>.api.aws/openai/v1` endpoint.1137Pass `base_url` to `bedrock(...)` or set `AWS_BEDROCK_BASE_URL` to override the derived `https://bedrock-mantle.<region>.api.aws/openai/v1` endpoint. Custom URLs retain Mantle signing by default; pass `endpoint="runtime"` to use Runtime signing.
1077 1138
1078SigV4 requests require replayable, fully serialized request bodies. Standard JSON requests already meet this requirement, and response streaming is unaffected. Low-level one-shot request streams must be buffered before sending, or sent with bearer authentication and retries disabled.1139SigV4 requests require replayable, fully serialized request bodies. Standard JSON requests already meet this requirement, and response streaming is unaffected. Low-level one-shot request streams must be buffered before sending, or sent with bearer authentication and retries disabled.
1079 1140