From 923537e9a17f4c3ba1ea5209f1d8624605141385 Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 12 Oct 2026 03:28:37 +0000 Subject: [PATCH 1/2] Add svc unified deploy and one-time login key proposal r1 Why: capture the reviewed design for binary/source install, env prep, and passwordless activation via one-time restricted sessions. Evidence: SELF source review against Dev af9c2de; implementation NOT_RUN. Impact: Documents planning index only; no runtime change. Refs: docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md Co-authored-by: Cursor --- ...-10-12-svc-unified-deploy-and-login-key.md | 182 ++++++++++++++++++ docs/proposals/INDEX.md | 4 +- 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md diff --git a/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md b/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md new file mode 100644 index 0000000..424a428 --- /dev/null +++ b/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md @@ -0,0 +1,182 @@ +--- +title: svc 统一部署与一次性登录 Key 方案 +type: feature +date: 2026-10-12 +artifact_contract: ce-unified-plan/v1 +execution: code +product_contract_source: ce-plan-bootstrap +--- + +# svc 统一部署与一次性登录 Key 方案 r1 + +确认状态:待人工评审。当前交付为源码调查、方案评审结论并入的正式提案,以及 U1/U4 规格细化;业务实施、测试、部署与运行验收均为 **NOT_RUN**。 +修订记录:r1=2026-10-12 草案经源码复核后定稿(四项取舍采纳;补齐 §6 合同;对齐恢复方案 KTD 与已合入的 recovery U1 实例身份)。 +需求来源:2026-10-12 用户提出将 `svc.sh` 增强为统一部署入口(二进制与源码、环境准备、无初始密码开户与账户恢复),并要求一次性 API Key 只能兑换「设置密码」受限会话。负责人:weichen;编制:Cursor Agent。 +主记录:本文;任务卡:Dev `.task/feature-svc-unified-deploy-login-key.md`。源码路径以 Dev 根目录为基准。 + +## 1. 目标与成功边界 + +**目标:在干净或既有机器上,用同一套 `svc` 入口完成二进制或源码部署、按档准备依赖,并通过后端账户能力完成无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话,完成设密前不能访问业务数据。** + +必须区分三类能力: + +| 能力 | 结果 | 非目标 | +|---|---|---| +| 统一安装 / 升级 | 指定版本或提交物化为可切换候选;切换后实例身份、DB、数据根与账户不变 | 不接管共享 PostgreSQL;不因发现端口而认领外部服务 | +| 环境检测与准备 | `doctor` 只报告;`env prepare` 按模式执行可幂等计划 | 不把任意发行版 Go/Node 标为可构建;工具链版本读自所选提交或发布清单 | +| 账户激活 / 恢复 | 无预设密码开户或签发恢复 Key;原子兑换 → 受限会话 → 设密 → 正常登录 | 不删除重建用户;不迁移业务归属;普通找回默认不撤销长期集成 Key | + +与 [服务重启与全量数据恢复方案 r2](2026-10-12-service-restart-data-recovery.md) 的关系: + +- **复用** KTD1–5、KTD12:持久 manifest、唯一监管者、team=PG 且失败不回落 SQLite、readiness 与身份。 +- **复用** 已合入的 recovery U1(Dev #415):`runtime//manifest.json`、启动身份校验、`svc init`、原子写路径(见 Dev `docs/recovery/u1-identity-manifest.md`)。 +- **本方案新增**:部署来源统一(binary/source)、doctor/env prepare、账户生命周期与一次性登录 Key、安装入口与双轨收敛。 +- 命名区分:**账户恢复 Key** ≠ **服务数据恢复**。 + +## 2. 当前事实及重点差距 + +源码基线(SELF·工作区观察,启动 precheck READY):Dev `af9c2de663be5ff102dcab7698464a645832f569`;Backend gitlink 以该提交为准;本地评审时曾对照 `3fa0d3a` / Backend `696ef15`,与当前 main 可能有漂移,实施前以 `task-sync` 后 SHA 为准。运行验收 **NOT_RUN**。 + +| 对象 | 已存在的基础 | 尚需补齐 | +|---|---|---| +| 部署来源 | `deploy --from local\|dev\|release\|rdm`;dev/rdm 独立缓存物化;release 读本地 Releases 仓并校验 sha256 | 远程下载/离线导入;统一 `install`;release@ver 钉扎(现 `sort -V\|tail -1` 取最大版本,见 `scripts/svc.sh` `resolve_release`) | +| 部署生命周期 | 预检失败不停机;预检通过后 **先停再构建**;无程序备份/自动回滚 | 候选获取与校验全程不停旧服务;缺摘要硬失败;迁移后回退独立判断 | +| 实例身份 | recovery U1:manifest + marker + init;`svc.env` 派生 | 账户 CLI 必须绑定实例最终配置;缺绑定拒绝,禁止回落 `./data` | +| 环境 | 端口/`flock`/pg 工具链按需检查;文档列前提 | `doctor` / `env prepare`;无 `flock` 时不得放行冲突操作(现状直通) | +| 账户 CLI | `user create\|reset-password\|list`;省略密码 → 随机明文一次 + `must_change` | 无密码创建 + 激活 Key;恢复 Key;OpenExisting(不建空库、不静默 migrate) | +| API Key | 明文只显示一次;可长期复用;无 TTL/次数 | **独立**一次性登录凭据表;不可走 Bearer/`?key=` | +| 强制改密 | 前端门控 + `/api/me` 标志;`changePassword` 要求原密码 | 服务端中间件拦截待改密/受限会话;设密分型(一次性会话不要求原密码) | +| 安装双轨 | Dev `svc deploy` 多实例;Releases `install.sh` 系统 systemd | 统一部署计划;`install.sh` 薄封装或明确遗留 | + +命题裁定(源码复核): + +1. 长期 API Key 是 **show-once plaintext,不是 single-use** — **成立**。 +2. **无**统一中间件拦截 `must_change_password` — **成立**。 + +## 3. 需求合同 + +| ID | 范围 | 要求与可判定验收 | +|---|---|---| +| R1 | 安装入口 | `doctor` / `install` / 兼容 `--from` 生成同一部署计划;二进制无需 Go/Node;源码固定提交且子模块组合可核验 | +| R2 | 实例身份 | 启停、升级、开户、签发 Key 命中同一 store 与 data 根;缺失/不符拒绝;与恢复案 R2/manifest 一致 | +| R3 | 切换安全 | 构建/下载/摘要失败时旧服务继续;程序+插件+前端作为版本组合切换;固定版本不得被「最大版本」替代 | +| R4 | 存储档 | team 默认 PG+auth;`existing` / `managed-local` / `local(SQLite)` 显式选择;PG 失败不回落 SQLite | +| R5 | 开户 | 无初始密码;角色明确;创建与激活 Key 同事务;同名冲突不覆盖 | +| R6 | 账户恢复 | 精确命中既有账户;不改密码/不吊销会话/不改业务数据于签发时;保持 owner/角色/成员关系 | +| R7 | 一次性 Key | ≥256bit、只存摘要、activate\|recover、默认 TTL 30min、状态机、原子兑换、专用 POST body | +| R8 | 受限会话 | 仅身份查询、设密、退出;业务/下载/SSE/admin/插件拒绝;普通 `must_change` 同样服务端限制 | +| R9 | 设密事务 | 写 hash、清待激活/待改密、作废未用恢复凭据、失效相关会话同事务;成功后销毁受限会话并要求密码重新登录 | +| R10 | 集成 Key | 普通找回默认保留长期 API Key;失陷恢复显式 `--revoke-all-credentials` | +| R11 | 首次管理员 | 仅核验为新实例(无用户且无历史业务标记);事务防并发;不得因「未发现管理员」接管有数据环境 | +| R12 | 证据 | 验收绑定固定源码/制品摘要/环境;SELF/REPLAY/GATE 分源 | + +## 4. 技术决策(KTD) + +KTD1. **部署方式只决定程序来源,不决定数据位置。** binary ↔ source 可切换;切换保持 DB、数据根、账户与 instance_id。 + +KTD2. **账户规则只在 Go 后端。** 脚本调用实例对应版本的 CLI;不直接改用户表。 + +KTD3. **一次性登录凭据独立于长期 `api_keys`。** 专用表与兑换 API;普通 Bearer、SSE `?key=`、长期 Key 路径均拒绝。 + +KTD4. **受限会话为独立 scope。** 默认 10 分钟;allowlist 仅 me / 设密 / logout。 + +KTD5. **团队安装默认 PostgreSQL;存储选择显式。** 与恢复 KTD5、`config.Tier=team` 一致。 + +KTD6. **一次性 Key 默认 30 分钟**(可配置建议范围 5–120 分钟);审计记实际 TTL。 + +KTD7. **激活/恢复设密成功后必须重新密码登录**(销毁受限会话、清 cookie)。普通主动改密可保留「要求原密码」路径;激活路径不要求原密码。 + +KTD8. **普通账户恢复默认保留长期集成 Key;失陷显式撤销全部凭据。** 两种情况均保留业务数据。 + +KTD9. **候选校验完成前不停旧服务**;切换短窗;schema 迁移后能否自动回退旧程序另行判断,失败不自动用备份覆盖业务库。 + +KTD10. **双轨收敛到同一部署计划。** 新旧 CLI 同后端;Releases `install.sh` 变为薄封装或文档降级为遗留,禁止第三套生命周期。 + +## 5. 职责划分与接口示例 + +| 部分 | 负责 | +|---|---| +| `svc.sh` | doctor、env prepare、获取制品、构建、实例配置、生命周期、调用账户 CLI | +| 后端 CLI | 创建账户、签发/撤销一次性 Key、核验目标库、OpenExisting、操作审计 | +| 后端认证 | 原子消费 Key、受限会话、设密事务、中间件限制 | +| 登录页 | 输入一次性 Key、设密、过期/重发提示;遵循 `DESIGN.md` | +| 发布制品 | 版本、平台、摘要、组件版本、能力声明 | + +拟新增 CLI(当前脚本尚不支持;兼容 `--from` 保留): + +```bash +./svc.sh doctor --mode binary --tier team +./svc.sh install prod --mode binary --version <固定版本> +./svc.sh install prod --mode source --repo <仓库> --ref <固定提交> +./svc.sh prod deploy --mode binary --version <固定版本> +./svc.sh prod user create --owner alice --role user +./svc.sh prod user issue-login-key --owner alice --purpose recover +./svc.sh prod user list +./svc.sh prod user revoke-login-key --id <凭据编号> +``` + +Linux 服务账户与应用账户分开管理。 + +## 6. 规格合同(实施前必须写进 U1/U4,否则返工) + +1. 独立凭据类型 + `POST` body 兑换 API。 +2. 会话 scope / 中间件 allowlist;覆盖 `must_change` 普通首登。 +3. 设密接口分型:受限会话不校验原密码;普通改密继续要求原密码;同事务完成写 hash / 清标志 / 作废 Key / 吊销会话。 +4. 密码未设置状态:`password_hash` 可空或 sentinel;`VerifyLogin` 拒绝未设密;创建 = 用户行 + 激活 Key 同事务。 +5. CLI `OpenExisting`:目录/DB 不存在则失败;运维模式可禁止自动 migrate / 要求 schema 兼容。 +6. `release@` 必须解析到该版本目录;缺摘要硬失败。 +7. 部署:获取/构建/校验不停旧服务;组合切换;迁移后回退独立判断。 +8. `install` 与 `--from` 同一计划;双轨收敛(KTD10)。 +9. 首次管理员仅新实例;事务防并发。 +10. 凭据交付:交互 stdout 一次 / 非交互 `chmod 600` 文件;日志与 evidence 只记凭据 ID;随机密码路径首期可并存但默认无密码 + Key。 +11. 无 `flock` 时拒绝冲突生命周期与账户操作(收紧现状「直通」)。 + +详细设计(正文在 Dev 仓,随本任务分支提交): + +- U1:`docs/svc-deploy/u1-instance-account-binding.md` +- U4:`docs/svc-deploy/u4-one-time-login-key.md` + +## 7. 增量与完成门槛 + +| 增量 | 主要范围 | 完成条件 | +|---|---|---| +| **U1** 实例—账户绑定补齐 | 账户 CLI 读实例 manifest;OpenExisting;锁缺失拒绝;install 骨架对接既有 identity | 开户/签发命中同一 store;错误 data/DSN 拒绝;与 recovery U1 字段对齐 | +| **U2** 二进制与源码来源 | 下载/离线导入、仓库物化、版本清单、候选先校验 | 无开发仓可部署;固定版本与摘要可核验;修复 release 钉扎 | +| **U3** 环境检测与准备 | 系统适配器、依赖计划、专用工具链、监管配置 | Ubuntu/Debian 首验;幂等;不接管共享服务;binary 不装 Go/Node | +| **U4** 一次性凭据与认证限制 | Backend CLI/Store/Server/迁移 | 原子开户/兑换/设密;受限会话无法调业务 API;并发兑换单胜 | +| **U5** 脚本与登录页接线 | 账户命令、首次管理员、凭据交付、Login/设密页 | 新建与恢复走通;刷新与异常可续;DESIGN.md | +| **U6** 组合与故障验收 | Dev 组合、发布包、真机、数据保护 | 两种部署 × 存储档;故障注入;浏览器 + 真机;治理回归 | + +**近期优先 U1、U4**(可并行兄弟分支、共用 R0)。跨仓顺序:Backend(U4)→ Frontend(U5)→ Dev gitlink + `svc.sh`(U1/U2/U3/U5);组合 `make test` 后宣称可合入。 + +### 必须覆盖的验收场景(摘要) + +干净机器二进制安装;源码固定提交与子模块;两种部署互切后数据不变;构建/摘要/配置失败旧服务可用;PG 身份不符拒绝且不回落 SQLite;无密码开户且不覆盖既有;同 Key 并发兑换仅一次成功;受限会话拒业务/SSE/admin;消费后建会话失败与设密中途失败无半完成态;恢复前后业务与权限对账;SQLite 与真实 PG;治理回归;源码测试不代替浏览器与真机。 + +额外钉住:`release@v` 多版本不得装成更高版本;账户 CLI 不得回落默认 `./data`。 + +## 8. 一次性 Key 流程 + +```mermaid +flowchart LR + A["创建账户或签发恢复 Key"] --> B["输入一次性 Key"] + B --> C["后端原子消费"] + C --> D["仅允许设置密码的短期会话"] + D --> E["设置并确认新密码"] + E --> F["作废恢复凭据及相关旧会话"] + F --> G["使用新密码正常登录"] +``` + +凭据规则:独立前缀;只存摘要;用途 `activate`|`recover`;状态未使用/已消费/已撤销/已过期;密码变更后旧恢复凭据不可再用。符合 [OWASP Forgot Password](https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html) 与 [Session Management](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html);保留现有 CSRF 校验。 + +## 9. 风险与未授权范围 + +- 实施、故障注入、真机部署、浏览器验收:**未授权 / NOT_RUN**。 +- 本任务交付终点:正式提案 r1 + U1/U4 规格 + 任务卡与索引入口;推送/PR 须另获授权。 +- 与 recovery U1 重叠处只做增量,不重做已合入的 manifest 层。 + +## 10. 规划进展与下一步 + +- 本次推进:源码复核;四项取舍定案;正式提案 r1;U1/U4 规格细化。 +- 首选下一任务(**待授权**):并行启动 U1 实施与 U4 实施(兄弟分支、共用 R0);U2/U3 规格可随后写作但不阻塞 U1/U4。 +- 前置:人工批准本提案 r1(至少需求表 + 方案设计 + U1/U4 实施计划阶段);实施前 `make precheck` 与 `task-sync`。 diff --git a/docs/proposals/INDEX.md b/docs/proposals/INDEX.md index 38d3571..802a45b 100644 --- a/docs/proposals/INDEX.md +++ b/docs/proposals/INDEX.md @@ -168,7 +168,9 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围 ## 2026-10-12 规划补充 -- [服务重启与全量数据恢复方案 r2](2026-10-12-service-restart-data-recovery.md):2026-10-12 用户要求 svc 停止/再次启动及异常退出后恢复所有服务与数据;覆盖服务依赖/监管、持久配置和数据身份、run/HITL/命令/通知、未知副作用隔离、文件一致性与组合备份。r1 经六角色自审,r2 吸收外部源码复核(见同名 review 记录两轮)。**2026-10-12 用户批准 r2(五阶段一并)**;实施/故障注入/部署/运行验收 NOT_RUN。关联协作存储 R7;U2 首切片已由 svc-autorecover 任务合入 main(PR #396/#401,2026-10-11),余量按 KTD1/KTD2 对齐后续增量。 +- [svc 统一部署与一次性登录 Key 方案 r1](2026-10-12-svc-unified-deploy-and-login-key.md):将 `svc.sh` 增强为二进制/源码统一部署入口,并补齐无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话。r1 含源码复核与四项取舍定案;复用恢复方案 KTD 与已合入的 recovery U1(Dev #415)。**待人工评审**;实施/测试/部署/运行验收 NOT_RUN。近期优先 U1(实例—账户绑定)与 U4(一次性凭据);规格见 Dev `docs/svc-deploy/`。 + +- [服务重启与全量数据恢复方案 r2](2026-10-12-service-restart-data-recovery.md):2026-10-12 用户要求 svc 停止/再次启动及异常退出后恢复所有服务与数据;覆盖服务依赖/监管、持久配置和数据身份、run/HITL/命令/通知、未知副作用隔离、文件一致性与组合备份。r1 经六角色自审,r2 吸收外部源码复核(见同名 review 记录两轮)。**2026-10-12 用户批准 r2(五阶段一并)**;实施/故障注入/部署/运行验收 NOT_RUN。关联协作存储 R7;U2 首切片已由 svc-autorecover 任务合入 main(PR #396/#401,2026-10-11);U1 实例身份已合入(Dev #415,2026-10-12),余量按 KTD 对齐后续增量。 ## 2026-10-11 规划补充 From 7df7d786d0a87293c8605608e4845f7e59b9be3b Mon Sep 17 00:00:00 2001 From: weichen Date: Mon, 12 Oct 2026 03:32:55 +0000 Subject: [PATCH 2/2] Record r1 approval for svc unified deploy proposal Why: user approved the proposal and U1/U4 specs and authorized push/PRs plus U1/U4 implementation start. Evidence: SELF conversation approval 2026-10-12; implementation still NOT_RUN. Impact: planning status only. Refs: docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md Co-authored-by: Cursor --- docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md | 4 ++-- docs/proposals/INDEX.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md b/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md index 424a428..1a28135 100644 --- a/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md +++ b/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md @@ -9,8 +9,8 @@ product_contract_source: ce-plan-bootstrap # svc 统一部署与一次性登录 Key 方案 r1 -确认状态:待人工评审。当前交付为源码调查、方案评审结论并入的正式提案,以及 U1/U4 规格细化;业务实施、测试、部署与运行验收均为 **NOT_RUN**。 -修订记录:r1=2026-10-12 草案经源码复核后定稿(四项取舍采纳;补齐 §6 合同;对齐恢复方案 KTD 与已合入的 recovery U1 实例身份)。 +确认状态:**已批准**(2026-10-12 用户「批准,继续推进」:需求拆解→实施计划五阶段及 U1/U4 规格一并批准;授权推送/PR 与启动 U1/U4 实施;合入仍由 owner 执行)。业务实施、测试、部署与运行验收在批准时仍为 **NOT_RUN**,由后续实施任务推进。 +修订记录:r1=2026-10-12 草案经源码复核后定稿(四项取舍采纳;补齐 §6 合同;对齐恢复方案 KTD 与已合入的 recovery U1 实例身份);同日获批并进入推送与 U1/U4 实施。 需求来源:2026-10-12 用户提出将 `svc.sh` 增强为统一部署入口(二进制与源码、环境准备、无初始密码开户与账户恢复),并要求一次性 API Key 只能兑换「设置密码」受限会话。负责人:weichen;编制:Cursor Agent。 主记录:本文;任务卡:Dev `.task/feature-svc-unified-deploy-login-key.md`。源码路径以 Dev 根目录为基准。 diff --git a/docs/proposals/INDEX.md b/docs/proposals/INDEX.md index 802a45b..dfb1ff0 100644 --- a/docs/proposals/INDEX.md +++ b/docs/proposals/INDEX.md @@ -168,7 +168,7 @@ RDM 总案把库分期作为支撑与依赖,不覆盖库分期的原始范围 ## 2026-10-12 规划补充 -- [svc 统一部署与一次性登录 Key 方案 r1](2026-10-12-svc-unified-deploy-and-login-key.md):将 `svc.sh` 增强为二进制/源码统一部署入口,并补齐无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话。r1 含源码复核与四项取舍定案;复用恢复方案 KTD 与已合入的 recovery U1(Dev #415)。**待人工评审**;实施/测试/部署/运行验收 NOT_RUN。近期优先 U1(实例—账户绑定)与 U4(一次性凭据);规格见 Dev `docs/svc-deploy/`。 +- [svc 统一部署与一次性登录 Key 方案 r1](2026-10-12-svc-unified-deploy-and-login-key.md):将 `svc.sh` 增强为二进制/源码统一部署入口,并补齐无初始密码开户与账户恢复;一次性登录 Key 只能兑换设密受限会话。r1 含源码复核与四项取舍定案;复用恢复方案 KTD 与已合入的 recovery U1(Dev #415)。**2026-10-12 已批准**(五阶段+U1/U4 规格);授权推送/PR 与 U1/U4 实施启动;合入由 owner 执行。规格见 Dev `docs/svc-deploy/`。 - [服务重启与全量数据恢复方案 r2](2026-10-12-service-restart-data-recovery.md):2026-10-12 用户要求 svc 停止/再次启动及异常退出后恢复所有服务与数据;覆盖服务依赖/监管、持久配置和数据身份、run/HITL/命令/通知、未知副作用隔离、文件一致性与组合备份。r1 经六角色自审,r2 吸收外部源码复核(见同名 review 记录两轮)。**2026-10-12 用户批准 r2(五阶段一并)**;实施/故障注入/部署/运行验收 NOT_RUN。关联协作存储 R7;U2 首切片已由 svc-autorecover 任务合入 main(PR #396/#401,2026-10-11);U1 实例身份已合入(Dev #415,2026-10-12),余量按 KTD 对齐后续增量。