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