Files
mnote/design/02-convex-rust-long-term-architecture/done/2-3-local-workspace-access-control-productization-v1.md
T
lix-2026 1956a8a21a chore: align mvp design governance
- 统一 local-first MVP 后阶段架构口径,补充 process 执行总序和 Reasonix 协作记录

- 归档已完成的 design checklist,标注参考型 process,更新 AGENTS/REASONIX/架构文档

- 补充文件树/主编辑器下载与上下文菜单相关实现、bug 记录和 smoke 脚本

验证:git diff --check;codegraph sync .;cargo test -p mnote-web;node --check scripts/task476-filetree-editor-context-menu-download-smoke.js
2026-05-21 09:04:13 +08:00

89 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2-3 [done] Local Workspace Access Control 产品化 checklist v1
> 创建时间:2026-05-19
>
> 当前状态:`DONE`
>
> 归档说明(2026-05-21):P0 管理员控制面 API 与 P1 权限覆盖审计已完成;管理员 UI/API、local folder open、page body write、tree command、Hermes/Reasonix 与 shared AI session 权限链已有代码与测试证据。后续授权产品化扩展应新开文档。
>
> 上位依据:
> - `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md`
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
> - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md`
>
> 目标:把已存在的 admin / owner / grant 本地目录权限模型产品化,形成管理员可管理、agent 可复用、全入口不绕过的控制面。
---
## 1. 当前已具备底座
- [x] 管理员身份支持 `MNOTE_ADMIN_USER_IDS`
- [x] 目录授权文件默认位置为 `/mnt/Data1T/Mnote_data/control-plane/access-policy.json`
- [x] 本地目录访问已有 admin / owner / grant 三层模型。
- [x] 普通用户不能访问未授权目录。
- [x] read grant 只能读,write grant 可写。
- [x] 读路径使用 `ensure_local_workspace_read_access`,写路径使用 `ensure_local_workspace_access`
---
## 2. 本轮 P0:最小管理员控制面 API
- [x] A1. 新增 `GET /api/admin/access-policy`
- 目标:管理员查看当前策略、策略文件路径、有效管理员来源和 grant 列表。
- 验证:单测覆盖非管理员 403、管理员可读。
- 实现:`rust/crates/mnote-web/src/routes/local_folder_source.rs` + `rust/crates/mnote-web/src/routes/mod.rs`
- [x] A2. 新增 `POST /api/admin/access-policy/validate-root`
- 目标:管理员输入 `rootUri``rootPath` 后返回 canonical path / rootUri,并拒绝不存在或非目录路径。
- 验证:单测覆盖合法目录、非法路径。
- [x] A3. 新增 `POST /api/admin/access-policy/grants`
- 目标:管理员添加用户目录授权,写入 `access-policy.json`
- 字段:`userId``rootUri/rootPath``permission=read|write``recursive``capabilities=[ai|share]`
- 验证:单测覆盖创建 grant、重复 grant 拒绝、非管理员拒绝。
- [x] A4. 新增 `DELETE /api/admin/access-policy/grants/{grantId}`
- 目标:管理员删除授权。
- 验证:单测覆盖删除后普通用户失去对应访问权。
---
## 3. P1:权限覆盖审计
- [x] B1. 审计 local folder open / default workspace / file open / asset upload。
- 结论:default workspace 走 owner manifestasset upload 走 write accessfile open 已从 write access 收口为 read access,并补 `local_file_open_allows_read_grant` / root escape 单测。
- [x] B2. 审计 page body write / documents compat save / title / options。
- 结论:`/api/page-body/write``documents/save`、title、options 在 local source 下统一走 `ensure_local_workspace_access` 后写本地 markdown / metadata。
- [x] B3. 审计 tree command / trash / restore / purge。
- 结论:tree snapshot 读路径走 read accesscreate / rename / copy / trash / restore / purge 写路径走 write access;已有 tree command local folder 单测覆盖。
- [x] B4. 审计 Hermes / Reasonix run allowed roots 与 AI tools。
- 结论:Hermes/Reasonix local ACP session 创建和 run 写入本地 private jsonl 前走 write access`mnote.doc.fetch` 直接本地文件读取改走 `ensure_local_path_read_access``mnote.page.get` 传递 `sourceKind/rootUri` 并校验 `aiAccessScope.allowedResourceIds`
- [x] B5. 审计 shared AI session read/write 不扩大 workspace 权限。
- 结论:AI tool 层补 `aiAccessScope.allowedResourceIds` 校验;共享只读场景下 markdown edit 仍禁止写入,验证见 `hermes_tools_markdown_edit_shared_read_is_forbidden`
---
## 4. P2:后续产品化
- [ ] C1. 管理员 UI:列表、添加、删除、validate root。
- [ ] C2. agent changed files / diff 审计落盘。
- [ ] C3. 权限策略变更 audit 记录。
- [ ] C4. share / ai capability 接入真实执行路径。
---
## 5. 本轮验证包
- [x] `cargo fmt --check --all`
- [x] `cargo test -p mnote-web local_access_policy -- --nocapture`
- [x] `cargo test -p mnote-web local_workspace_access -- --nocapture`
- [x] `cargo test -p mnote-web local_folder -- --nocapture`
- [x] `npm run check:local-first-convex-guard`
- [x] `git diff --check -- <changed-files>`
补充验证:
- [x] `cargo test -p mnote-web local_path_read_access -- --nocapture`
- [x] `cargo test -p mnote-web local_file_open -- --nocapture`
- [x] `cargo test -p mnote-web hermes_tools_doc_fetch -- --nocapture`
- [x] `cargo test -p mnote-web hermes_tools_page_get -- --nocapture`
- [x] `cargo test -p mnote-web hermes_client_local_acp -- --nocapture`
- [x] `cargo test -p mnote-web hermes_tools_markdown_edit_shared_read_is_forbidden -- --nocapture`