83 行
6.9 KiB
Markdown
83 行
6.9 KiB
Markdown
# 生产管理员 break-glass 密码重置:执行计划
|
||
|
||
> 当前状态:RESET COMPLETE / REVIEWED。用户已于 2026-08-09 批准并完成本任务认证恢复生命周期;生产写入、强制改密、最终验证与敏感材料清理均已完成,合同业务验收仍留在原 readiness task。
|
||
|
||
## 1. 规划事实
|
||
|
||
- [x] 任务边界:只恢复唯一管理员认证生命周期,不做合同/员工负向验收。
|
||
- [x] 现有脚本具 `--preflight`、`--verify`、`--verify-password-changed`、`--diagnose-wecom-binding` 四个只读入口,以及精确 `ACTIVE_ADMIN_BREAK_GLASS` 写入确认串。
|
||
- [x] apply 事务内二次校验目标;session/challenge updateMany 均限定 `target.id`。
|
||
- [x] 脚本使用应用同源 bcrypt、强制改密、token/session/challenge/audit 合同;当前脚本自产品候选以来未变化。
|
||
- [x] npx/Playwright 运行条件可用;密码不得进入 CLI argv/env,执行时使用从 stdin 读取凭据的一次性 Playwright runner,新会话、零 retry,不新增 test spec。
|
||
- [x] 旧 hash 仅是短期高敏有限恢复材料,不是完整/部分状态回滚。
|
||
|
||
## 2. 启动门禁(规划复核后)
|
||
|
||
- [x] 用户完成规划只读复核并明确批准 task start。
|
||
- [x] 用户批准按本任务合同执行生产管理员认证恢复;批准范围包含脚本完整副作用与强制改密的两次密码写入,不包含任何业务页面或合同验收。
|
||
- [x] 规划提交 `8806521` 已 published,执行前工作区 clean;原 readiness task 保持 `LOGIN PAUSED`。
|
||
- [x] 本地 focused unit test 6/6 与 node syntax PASS。
|
||
- [x] 生产 identity/read-only preflight 为 13/13,65 migrations 全 applied、pending=none,产品 build 匹配候选,窗口为 `OPEN/0`。
|
||
- [x] 运行容器脚本 SHA 与产品候选精确一致,未复制或替换生产脚本。
|
||
|
||
## 3. 生产执行清单
|
||
|
||
### Phase A:只读前置
|
||
|
||
- [x] 运行脚本 `--preflight`,结果为 PASS/1/true。
|
||
- [x] 运行写前 `--diagnose-wecom-binding`:目标唯一且已绑定,无绑定冲突;近 30 分钟密码/企微登录与失败计数均为 0。
|
||
- [x] 写前快照为 must-change=false、locks cleared、active session=1、两类 active challenge=0;该会话过去 24 小时无活动,近 30 分钟无认证活动,按批准副作用撤销。
|
||
- [x] 创建远端 `0700/0600` recovery material 并验证存在;hash 与实际路径均未回显或进入任务证据。
|
||
- [x] 生成互不相同且不复用旧 secret 的临时/最终强密码,存入本机 `0600` 临时 secret;未进入 env/argv/history。
|
||
|
||
### Phase B:唯一 break-glass 写入
|
||
|
||
- [x] 写入本地 attempt 哨兵后,从 stdin 执行一次且仅一次 `--apply ACTIVE_ADMIN_BREAK_GLASS`;`applyExecutionCount=1`。
|
||
- [x] apply 结构化结果 PASS/1:passwordUpdated、mustChangePassword、tokenVersionIncremented、locksCleared、auditCreated 均为 true;撤销陈旧会话 1,失效两类 challenge 均为 0。
|
||
- [x] apply 通道与结果完整,没有进入 `APPLY_UNCERTAIN`;attempt 哨兵保留至最终清理,执行期间不存在第二次 apply 路径。
|
||
- [x] 紧随 apply 的 `--verify` 七项 PASS:唯一目标、must-change=true、locks cleared、active sessions=0、两类 active codes=0、audit present=true。
|
||
|
||
### Phase C:secret 与强制改密
|
||
|
||
- [x] `--verify` PASS 后原子更新仓库外 live-smoke admin identifier/temp password,现场复核内容匹配且权限为 `0600`;第一次本地更新未改变文件并被匹配检查挡住,修正后才进入登录,没有消耗登录次数。
|
||
- [x] 一次性 Playwright runner 通过受控文件描述符读取凭据,新会话登录 1 次并确认跳到 `/change-password`;零 retry。
|
||
- [x] 强制改密提交 1 次;成功到 `/portal` 后立即清理并关闭,非认证业务 API 在客户端被阻断,实际发送数为 0。
|
||
- [x] `--verify-password-changed` PASS:must-change=false、locks cleared、active sessions=1,两类审计均存在。
|
||
- [x] 仓库外 live-smoke admin secret 原子更新为最终凭据,内容匹配且权限仍为 `0600`。
|
||
- [x] 写后 `--diagnose-wecom-binding` PASS:目标与绑定仍唯一、无冲突;本轮 1 次密码登录、0 次失败,未修改企微绑定。
|
||
|
||
### Phase D:清理与交接
|
||
|
||
- [x] 删除本机临时 secret、Playwright storage/cookie 和远端旧 hash;`temporaryCredentialDestroyed=true`、`browserStateCleared=true`、`recoveryMaterialDestroyed=true`。
|
||
- [x] 源码与 apply 结果确认 session/challenge 写入均限定唯一目标;浏览器业务 API 发送数 0,合同/schema/权限/其他账号写入为 0。
|
||
- [x] 最终生产只读 preflight 为 13/13,migration pending=none,`rollbackWindow=OPEN / terminatedRows=0 / basis=terminated_status_count`。
|
||
- [x] 只读 reviewer 已核对脱敏执行记录、源码与单测;两轮收口 finding 修正后最终结论为 `PASS`,且未宣称 reviewer 独立重跑生产。
|
||
- [x] 向 `08-08-production-authenticated-readiness` 只交接“最终管理员 secret 已就绪”,不交接值;合同验收继续由该任务完成。
|
||
|
||
## 4. 允许与禁止的输出
|
||
|
||
| 阶段 | 允许 | 禁止 |
|
||
| --- | --- | --- |
|
||
| preflight/SHA | PASS、count、match 布尔 | 主机、路径、账号、email |
|
||
| apply/verify | status、副作用布尔/计数、apply 次数 | 临时密码、新旧 hash、token |
|
||
| browser | 路由阶段、submit 次数、HTTP 状态 | 表单值、cookie、storage、截图中的账号 |
|
||
| cleanup | destroyed/cleared 布尔 | recovery material 路径/内容 |
|
||
|
||
## 5. 规划门禁
|
||
|
||
- [x] `cd server && npm test -- tests/unit/scripts/reset-active-admin-password.test.js`:PASS,6/6。
|
||
- [x] `node --check server/src/scripts/reset-active-admin-password.js`:PASS。
|
||
- [x] `python3 ./.trellis/scripts/task.py validate 08-09-production-admin-break-glass-reset`:PASS。
|
||
- [x] `node scripts/qa/check-process-contract.mjs --baseline --json`:PASS,0 errors / 0 warnings。
|
||
- [x] `node scripts/qa/check-trellis-governance.mjs --json`:PASS,0 errors / 0 warnings。
|
||
- [x] `node scripts/qa/check-sensitive-content.mjs`:PASS,0 findings。
|
||
- [x] `git diff --check`:PASS。
|
||
|
||
## 6. 执行记录与当前结论
|
||
|
||
- 写前辅助 SHA 探测首次误用 `docker compose`,在进入容器前被远端 legacy Compose 能力拒绝;随后按部署脚本的实际选择改用 `docker-compose`。该失败为只读调用错误,账号/数据库写入为 0。
|
||
- 写前 break-glass 审计基线为 1;写后为 2,增量恰好 1。token version 相对写前基线上升,且 apply 返回自身 token increment 断言为 true。
|
||
- 唯一 apply、唯一登录、唯一强制改密均已完成;最终 secret 可用性由应用登录和 `--verify-password-changed` 双重证明。
|
||
- 敏感恢复材料与一次性凭据均已销毁,不再保留 24 小时恢复窗口。该销毁不影响已经写入的审计与最终密码。
|
||
- 当前只完成管理员认证恢复,不代表合同登录态验收通过。只读 reviewer 已完成;下一步恢复 `08-08-production-authenticated-readiness`。
|