feat: 实现多 Provider 协议、SSRF 安全调用与 worker 原子尝试 (#19) #22

Closed
opened 2026-08-21 16:07:27 +08:00 by ila · 0 comments
Owner

基本信息

  • 类型:需求
  • 所属 Epic:#3
  • 所属 MVP / 版本:#19 / MVP-1
  • 阶段:已完成

原始需求

  • 来源:用户对话与已确认 MVP-1 技术设计、管理端原型 #17、用户端原型 #18。
  • 提出时间:2026-08-21
  • 脱敏摘要:按已确认 MVP-1 范围建立生产实现单元工单。

文档影响

  • 不影响长期文档,原因:本工单实现已确认设计;入口、契约、规则或验证方法确有变化时,在验收前更新相应核心 Wiki。
  • 更新项目档案或本地开发与验证
  • 更新架构与代码地图
  • 更新业务规则与术语
  • 更新常见修改或故障排查
  • 更新其他 Wiki 页面:

交付文档影响

  • 无交付文档影响,原因:本工单交付内部实现,最终用户操作文档待功能集成后统一评估。
  • 更新已有交付文档,受众与页面:
  • 新增交付文档,受众与页面:

变更控制

  • 不增加计费扣点、支付、配额、内容审核、公开注册、MVP-2 API Key/openapi 或其他已排除范围。
  • 不使用真实 Provider 额度进行调试;自动化与开发使用 mock。
  • 实施开始前复核依赖工单、工作区和已确认设计;完成后保持“待验收”,由用户明确验收后关闭。

依赖与并行

  • 前置工单:#20、#21
  • 是否允许并行:否;worker 依赖迁移和已确认路由核心契约。

目标与范围

实现 chat、images、images_edits、gemini 的能力匹配协议适配、mock 上游、SSRF 安全调用、worker 的 lease/attempt/CAS 流程和熔断 runtime 更新。

不实现管理员配置页面、portal 表单或真实 Provider 验收调用。

已确认方案

所有出站请求经过 DNS 解析后、连接前的 DialContext SSRF 拦截;认证仅支持 none/bearer/x-goog-api-key,extra_body 不得覆盖安全保留字段。worker 以当前 lease_token CAS 追加与完成 attempt;陈旧 token 所有最终写入均为 0 行;输出在 Succeed 前暂存,CAS 失败即清理。自动化仅调用 mock。

验收标准

  • 四种 api_type 的固定请求/结果、能力不匹配、base64/URL 限制和 Gemini inlineData 使用 mock 覆盖。
  • SSRF、认证 header、重定向、脱敏响应/错误与 extra_body 白名单被验证。
  • Begin/Finish/Succeed/Fail、lease 交接、attempt/provider_attempt_count、CAS 与输出清理保持原子一致。
  • 四类 retryable 换家与三类立即返回语义覆盖单元/集成测试。

验证

  • 运行 platform/worker/provider mock 测试、SSRF 回归与租约并发测试。
  • 不调用真实上游,不记录明文密钥或完整上游响应。

实施记录(2026-08-21)

  • 实现四种固定 Provider 协议、认证白名单、extra_body 保留字段拒绝和本地 mock;所有网络路径复用 DNS 后、连接前的 SSRF 拦截。
  • 将队列扩展为 Provider attempt 的 Begin/Finish lease-token CAS;每次上游调用持久化脱敏 attempt 并递增 provider_attempt_count,陈旧 token 的 Begin/Finish/Succeed/Fail 均影响 0 行。
  • 新增跨 worker GORMRuntime,按 enabled/能力/runtime 状态原子预留成员;half-open 同时只允许一个探测租约,成功关闭,retryable 阈值失败打开,401 立即打开。
  • worker 改为读取无密钥 RouteSnapshot、过滤已调用成员、加权无放回候选并按 retryable 红线执行;输出在 Succeed CAS 前暂存,CAS 失败清理。
  • 提交:35fd0342f0afcff5e6ae89b05079d1af4eb373e7,已推送至 main。
  • 验证:受影响包 race 测试、go vet ./...、go build ./...、隔离 MySQL 8 的 go test -count=1 ./...、Harness 检查和 Python 42 项测试均通过;只请求本地 mock,不调用真实 Provider。
  • 长期文档影响:无。实现落在 #16 已确认的协议、安全、worker 和 runtime 契约内,没有新增外部入口或业务规则。
  • 任务归档:Task-22-MVP-1-多-Provider-协议安全调用与-Worker-原子尝试,revision 119048e4cfed15641a69ca296928a7188704fcc3;未导出 docs/task/。

用户验收(2026-08-21)

  • 用户明确确认 #22 验收通过。
  • 实现提交:35fd0342f0afcff5e6ae89b05079d1af4eb373e7,已推送至 main。
  • 任务归档:Task-22-MVP-1-多-Provider-协议安全调用与-Worker-原子尝试,revision $archiveRevision;未导出 docs/task/。
## 基本信息 - 类型:需求 - 所属 Epic:#3 - 所属 MVP / 版本:#19 / MVP-1 - 阶段:已完成 ## 原始需求 - 来源:用户对话与已确认 MVP-1 技术设计、管理端原型 #17、用户端原型 #18。 - 提出时间:2026-08-21 - 脱敏摘要:按已确认 MVP-1 范围建立生产实现单元工单。 ## 文档影响 - [x] 不影响长期文档,原因:本工单实现已确认设计;入口、契约、规则或验证方法确有变化时,在验收前更新相应核心 Wiki。 - [ ] 更新项目档案或本地开发与验证 - [ ] 更新架构与代码地图 - [ ] 更新业务规则与术语 - [ ] 更新常见修改或故障排查 - [ ] 更新其他 Wiki 页面: ## 交付文档影响 - [x] 无交付文档影响,原因:本工单交付内部实现,最终用户操作文档待功能集成后统一评估。 - [ ] 更新已有交付文档,受众与页面: - [ ] 新增交付文档,受众与页面: ## 变更控制 - 不增加计费扣点、支付、配额、内容审核、公开注册、MVP-2 API Key/openapi 或其他已排除范围。 - 不使用真实 Provider 额度进行调试;自动化与开发使用 mock。 - 实施开始前复核依赖工单、工作区和已确认设计;完成后保持“待验收”,由用户明确验收后关闭。 ## 依赖与并行 - 前置工单:#20、#21 - 是否允许并行:否;worker 依赖迁移和已确认路由核心契约。 ## 目标与范围 实现 chat、images、images_edits、gemini 的能力匹配协议适配、mock 上游、SSRF 安全调用、worker 的 lease/attempt/CAS 流程和熔断 runtime 更新。 不实现管理员配置页面、portal 表单或真实 Provider 验收调用。 ## 已确认方案 所有出站请求经过 DNS 解析后、连接前的 DialContext SSRF 拦截;认证仅支持 none/bearer/x-goog-api-key,extra_body 不得覆盖安全保留字段。worker 以当前 lease_token CAS 追加与完成 attempt;陈旧 token 所有最终写入均为 0 行;输出在 Succeed 前暂存,CAS 失败即清理。自动化仅调用 mock。 ## 验收标准 - [x] 四种 api_type 的固定请求/结果、能力不匹配、base64/URL 限制和 Gemini inlineData 使用 mock 覆盖。 - [x] SSRF、认证 header、重定向、脱敏响应/错误与 extra_body 白名单被验证。 - [x] Begin/Finish/Succeed/Fail、lease 交接、attempt/provider_attempt_count、CAS 与输出清理保持原子一致。 - [x] 四类 retryable 换家与三类立即返回语义覆盖单元/集成测试。 ## 验证 - 运行 platform/worker/provider mock 测试、SSRF 回归与租约并发测试。 - 不调用真实上游,不记录明文密钥或完整上游响应。 ## 实施记录(2026-08-21) - 实现四种固定 Provider 协议、认证白名单、`extra_body` 保留字段拒绝和本地 mock;所有网络路径复用 DNS 后、连接前的 SSRF 拦截。 - 将队列扩展为 Provider attempt 的 Begin/Finish lease-token CAS;每次上游调用持久化脱敏 attempt 并递增 `provider_attempt_count`,陈旧 token 的 Begin/Finish/Succeed/Fail 均影响 0 行。 - 新增跨 worker `GORMRuntime`,按 enabled/能力/runtime 状态原子预留成员;half-open 同时只允许一个探测租约,成功关闭,retryable 阈值失败打开,401 立即打开。 - worker 改为读取无密钥 `RouteSnapshot`、过滤已调用成员、加权无放回候选并按 retryable 红线执行;输出在 Succeed CAS 前暂存,CAS 失败清理。 - 提交:`35fd0342f0afcff5e6ae89b05079d1af4eb373e7`,已推送至 `main`。 - 验证:受影响包 race 测试、`go vet ./...`、`go build ./...`、隔离 MySQL 8 的 `go test -count=1 ./...`、Harness 检查和 Python 42 项测试均通过;只请求本地 mock,不调用真实 Provider。 - 长期文档影响:无。实现落在 #16 已确认的协议、安全、worker 和 runtime 契约内,没有新增外部入口或业务规则。 - 任务归档:Task-22-MVP-1-多-Provider-协议安全调用与-Worker-原子尝试,revision `119048e4cfed15641a69ca296928a7188704fcc3`;未导出 `docs/task/`。 ## 用户验收(2026-08-21) - 用户明确确认 #22 验收通过。 - 实现提交:35fd0342f0afcff5e6ae89b05079d1af4eb373e7,已推送至 main。 - 任务归档:Task-22-MVP-1-多-Provider-协议安全调用与-Worker-原子尝试,revision $archiveRevision;未导出 docs/task/。
ila closed this issue 2026-08-21 21:10:28 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/chorus#22