status: complete
| 时间 | 阶段 | 事件 | 备注 |
|---|---|---|---|
| 2026-07-26 | Research | 核实根密钥来源、配置优先级和全部 EncryptorFactory 调用点 |
确认根密钥间接保护持久化数据,不能直接替换 |
| 2026-07-27 | Proposal amendment | 增加启动前密钥自动引导和 Docker 持久化卷 | 用户明确要求启动自动注入,无需手工 export;历史 legacy key 仍不可推导 |
| 2026-07-26 | Research | 核实数据连接密码和低代码动态字段链路 | password_cipher 已有种子密文;生产 encrypt_config 状态未知 |
| 2026-07-26 | Research | 核实配置中心与通用配置分组旁路 | 数据库配置 addFirst,可覆盖环境/YAML;通用 CRUD 可读写原始 JSON |
| 2026-07-26 | Proposal 审查 | 补查 /system/config 散配置入口 |
读取已脱敏,但 insert/update 仍可写部署级 crypto key,已纳入 Spec |
| 2026-07-26 | Research | 核实浏览器会话密钥和固定 TypeHandler | 会话协议应保留;TypeHandler 为死代码,可删除 |
| 2026-07-26 | Proposal | 创建 Spec、Tasks、Test Spec 和执行日志 | 等待 HARD-GATE,未修改生产代码 |
| 2026-07-26 | HARD-GATE | 用户明确要求继续完成剩余任务 | 进入 /apply framework-crypto-key-lifecycle-hardening |
| 2026-07-26 | Apply A | 完成来源、数据库配置、API、UI、初始化 SQL 与死代码暴露面清理 | 非法 crypto JSON 读写失败关闭;Map 方括号键名旁路同步封堵 |
| 2026-07-26 | Apply B | 完成 FPC1 持久化协议及 Data/Generator 双读接入 |
默认仍写旧格式;浏览器会话密钥协议未改 |
| 2026-07-26 | Apply C | 完成 inventory/dry-run/execute、全 scope 预检和批次原子事务 | 未执行真实数据库迁移 |
| 2026-07-26 | Review | 完成 Spec Compliance 和 Code Quality 两阶段审查 | 修复批次事务、配置失败关闭、预检顺序、容量元数据和日志安全问题 |
| 时间 | 范围 | 命令 | 结果 | 警告/跳过 |
|---|---|---|---|---|
| 2026-07-26 18:54 CST | 四份 SDD 文档 | rg -n '[[:blank:]]+$' .../*.md;EOF `tail -c 1 |
od`;章节/状态断言;两处已知硬编码密钥精确扫描 | 通过:无尾随空白,四文件 EOF 均为 0a,Spec 13 章和 propose/HARD-GATE 状态存在,文档未复制历史密钥值 |
| Task | 时间 | Red 证据 | Green/构建证据 | 提交 | 备注 |
|---|---|---|---|---|---|
| Task 1-5(含 4B) | 2026-07-26 | 配置管理/旁路测试在旧合同下失败;非法 JSON 新用例 3 条中 1 条失败 | Config 8 条通过;System 防护 4 条通过;初始化值和历史密钥扫描通过 | 未提交 | 配置只保留非敏感功能开关,Flyway 清理数据库历史值 |
| Task 6-8(含 7B) | 2026-07-26 | 新协议、数据连接和低代码失败关闭行为在旧实现下不成立 | Crypto 22 条、Data 读写相关测试、Dynamic CRUD 生命周期测试通过 | 未提交 | SessionKeyStore、API Advice 和前端会话协议保持不变 |
| Task 9-11 | 2026-07-26 | 批次事务 Red 8 条中 6 条通过、2 条原子性断言失败 | 批次事务专项 12 条通过;最终 Data 7、Generator/System/Admin 22 条通过 | 未提交 | Data 使用 REQUIRES_NEW;低代码使用实际运行数据源事务管理器 |
| Task 12 | 2026-07-26 | — | 44 模块 test-compile/package、59 条隔离测试、前端 build、静态扫描通过 | 未提交 | 生产迁移和旧钥退役按设计跳过 |
| Task 13 | 2026-07-27 | 旧实现缺少启动前自动注入 | 启动引导 8/8,引导+原校验 15/15,Compose 解析通过 | 未提交 | 新安装自动生成并持久化;历史 legacy key 不可自动推导 |
| 决策 | 选择 | 放弃的方案 | 原因 |
|---|---|---|---|
| 密钥域 | 传输根密钥与持久化 keyring 分离 | 继续共用单一根密钥 | 避免 API 密钥轮换再次破坏持久化数据 |
| 密文协议 | FPC1:algorithm:keyId:payload |
直接替换旧 key | 需要兼容读取、定位 keyId 和受控迁移 |
| 发布策略 | 双读能力先发布,写入开关后切换 | 新版本一部署即写新格式 | 兼容滚动发布中的旧节点 |
| 迁移策略 | 管理员 dry-run/execute,按租户/configKey | Flyway 自动解密所有动态表 | Flyway 没有运行密钥和动态数据源上下文 |
| 动态表 DDL | 容量不足阻塞,不自动扩列 | 迁移器自动修改字段长度 | 外部数据源和业务表 DDL 风险过高 |
| 错误处理 | 解密失败关闭 | 把密文当明文或静默跳过 | 防止错误密钥被掩盖和敏感值错误流转 |
| 启动 Secret | EnvironmentPostProcessor + 外部稳定文件 | 每次启动生成、写入 Git/DB、运行后修改父环境 | 配置绑定前生效,又不会因重启或容器重建换钥 |
| 问题 | 原因 | 解决方案 | 沉淀? |
|---|---|---|---|
| 初步判断根密钥只用于 API 降级不完整 | 只追踪了直接 Advice 调用,遗漏 EncryptorFactory 的业务消费者 |
全仓搜索工厂注入和无参 encrypt/decrypt,确认两类持久化调用 | 已写入 pitfalls.md |
| 只改 YAML 仍可能不生效 | DB PropertySource 使用 addFirst |
同时移除 ConfigConverter 映射、配置 API 字段和数据库历史值 | 已沉淀 |
| 只封堵 config group 仍存在散配置旁路 | DbConfigLoader 同时加载 sys_config 与 sys_config_group |
共享精确密钥策略,拦截 /system/config 写入并由 Flyway同步清理 |
已沉淀 |
| 滚动发布会产生格式不兼容 | 旧节点不能识别版本前缀 | 增加 write-versioned 开关并固化发布顺序 |
已写入 decisions.md |
| per-row 捕获会破坏批次原子性 | 行级失败被吞掉后事务仍可提交前序更新 | 先准备整批,再在 REQUIRES_NEW 中执行;冲突/异常抛出触发整批回滚 |
已沉淀 |
| 只在各 scope 内校验会产生部分迁移 | Data 先写入后 Lowcode 参数校验失败 | Coordinator 在首次写入前预校验全部 included scope | 已沉淀 |
| 偏差点 | Spec 预期 | 实际情况 | 处理方式 |
|---|---|---|---|
| 每 Task 独立提交 | 每个实施 Task 使用独立提交 | 工作区在进入本变更前已有多组用户修改,且用户未要求代为提交;本轮未创建 Git commit | 保留按 Task 的验证和文件记录,不混入或提交用户其它变更;由仓库所有者按需要整理提交 |
| SQL Server 低代码迁移验证 | Tasks 初稿列出 MySQL/PostgreSQL/Oracle/SQL Server | 当前低代码运行时仅注册 MySQL/PostgreSQL/Oracle,仓库没有可复用的 SQL Server 完整方言 | 不在密钥变更中局部新增不完整方言;文档改为验证现有三种方言 |
| 生产迁移与退役 | 代码就绪后按 Runbook 执行 | 本地无真实 keyring、租户清单、备份和维护窗口 | 保持部署待办,不标记归零或退役完成 |
CryptoSecretEnvironmentPostProcessor,由 META-INF/spring.factories 在配置绑定前自动加载。0700、文件/锁 0600;非法字段、空值、非法 Base64、错误长度和符号链接失败关闭。CryptoConfigurationValidatorTest 合并执行 15/15 通过。SpringApplication 不依赖手工 export,Context 刷新前可读取根密钥和活动密钥。docker compose config --quiet 通过;Admin 挂载 crypto_secrets:/var/lib/forge/secrets,容器未启动。git diff --check 通过;相关 Java、注册文件和文档无尾随空白,EOF 均为 LF。META-INF/spring.factories 已注册 CryptoSecretEnvironmentPostProcessor;Admin/Report YAML 和 Docker Compose 均包含 bootstrap 配置,Admin 挂载 crypto_secrets 卷。-Penable-tests -DskipTests test-compile,44/44 模块成功,耗时 39.411 秒。mvn -pl forge-admin-server,forge-report-server -am package -DskipTests,44/44 模块成功,耗时 38.178 秒。pnpm build,8725 模块成功,耗时 1 分 33 秒;仅有既有命名冲突、动态/静态 import、CSS 注释和分块警告。git diff --check 通过;Flyway 最新版本 1.0.52、无重复版本、无占位符;受管源码/配置中的历史根密钥和旧种子密文均为 0;初始化 JSON 无部署密钥字段;EncryptTypeHandler 引用为 0;浏览器会话协议引用保留。