Skip to content

feat(auth): harden X.509 token lifecycle and tenant isolation - #2473

Merged
jbeckwith-oai merged 13 commits into
mainfrom
codex/x509-04-token-lifecycle
Aug 26, 2026
Merged

jbeckwith-oai merged 13 commits into
mainfrom
codex/x509-04-token-lifecycle

Conversation

@jbeckwith-oai

Copy link
Copy Markdown
Contributor

Summary

Part 4 of 5; based on codex/x509-03-client-integration.

  • Add tenant/account/certificate-scoped, generation-safe token caching, singleflight refresh, clone sharing, proactive refresh, and bounded 401 rotation.
  • Classify issuer/API transport failures privately: retry or temporarily reuse a still-valid bearer only for approved transient failures; permanent TLS, protocol, OAuth, and tenant failures are terminal.
  • Enforce exact tenant-header snapshots, reject underscore aliases, cancel abandoned refreshes/backoff, sanitize nested transport/body errors, and apply one monotonic deadline to successful and failing responses.

Verification

  • 243 focused lifecycle/security/transport/client regressions, including stale same-byte generations, repeated 401s, noncooperative abandoned refreshes, TLS trust failures, tenant aliases, and hung response bodies.
  • Exact minimum Node 22.22.0, pnpm lint, pnpm exec tsc --noEmit, pnpm build, and packed npm artifact checks.
  • Two independent security-review rounds and a completed full-stack Codex Security diff scan: zero remaining findings.

Next: codex/x509-05-e2e-docs-hardening.

@jbeckwith-oai
jbeckwith-oai requested a review from a team as a code owner August 25, 2026 19:27
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-08-26T03:34:45.548437Z 1038481 New commits
🔒 Security Review ✅ Completed 2026-08-26T03:36:26.094261Z 1038481 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9e9f746953

ℹ️ 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".

Comment thread src/auth/x509-transport.ts Resolved

@HAYDEN-OAI HAYDEN-OAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One additional fail-closed authentication issue is noted inline. The existing retry-timer lifecycle finding also remains unresolved; both should be addressed before approval.

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-03-client-integration branch from ba4e8c9 to d16c878 Compare August 25, 2026 20:53
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from 9e9f746 to 02d6e60 Compare August 25, 2026 20:53

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 02d6e60944

ℹ️ 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".

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-03-client-integration branch from d16c878 to 4bedd94 Compare August 25, 2026 21:17
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from 02d6e60 to c1c9ded Compare August 25, 2026 21:17

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1c9ded659

ℹ️ 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".

Comment thread src/client.ts Resolved
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-03-client-integration branch from 4bedd94 to 9cee783 Compare August 25, 2026 21:32
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from c1c9ded to 368ab64 Compare August 25, 2026 21:32
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ 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".

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from 368ab64 to c1aa772 Compare August 25, 2026 21:41
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-03-client-integration branch from 9cee783 to 8660250 Compare August 25, 2026 21:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1aa7722d0

ℹ️ 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".

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from c1aa772 to f1819b6 Compare August 25, 2026 21:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1819b6024

ℹ️ 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".

Comment thread src/client.ts Resolved
Comment thread src/client.ts Resolved
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch 2 times, most recently from 2cff517 to c409002 Compare August 25, 2026 22:14

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c409002bca

ℹ️ 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".

Comment thread src/client.ts Resolved
Comment thread src/client.ts Resolved
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from c409002 to 583118e Compare August 25, 2026 22:27
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

headerValue(headers, 'OpenAI-Organization') !== this.#organization ||
headerValue(headers, 'OpenAI-Project') !== this.#project

P2 Badge Normalize tenant selectors before exchanging credentials

When an enrolled selector contains leading or trailing HTTP whitespace (for example, organization: ' org_123 '), buildHeaders() trims it while #organization retains the raw value, so this comparison rejects the request only after getToken() has already performed the certificate exchange. The fresh evidence beyond the earlier mutable-accessor issue is Headers normalization of a single stable value; normalize or reject enrolled selectors before authentication and compare against that serialized snapshot.

AGENTS.md reference: AGENTS.md:L106-L110

ℹ️ 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".

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from 583118e to 71b69e9 Compare August 25, 2026 22:42

@HAYDEN-OAI HAYDEN-OAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the current stacked diff and all previously reported findings. Certificate-bound token caching and clone sharing now preserve tenant/request ownership and generations; refresh singleflight, suspend-aware expiry, transient-only fallback, bounded 401 rotation, Retry-After, cancellation/deadlines, and sanitized issuer/API failures are handled correctly. Verified the previous retry-timer, permanent-body-failure, tenant-alias/snapshot, hook-abort, and nested-clone-scope issues are resolved. No remaining substantive findings.

@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from 71b69e9 to 841bf72 Compare August 26, 2026 00:27
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-03-client-integration branch from 26f8641 to 67b4165 Compare August 26, 2026 00:27
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch 2 times, most recently from bba2956 to 83d01f1 Compare August 26, 2026 01:19
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch 4 times, most recently from 1f1d18e to 1c40590 Compare August 26, 2026 03:03

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c04436c813

ℹ️ 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".

Base automatically changed from codex/x509-03-client-integration to main August 26, 2026 03:16
## Summary

Part 5 of 5; based on `codex/x509-04-token-lifecycle`.

- Document the Node-only X.509 contract, refresh policy, bearer-token
handling, approved global endpoint, caller-owned dispatcher, and manual
live-validation workflow.
- Add a runnable example supporting both protected PEM variables and
documented local certificate-path/identity fixtures, encrypted keys,
explicit direct/CONNECT proxy modes, optional project selection, and
sanitized proxy failures.
- Extend the genuine local mTLS + CONNECT integration to verify cache
reuse, a real API 401, one token refresh/replay, renewed-token reuse,
issuer/API certificate identity/SNI, and zero proxy credential leakage.
- Add child-process regressions for malformed secret-bearing proxy URLs,
mismatched proxy modes, and ignored ambient proxies; verified against a
fresh checkout with no prebuilt `dist/`.

## Verification

- 246 focused X.509/client/transport/example regressions; exact minimum
Node 22.22.0; real ephemeral certificate/CONNECT wire test.
- `pnpm lint`, `pnpm exec tsc --noEmit`, `pnpm build`, packed npm
artifact/export checks, Node version-policy validation, and the trusted
custom-code budget check (2,791 / 3,000 lines).
- Two independent security/code-review rounds; full-stack Codex Security
diff scan completed across 12 production/package files with zero
findings.
- `pnpm test:live:x509` is intentionally manual and correctly fails
closed without owner-provisioned enrolled credentials; no
production-live success is claimed.
@jbeckwith-oai
jbeckwith-oai force-pushed the codex/x509-04-token-lifecycle branch from c04436c to 1038481 Compare August 26, 2026 03:31
@openai-sdks

openai-sdks Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

OkTest Summary

✅ 237/237 SDK tests passed in 11.434s for Node SDK PR #2473.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 161ms
tests/chat-completions-create.test.ts ✅ Passed 234ms
tests/chat-completions-stream.test.ts ✅ Passed 251ms
tests/files-content-binary.test.ts ✅ Passed 180ms
tests/files-create-multipart.test.ts ✅ Passed 167ms
tests/files-list-pagination.test.ts ✅ Passed 181ms
tests/initialize-config.test.ts ✅ Passed 189ms
tests/instance-isolation.test.ts ✅ Passed 134ms
tests/models-list.test.ts ✅ Passed 143ms
tests/responses-background-lifecycle.test.ts ✅ Passed 268ms
tests/responses-body-method-errors.test.ts ✅ Passed 458ms
tests/responses-cancel-timeout.test.ts ✅ Passed 251ms
tests/responses-cancel.test.ts ✅ Passed 250ms
tests/responses-compact-retries.test.ts ✅ Passed 300ms
tests/responses-compact.test.ts ✅ Passed 275ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 151ms
tests/responses-create-advanced.test.ts ✅ Passed 218ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.178s
tests/responses-create-errors.test.ts ✅ Passed 232ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 234ms
tests/responses-create-retries.test.ts ✅ Passed 348ms
tests/responses-create-stream-failures.test.ts ✅ Passed 273ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.169s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.825s
tests/responses-create-stream.test.ts ✅ Passed 101ms
tests/responses-create-terminal-states.test.ts ✅ Passed 236ms
tests/responses-create-timeout.test.ts ✅ Passed 263ms
tests/responses-create.test.ts ✅ Passed 284ms
tests/responses-delete.test.ts ✅ Passed 226ms
tests/responses-input-items-errors.test.ts ✅ Passed 210ms
tests/responses-input-items-list.test.ts ✅ Passed 211ms
tests/responses-input-items-options.test.ts ✅ Passed 131ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 261ms
tests/responses-input-tokens-count.test.ts ✅ Passed 260ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.404s
tests/responses-not-found-errors.test.ts ✅ Passed 368ms
tests/responses-parse.test.ts ✅ Passed 214ms
tests/responses-retrieve-retries.test.ts ✅ Passed 283ms
tests/responses-retrieve.test.ts ✅ Passed 199ms
tests/responses-stored-method-errors.test.ts ✅ Passed 585ms
tests/retry-behavior.test.ts ✅ Passed 3.155s
tests/sdk-error-shape.test.ts ✅ Passed 321ms

View OkTest run #32926803626

SDK merge (4f812e8a0109) · head (10384813d981) · base (ee5229b4aae0) · OkTest (2b1bdfd25e98)

@github-actions

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

32 mixed files remain; 1 existing customization changed.

Compared ee5229b4aae0 → 10384813d981. Generated baselines verified.

File Result Current custom patch
src/client.ts Existing customization changed +766 / −89
31 existing customizations unchanged
  • api.md
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py
  • src/resources/audio/transcriptions.ts
  • src/resources/audio/translations.ts
  • src/resources/beta/assistants.ts
  • src/resources/beta/beta.ts
  • src/resources/beta/index.ts
  • src/resources/beta/responses/internal-base.ts
  • src/resources/beta/responses/responses.ts
  • src/resources/beta/threads/index.ts
  • src/resources/beta/threads/runs/index.ts
  • src/resources/beta/threads/runs/runs.ts
  • src/resources/beta/threads/threads.ts
  • src/resources/chat/completions/completions.ts
  • src/resources/chat/completions/index.ts
  • src/resources/conversations/index.ts
  • src/resources/embeddings.ts
  • src/resources/files.ts
  • src/resources/fine-tuning/checkpoints/permissions.ts
  • src/resources/images.ts
  • src/resources/responses/internal-base.ts
  • src/resources/responses/responses.ts
  • src/resources/skills/skills.ts
  • src/resources/skills/versions/versions.ts
  • src/resources/vector-stores/file-batches.ts
  • src/resources/vector-stores/files.ts
  • src/resources/webhooks/index.ts
  • src/resources/webhooks/webhooks.ts
  • tests/lib/data-residency.test.ts

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 32926826038 --repo openai/openai-node \
  --name castiron-custom-code-32926826038-1 --dir /tmp/castiron-custom-code-32926826038-1
git apply --stat /tmp/castiron-custom-code-32926826038-1/custom-code.patch
cat /tmp/castiron-custom-code-32926826038-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin ee5229b4aae0778719c5d0a0f23ea90b74aa837b 10384813d9817f1c5cf96b537b3b498fa3ee872e
python3 scripts/castiron/custom_code_report.py report \
  --base ee5229b4aae0778719c5d0a0f23ea90b74aa837b \
  --head 10384813d9817f1c5cf96b537b3b498fa3ee872e --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-10384813d981
cat /tmp/castiron-custom-code-10384813d981/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@jbeckwith-oai
jbeckwith-oai added this pull request to the merge queue Aug 26, 2026
Merged via the queue into main with commit 6992683 Aug 26, 2026
35 checks passed
@jbeckwith-oai
jbeckwith-oai deleted the codex/x509-04-token-lifecycle branch August 26, 2026 04:32
@openai-sdks openai-sdks Bot mentioned this pull request Aug 26, 2026
gh-actions-shared Bot pushed a commit to xf-qubit/openai-node that referenced this pull request Sep 1, 2026
Raise the custom-code budget from 3,000 to 4,000 to unblock SDK
generation. Main currently uses 2,983 lines; the current generation
candidate uses 3,497, leaving 503 lines under the new limit.

These remaining customizations are technical debt. We do not have time
to address that debt at the moment, so this raises the budget to unblock
the work and defers the underlying cleanup.

Usage was 1,770 when the original budget landed in openai#2446. The increase
on main came from:

- Reporter and test changes: +696 lines in openai#2447 and openai#2464.
- X.509 client integration: +513 lines in openai#2472, openai#2473 and openai#2479.
- Webhook verification wiring: +4 lines in openai#2475.

Only `.castiron-ratchet.json` changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants