Skip to content

fix(ai): narrow OpenAI Responses relay session-affinity headers - #3715

Closed
grantjayy wants to merge 2 commits into
Yeachan-Heo:devfrom
grantjayy:fix/issue-3689-affinity-policy-20260801
Closed

fix(ai): narrow OpenAI Responses relay session-affinity headers#3715
grantjayy wants to merge 2 commits into
Yeachan-Heo:devfrom
grantjayy:fix/issue-3689-affinity-policy-20260801

Conversation

@grantjayy

Copy link
Copy Markdown
Contributor

Summary

  • preserve automatic OpenAI Responses session-affinity headers for the default OpenAI endpoint
  • allow custom OpenAI relays to opt in through the existing compat.sendSessionHeaders authority
  • exclude GitHub Copilot and every non-OpenAI provider, preserve explicit header precedence, and keep identity stable through repeated/provider-state replay

Checks

  • bun test packages/ai/test/openai-responses-cache-affinity.test.ts (11 pass, 0 fail)
  • bun --cwd=packages/ai run check
  • bunx biome lint packages/ai/src/providers/openai-responses.ts packages/ai/test/openai-responses-cache-affinity.test.ts
  • bunx biome format packages/ai/src/providers/openai-responses.ts packages/ai/test/openai-responses-cache-affinity.test.ts
  • independent adversarial review: PASS, no P0/P1/P2 findings

Fixes #3689

Supersedes closed PR #3690 by addressing the maintainer P1: affinity headers are now restricted to provider=openai, with custom relays requiring explicit opt-in; Copilot and other provider identities remain excluded.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed: Yeachan-Heo / bounded exact-head red-team review

VERDICT: REQUEST_CHANGES

Reviewed exact current head ef03b02b00398ddc0e13f43211f3dc446dde2c07 against current base/dev 547320dc26d045864994791fa4d013b91503e1e0. Exact Dev CI run 30708215470 and Public site sync 30708215467 are terminal green; the focused openai-responses-cache-affinity test and affected-path checks pass. GitHub reports CLEAN / MERGEABLE.

The relay opt-in boundary, provider exclusion, explicit-header precedence, and repeated/provider-session-state continuity tests are otherwise correct. However, the official-endpoint matcher is origin-incomplete: isDefaultOpenAIBaseUrl() accepts any URL whose hostname is api.openai.com and whose path is empty or /v1, without requiring the HTTPS scheme and default origin/port. Consequently, http://api.openai.com/v1, https://api.openai.com:8443/v1, and equivalent non-default-origin endpoints are treated as first-party and receive session_id and x-client-request-id automatically. Those headers carry the agent session identity and can disclose it to a proxy, alternate listener, or origin that is not the official https://api.openai.com origin.

The custom-relay opt-in is not a substitute for strict official-origin matching: it is appropriate for explicitly opted-in relays, while the implicit first-party path must be restricted to the canonical secure origin. Add focused negative tests for non-HTTPS and non-default-port api.openai.com URLs, then require https: plus the canonical port/origin before automatic header emission. Preserve explicit caller headers and the existing compat.sendSessionHeaders opt-in behavior.

No merge performed. #3694 was not touched.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

REQUEST_CHANGES

Reviewed exact head ef03b02b00398ddc0e13f43211f3dc446dde2c07 against current origin/dev c1bf3be50e2cf0dfdf51b57eb43f7a99521c94b8.

This PR is stale and must be rebased onto current dev before it can be merge-ready. The PR base is 547320dc26d045864994791fa4d013b91503e1e0, not the requested current baseline. I checked the relay-affinity change at packages/ai/src/providers/openai-responses.ts:106-113,498-500: default custom endpoints remain header-off, provider identity is restricted to openai, explicit opt-in is required for custom relays, and caller headers retain precedence. No additional credential-routing or privacy leak was found in this exact diff.

Focused verification at the exact head passed with OPENAI_BASE_URL=https://api.openai.com/v1 bun test packages/ai/test/openai-responses-cache-affinity.test.ts (11 pass). Please rebase and rerun this coverage against c1bf3be50e2cf0dfdf51b57eb43f7a99521c94b8; do not merge this stale head.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@grantjayy

Copy link
Copy Markdown
Contributor Author

Repaired at 4dc51fc: automatic Responses session-affinity headers now require HTTPS api.openai.com on the default port; added behavioral coverage for http://api.openai.com/v1 and https://api.openai.com:8443/v1. Explicit compat.sendSessionHeaders relay opt-in, caller-header precedence, and non-OpenAI exclusions remain covered. Merged current origin/dev normally. Verified: focused affinity test, packages/ai check, focused Biome check; current-head CI is terminal with no failures.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Census reassignment receipt: OpenAI Responses session-affinity transport batch reviewed for routing-contract overlap.

Exact head: 4dc51fc25a1fcd3d7a80e03e3a1e937f12ae2cd4. Current dev: bf37cb30d0442926ad3fb2b2c6fc26a6d3edeffc.

The changed files do not overlap MiniMax policy files, but this PR is not merge-ready: review changes are requested by Yeachan-Heo and its recorded base is stale relative to current dev. No mutation or merge was performed.


[repo owner's gaebal-gajae (clawdbot) 🦞]

Custom OpenAI relays could not opt into Responses session affinity without broadening header disclosure beyond trusted provider identities. Reuse the existing explicit compatibility authority while preserving first-party defaults and caller precedence.

Lore-id: issue-3689-affinity

Constraint: only provider=openai may receive Responses session-affinity headers

Constraint: custom relays require compat.sendSessionHeaders=true

Rejected: cache-retention gate | affinity identity must persist when retention is none

Confidence: high

Scope-risk: narrow

Reversibility: easy

Tested: bun test packages/ai/test/openai-responses-cache-affinity.test.ts

Tested: bun --cwd=packages/ai run check

Tested: biome lint and format checks for changed TypeScript files

Not-tested: live relay requests
Hostname matching allowed automatic session affinity headers over HTTP and non-default listeners.\n\nRestrict the trusted endpoint matcher to HTTPS api.openai.com on the default port while retaining explicit relay opt-in.\n\nLore-id: 3715-affinity-origin\nConstraint: preserve explicit compat.sendSessionHeaders relay opt-in\nConstraint: explicit caller headers retain precedence\nRejected: hostname-and-path matching | accepts alternate schemes and listeners\nConfidence: high\nScope-risk: narrow\nReversibility: straightforward\nTested: packages/ai/test/openai-responses-cache-affinity.test.ts; packages/ai check; focused Biome check
@grantjayy
grantjayy force-pushed the fix/issue-3689-affinity-policy-20260801 branch from 4dc51fc to 205cff1 Compare August 3, 2026 08:29
@Yeachan-Heo

Copy link
Copy Markdown
Owner

Signed: GJC / bounded AI transport owner review

VERDICT: REQUEST_CHANGES

Reviewed exact head 205cff1cc77eb7518653806604672862e25a297b against exact PR base 1d74b45ee4627951ece3c920c8e61280a80933c2. GitHub reports open, non-draft, clean, and mergeable. Exact-head Dev CI run 30797573286 and Public site sync run 30797573264 are terminal green; the affected @gajae-code/ai check and openai-responses-cache-affinity.test.ts job passed. There are no bot/automated reviews or inline review comments on this PR/head.

Blocking API-contract issue: packages/ai/src/providers/openai-responses.ts now uses model.compat.sendSessionHeaders to opt custom Responses relays into session_id plus x-client-request-id, but the public OpenAICompat.sendSessionHeaders contract in packages/ai/src/types.ts still explicitly scopes the flag to openai-completions and promises session_id plus x-session-id. That makes the same public option mean different wire headers depending on transport without documenting the Responses behavior, and the current provider-name gate also means an explicitly opted-in Responses-compatible relay whose provider id is not literally openai is silently ignored. The safety work itself is sound: automatic injection is restricted to HTTPS api.openai.com on the default port, arbitrary/custom origins default off, Copilot and other providers stay off, caller headers win, and retries retain stable defaults. Before merge, define the intended public contract: either document the transport-specific Responses semantics and provider-id restriction, or introduce a Responses-specific compatibility option and test the supported custom-provider case.

@Yeachan-Heo Yeachan-Heo closed this Aug 5, 2026
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