Skip to content

fix(openai): normalize API key outbound client identity - #284

Merged
ranxi2001 merged 2 commits into
productionfrom
fix/openai-outbound-client-identity
Oct 3, 2026
Merged

ranxi2001 merged 2 commits into
productionfrom
fix/openai-outbound-client-identity

Conversation

@ranxi2001

Copy link
Copy Markdown
Owner

解决的问题与行为变化

  • 触发条件 / 原行为:OpenAI API Key 账号的普通 Responses、透传、Chat Completions 回退及部分辅助请求会把调用方的 User-Agent 原样发给上游。Go 客户端因此可能出现 Go-http-client/2.0,同时 originator、version 可能与客户端身份不配套。
  • 修改后行为:所有 platform=openai 的 API Key 账号默认使用现有 Codex 身份解析器生成配套的 User-Agent、originator 和 version。版本跟随后台 Codex 版本同步;账号显式 header_overrides 仍有最终优先级。
  • 覆盖范围:Responses、API passthrough、Chat Completions 及回退、WebSocket、input tokens、图片、Embeddings、alpha search、Responses 能力探测和账号测试。入站请求头与日志不修改,其他平台和 Prism/BPS 专用协议不改变。

关联记录与来源

  • Issue / 相关 PR:无。问题来源于线上请求记录中发现的 Go UA;截图中的上游 request ID 未取得,因此本 PR 不把某一条 429 归因于 UA。
  • 基线:production cf7398431cfd82ec1a9c7feca8a7b2b7f439d5c7。

复现与验收

  • 环境与基线:Sub2API production 源码,Go 1.27.0,本地 mock upstream;本 PR 未部署生产。
  • 前置条件与操作:
    1. 使用 API Key 账号构造 OpenAI Responses、透传、WS 或 Chat Completions 请求。
    2. 分别设置空 UA、Go-http-client/2.0、浏览器/SDK UA 和旧版 Codex UA。
  • 修复前观察:API Key 普通出站路径可保留调用方 UA;部分路径没有统一的 Codex 身份三元组。
  • 修复后观察 / 验收标准:出站 User-Agent、originator、version 来自同一规范身份;入站请求头仍保持原值;显式账号覆写和兼容性回滚开关保持有效。
  • 回归测试位置、覆盖的分支及未覆盖的情况:backend/internal/service/openai_apikey_identity_test.go 覆盖 34 个用例,包含 HTTP、透传、WS、测试请求、动态版本、覆写、回滚开关和其他平台;同时更新两个既有转发断言。没有真实上游抓包,也没有声称风控或 429 已由 UA 触发。

协议、调度或传输改动补充

  • 端点、模型映射、平台/账号类型、通道与 stream 模式:只改变 OpenAI API Key 出站身份头;请求体、模型映射、stream、调度和重试不变。
  • 是否改变重试/故障转移/幂等语义;请求已发出或流已开始后如何处理:不改变。
  • 并发占用、粘性状态、冷却与账号状态是否正确释放/保留:不改变。

实际验证

检查与执行目录 / 命令 结果 覆盖范围、证据或未运行原因
GOMAXPROCS=2 GOMEMLIMIT=3GiB go test -p 2 -tags=unit ./internal/service -run 'Test(OpenAIAPIKey.*Identity|AccountTestService_.*OpenAI|ProbeOpenAIAPIKey|.*CodexIdentity.*|.*OpenCode.*UserAgent.*|CommandCodeUpstream.*|.*HeaderOverride.*|.*AlphaSearch.*|.*Embeddings.*|.*CountTokens.*|.*OpenAIImages.*|ForwardAsAnthropic_ResponsesSupportedAccountStillUsesResponsesEndpoint|OpenAIGatewayService_APIKeyPassthrough_PreservesBodyAndUsesResponsesEndpoint)' -count=1 通过 当前 PR head 64885197d8eabb39256b5ab6023f11fa91e37654,相关 service 回归通过。
CGO_ENABLED=0 GOMAXPROCS=2 GOMEMLIMIT=3GiB go build -p 2 -o /tmp/sub2api-identity-check ./cmd/server 通过 本地 macOS arm64 编译检查,未嵌入前端,不是生产安装包。
git diff --check 通过 当前 PR diff 无空白错误。
完整 go test -tags=unit ./internal/service ./internal/config -count=1 未全通过 internal/config 通过;service 中 TestPriorityOAuthProfitUsesUserChargeAndTheoreticalCost 的浮点精度断言在未修改的 production 基线也失败(期望 4,实际 3.9999999999999996)。本 PR 未修改该逻辑。
集成测试 / golangci-lint 未运行 本机 Docker daemon 不可用,且本机没有 golangci-lint 可执行文件;本 PR 不声称这些检查通过。

兼容性与运行影响

  • 配置 / API / 默认行为:默认扩大 gateway.disable_codex_identity_enforcement=false 的统一身份范围至 OpenAI API Key;设置为 true 时 API Key 恢复原有头透传,作为兼容性回滚入口。
  • 数据库迁移、数据兼容与二进制回滚限制:不需要迁移;仅修改请求构造。
  • 权限、凭据脱敏、日志或采集内容:不新增凭据或日志采集;入站 UA 继续按原样记录。
  • 计费、资源开销、并发或性能:不改变计费、请求体、并发或重试;只增加少量 header 构造。
  • 灰度 / 回滚方式与残余风险:合并后可通过 gateway.disable_codex_identity_enforcement=true 回滚默认 API Key 身份统一。统一 UA 只能消除一类客户端身份差异,不保证上游不会因其他信号限流或风控。

文档与用户可见变化

新增 docs/openai-outbound-identity.md 说明身份优先级、覆盖范围和回滚开关。未部署、未发布 Release。

Agent 使用声明

  • Agent 名称与参与范围:Codex;分析线上 UA 来源、修改 OpenAI 出站请求构造、补充回归测试、更新文档和撰写本 PR。
  • 模型名称:GPT-6(Codex;完整部署模型 ID 未暴露)。
  • 推理强度:默认(未手动设置)。

提交前自查

  • base 分支和改动范围正确,没有夹带无关修改。
  • 正文、提交、测试数据和附件不含凭据、ticket/state 或真实用户敏感信息。
  • 实际验证结果已列出,失败、未运行和未覆盖的部分已说明。
  • 已检查配置默认值、权限、兼容性及相关文档;不适用项已说明。
  • Bug 修复有针对性回归验证,完整测试的既有浮点失败已单独说明。
  • 已填写 Agent 使用声明。

@ranxi2001
ranxi2001 merged commit 5bed808 into production Oct 3, 2026
18 checks passed
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.

1 participant