Files
ai-contract-platform/project-docs/V2-P1-04.9.2-cloud-kms-rewrap-fault-drills-2026-08-25.md
T
yuqei 1d85329a6a
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 9m12s
Build and Test Quality Gate / Isolated Alibaba and Tencent KMS gateway (pull_request) Failing after 4m53s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 24m55s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 8m42s
feat: deliver governed contract platform and async AI tasks
2026-08-26 12:53:47 +08:00

8.2 KiB
Raw Blame History

P1-04.9.2 实施与验收报告:双云 KMS、旧密文重包裹与故障演练

日期:2026-08-25
状态:功能、迁移、接口、管理端、自动化与超级管理员 Chrome UAT 已完成;真实企业云凭据验收属于发布门禁,不以模拟结果代替。

1. 阶段目标

  1. 把 P1-04.9.1 的通用 KMS Gateway 契约落实为阿里云 KMS 与腾讯云 KMS 的真实官方 SDK 适配器。
  2. 为旧本地 Fernet 密文建立租户级清单、异步批量重包裹、回读校验、暂停/恢复/取消/失败重试及字段级证据。
  3. 实施托管服务不可用故障注入,证明超时、鉴权失败或提供方不可用时不会改写凭据。
  4. 实施 SLO 外部升级通知的预检和显式入队演练,覆盖真实通知派发、重试与死信状态回写。
  5. 保持合同 API 不持有云厂商 SDK 或 AccessKey,并避免阿里云 SDK 的加密库版本约束污染主服务。

2. 架构结果

2.1 隔离的双云 KMS 数据面

新增独立 yuqei-kms-gateway 服务。合同 API 仍只调用统一的 /v1/encrypt 与 /v1/decrypt,网关内部按部署选择:

  • 阿里云:KMS 实例 SDK、ClientKey、ClientKey 密码、KMS 实例 CA、专属 endpoint、AES_GCM、固定 AAD。
  • 腾讯云:KMS API 3.0 SDK、广州等国内 region、文件注入的临时或长期 API 凭据、固定 EncryptionContext。
  • 公共门禁:文件注入服务 Bearer token、key allowlist、4 KiB 明文上限、请求超时、错误脱敏、无重定向、生产 TLS。
  • SDK 依赖隔离:独立镜像或 .venv;合同 API 继续使用自己的 cryptography>=44,不加载云 SDK。

生产 Compose 提供阿里云、腾讯云两套互斥 overlay;网关容器只读、非 root、no-new-privileges,凭据与 TLS 材料均为只读挂载。

2.2 批量重包裹

重包裹对象覆盖企业日历源中的企业应用 secret、访问令牌、刷新令牌、增量游标,以及未过期 OAuth state 的 PKCE verifier。流程为:

  1. 按当前租户扫描带密文的允许字段,只保存表名、记录 ID、字段名、来源后端和 SHA-256 指纹。
  2. inventory 模式只生成清单与证据,不改写数据。
  3. execute 模式创建异步任务,Worker 按批次取得租约并逐字段处理。
  4. 每个字段先解开旧 envelope,再调用当前 KMS/Vault 加密,然后立即调用当前托管解密回读。
  5. 回读明文使用常量时间比较;只有摘要一致且数据库旧指纹未变化时才写入新 envelope。
  6. 并发更新、无法恢复、外部托管错误均转为 skipped 或 failed,不静默覆盖;任务支持暂停、恢复、取消和只重试失败项。

数据库和审计不保存重包裹明文。云厂商 CMK 的原生版本轮换由云 KMS 保持历史解密能力;本批处理专门用于把 P1-04.9.1 以前的本地 Fernet 密文迁移到当前外部托管后端,不支持在未同时配置来源适配器时跨两个外部托管后端直接搬迁。

2.3 故障演练

  • 托管不可用:在事务内注入 timeout、authorization、provider_unavailable 三种隔离故障,比较演练前后租户密文字段数量与聚合摘要;只有“写入被阻止且摘要不变”才成功。
  • SLO 外部升级:dry_run 检查通知通道已启用、握手通过且订阅 SLO 升级事件,不产生外部副作用。
  • 真实入队:需要精确确认短语 SLO_EXTERNAL_DRILL,只向显式选择的通道创建一条带 drill=true 的通知投递。
  • 投递 Worker 的 delivered、retry_scheduled、dead_letter 会回写演练账本,演练证据与普通 SLO 事件可区分。

3. 数据、接口与界面

迁移:20260825_0063。

新增表:

  • playbook_secret_rewrap_jobs
  • playbook_secret_rewrap_items
  • playbook_operational_drills

新增接口:

  • GET|POST /api/v1/enterprise-playbook/governance/secret-custody/rewrap-jobs
  • POST /api/v1/enterprise-playbook/governance/secret-custody/rewrap-jobs/{job_id}/actions
  • GET|POST /api/v1/enterprise-playbook/governance/operational-drills

超级管理员 Playbook 页面新增“旧密文盘点与批量重包裹”和“托管不可用与 SLO 外部升级故障演练”。危险操作有确认门禁,列表显示任务计数、字段状态、零写入证据与外部投递状态。

4. 发布门禁

正式切换前必须在隔离预发布环境完成:

  1. 选择一家云厂商 overlay,配置企业自己的 endpoint、CMK、ClientKey/API 凭据、CA、服务 token 和网络白名单。
  2. 网关 /health 返回 configured=true;合同 API 托管状态返回 production_ready=true。
  3. 执行一次 round_trip 和一次持久化 recovery_canary,摘要均匹配。
  4. 先创建 inventory 并导出任务计数;抽查目标记录当前指纹与业务可用性。
  5. 使用小批次 execute,确认成功、失败、跳过之和等于总数;失败项不得通过手工数据库覆盖。
  6. 运行三种托管不可用模拟,全部应为零写入。
  7. 对测试通知通道先 dry_run,再显式 enqueue;确认外部接收与系统投递证据一致。
  8. 完成全量重包裹并至少保留一个回滚窗口后,撤除旧 Fernet recovery key 文件。

5. 明确边界

  • 当前开发机没有用户企业的阿里云 ClientKey、腾讯云 SecretId/SecretKey、CMK 或私网白名单,因此没有发起任何真实云端加解密请求。
  • 自动化已在独立环境实际导入两家固定版本官方 SDK,并以假客户端验证精确请求模型、AAD/EncryptionContext、返回结构、key 校验与错误分类。
  • “SDK 已接入”不等于“客户云账号已验收”;真实云往返是不可跳过的发布门禁。
  • 本机没有 Docker,Compose overlay 已完成 YAML 与安全字段静态校验,镜像构建及容器健康检查需在部署节点执行。

6. 验收记录

  • KMS Gateway:阿里云与腾讯云官方 SDK 均可在隔离 .venv 导入;4/4 网关契约与错误脱敏测试通过。
  • 合同后端:358 collected,354 passed,4 skipped;无失败。新增测试覆盖远程重包裹回读、租户清单、乐观锁写入、管理员取消、三类零写入故障注入和 SLO 投递死信。
  • 前端:typecheck、全部 Node 测试与生产 build 通过;生成路由包含三组 P1-04.9.2 代理接口。
  • OpenAPI:120 paths / 180 schemas,YAML 与所有 schema 引用可解析。
  • 数据库:PostgreSQL 已升级到 20260825_0063 (head)。
  • 服务:Contract API 8100 health=ok,Web 3000 HTTP 200,AI API 8101 保持运行;Review 与 Playbook Governance Worker 均运行且错误日志为空。Schema check 只有本地环境既有的 anti-abuse disabled warning,其余数据库、迁移和治理检查均为 ok。
  • 超级管理员 Chrome UAT:账号 uat.legal.20260823@example.test、工作区“Playbook 隔离 UAT”;阶段标识为 P1-04.9.2,治理数据加载失败为 0,浏览器控制台错误为 0。
  • UAT 盘点:创建 playbook-secret-rewrap-3886d259f4fb,状态 inventory_complete,当前隔离租户没有需要迁移的密文字段,业务数据未改写。
  • UAT 托管故障:创建 timeout 模拟,状态 succeeded、write_blocked=true、external_side_effect=false,页面显示“零写入”。
  • UAT SLO 门禁:对已握手但停用的测试邮件通道执行 dry-run,结果按预期失败且 external_side_effect=false;真实发送按钮保持禁用并展示启用/握手/订阅要求,未发送外部消息。

7. 官方实现依据

详细发布、故障演练和回退步骤见 project-docs/playbook-cloud-kms-rewrap-fault-drill-runbook-2026-08-25.md。