feat(auth): add X.509 workload identity federation for HTTP - #3622
feat(auth): add X.509 workload identity federation for HTTP#3622jbeckwith-oai wants to merge 11 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d83f5cb658
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 55e1460da3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5df57ae901
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2252fbe80f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e426fa535
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 145d3f2a02
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe8d0652b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe8d0652b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Security review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
What and why
Implement Phase 1 (HTTP only) of X.509 Workload Identity Federation in OpenAI SDKs: Design Proposal. Customers can exchange workload identity established by their existing mutually authenticated HTTP transport for an OpenAI access token without introducing SDK-owned certificates, private keys, token providers, or a configurable token endpoint.
Both
OpenAIandAsyncOpenAIsupport the same additive, typed public API:refresh_buffer_secondsis optional.WorkloadIdentityremains the existing callable, backward-compatible subject-token TypedDict; bothOpenAIandAsyncOpenAIaccept the explicit typed unionWorkloadIdentity | X509WorkloadIdentity.SubjectTokenWorkloadIdentityis a compatibility alias, and the publicWorkloadIdentityAuthconstructor remains narrowed to subject-token identities. The helper name, snake_case options, TypedDict configuration, SDK exception types, injected-client lifecycle, typedcopy()/with_options(), and explicit sync/async implementations follow neighboring Python SDK patterns. Azure/Bedrock overriding copy signatures retain Python-compatible parameter variance without changing their provider authentication behavior. Async refresh uses AnyIO-compatible locking and sleep; it never runs an asynchronous exchange through blocking thread work.Security, transport ownership, and compatibility
POST https://mtls.auth.openai.com/oauth/token; the JSON structurally omitssubject_token, the exchange URL is not public configuration, and redirects are disabled per request.expires_invalidation, half-TTL refresh-buffer clamping, sync and async single-flight refresh, cancellation-safe async waiters, bounded transient retries, andRetry-Afterhandling.https://mtls.api.openai.com/v1. Existing API-key authentication, JWT/ID-token workload identity, their separate exchange client, explicit base URLs, Python support policy, and dependency set are unchanged.Verification
./scripts/lintruff check .; changed-file formatting; 1,717 repository files format-clean after excluding one independently verified, untouched upstream baseline defectcompileall; both examples construct offline in API-key and X.509 modespython -m build --no-isolationgit diff --check; exact fourteen-path branch diff and clean committed worktreeThe focused X.509 tests cover exact host/path/body and absence of
subject_token, redirect refusal, transport/certificate ownership, transient retries andRetry-After, sync/async concurrency and cancellation, invalid/expired token responses and refresh windows, replayable versus one-shot upload/body behavior, safe error redaction, and API-key/JWT/ID-token regressions.Formatting baseline disclosure: the unmodified upstream
src/openai/resources/responses/responses.pyalready fails a whole-repositoryruff format --check .on the exact base revision. The repository's actual./scripts/lint, every changed file, and the other 1,717 files all pass; this PR intentionally does not modify unrelated generated code.Maintainability and Python idiom review
The required strict
thermo-nuclear-code-quality-reviewwas completed against the complete exact fourteen-file publication diff: no structural blockers. X.509 logic is isolated in one 269-line handwritten auth module; neither new production nor test files exceed 1,000 lines. Mode selection occurs once in each existing sync/async constructor, subject-token and X.509 implementations share one properly initialized generic auth/cache base without identity casts, existing auth/retry/error layers remain canonical, and sync/async differences stay explicit.The Python idiom review compared neighboring auth TypedDict/provider helpers,
OpenAI/AsyncOpenAIinjection and ownership, HTTPX/HTTPX2 request semantics, AnyIO cancellation, native SSLContext/transport boundaries, existing exception chaining/retry constants, pytest fixture style, and README examples. The result preserves established Python SDK naming, caller-client lifecycle, sync/async parity, and existing auth behavior without cross-language builder abstractions or hidden transport mutation.Refreshed upstream base:
10ee3f0da2ac6f93345c1204bd7bb1a2faa79ff2Validated publication head:
9512899eb98aab917ec9cf4c59342c77eb45c394Prior independent installed-artifact mTLS validation
Built the exact committed wheel with
.venv/bin/python -m build --no-isolation --outdir /private/tmp/openai-python-x509-round3-dist, installed that wheel into a clean temporary virtual environment, and executed/private/tmp/openai-python-x509-round3-venv/bin/python /private/tmp/openai-python-x509-second-round-e2e.pyfrom outside the repository. The harness generates an ephemeral CA plus fresh server/client certificates, requires and verifies client-certificate presentation on every local HTTPS request, and connects the unmodified native HTTPX2 transport to the exact pinned authentication and API origins through a hermetic local CONNECT proxy.Result: 19 sync/async scenarios passed; 48 real mTLS requests carried a verified client certificate (24 token exchanges, 24 API requests). Scenarios cover pinned host/path and token JSON without
subject_token, bearer injection, token caching, actual clock-based refresh, transient retry/Retry-After, 401 refresh/replay, non-replayable multipart uploads that invalidate rejected tokens without replay, typedwith_options()client copies that preserve their effective mTLS transport, async single-flight and waiter cancellation, sync/async timeouts, exchange/API redirect refusal including overridden auth, malformed token JSON, OAuth-error redaction, and the original callableWorkloadIdentitypublic API.Residual scope limitation: no customer-enrolled production identity provider was contacted or required; the independent end-to-end exchange uses a real local mutually authenticated TLS service with freshly generated certificates.
Current exact-head independent verification
Final independently verified head:
9512899eb98aab917ec9cf4c59342c77eb45c394; fresh mergeable base:10ee3f0da2ac6f93345c1204bd7bb1a2faa79ff2(zero commits behind).rye build --clean, installed the wheel into a freshly created virtual environment, and ran an external consumer through publicOpenAI/AsyncOpenAIwith a native HTTPX2 transport, ephemeral CA/server/client certificates, and a hermetic local CONNECT proxy. 32 independently reproduced scenarios passed over 78 real client-certificate-verified HTTPS requests: 38 exact-origin token exchanges and 40 API requests. The exchange body never containssubject_tokenand never inherits callerAuthorization; scenarios also prove actualBasicAuthsuppression, bearer injection, cache reuse/real-time refresh, transient retry, 401 replay and rejected-replay invalidation, real seekable multipart upload replay, one-shot upload invalidation, bidirectional API-key/X.509 mode switching, redirect refusal, timeout, cancellation/single-flight, typed/redacted errors, malformed identity rejection, and Azure boundaries../scripts/lintpasses Ruff, Pyright (0 errors / 0 warnings), mypy (1,547 source files), and import validation. Python support-policy validation, Python 3.9 wheel rejection, Bedrock wheel validation, HTTPX2/aiohttp/legacy wheel validation, README formatting, changed-file formatting, Python compilation, andgit diff --checkall pass.uv lock --checkfailure and one unrelated generated-fileruff format --check .failure are present unchanged on the exact upstream base; neither dependency locks nor generated baseline code were altered.