From 77d3da116fbfe876ddd2182d033f8fef31c9f7ce Mon Sep 17 00:00:00 2001 From: weichen Date: Sat, 12 Sep 2026 01:01:20 +0000 Subject: [PATCH] docs: add Phase 1 IAM and authorization implementation plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the database, PostgresAuthStore, AuthorizationService, and frontend capabilities workstream after Phase 0 security止血 is complete. --- ...12-phase1-iam-authz-implementation-plan.md | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 .doc/2026-09-12-phase1-iam-authz-implementation-plan.md diff --git a/.doc/2026-09-12-phase1-iam-authz-implementation-plan.md b/.doc/2026-09-12-phase1-iam-authz-implementation-plan.md new file mode 100644 index 00000000..b491f3fd --- /dev/null +++ b/.doc/2026-09-12-phase1-iam-authz-implementation-plan.md @@ -0,0 +1,99 @@ +# Phase 1:账户与授权权威化 Implementation Plan + +> **依据**:[2026-09-11-production-ready-workflow-governance-plan.md](./2026-09-11-production-ready-workflow-governance-plan.md) §5.2、§4、§12、Phase 1 +> **前置**:Phase 0 已合并(5 commits on `dev`,`8341168`) + +**Goal:** 登录、角色、权限、项目成员关系全部以数据库 + 服务端策略为唯一权威;前端只消费 `capabilities`;重启后会话/账户策略仍有效;禁用账户下一请求失效。 + +**Architecture:** Goose 迁移新增 IAM 表 → `PostgresAuthStore` 替换 `MemoryStore`(dev 可 feature flag 回退)→ `AuthorizationService` 统一 RBAC + `project_members` + admin 判定 → `/api/v1/auth/me` 返回 capabilities → 管理端用户/角色 API 持久化 → 前端移除 localStorage 权限权威。 + +**Tech Stack:** Goose、pgx、现有 `internal/auth`、`internal/authz`、React/Vite。 + +**明确不在本阶段:** 工作流版本模型、阶段 ABAC、capabilities 到每个 DocGov 动作的全覆盖(先系统 + 项目 + 已挂 authz 路由)。 + +--- + +## 完成门禁 + +| 门禁 | 判定 | +|---|---| +| 持久化账户 | 重启后 users/roles 仍在 DB | +| 持久化会话 | token 存哈希;logout/禁用立即失效 | +| 无 localStorage RBAC 权威 | `AdminSettingsModal` 读写 API;`hasPermission` 仅 UI 兜底并标注 deprecated | +| 项目成员 CRUD | 创建者可增删改成员;API 测试 | +| 负例 | 禁用用户 token → 401;跨项目已挂 authz → 403 | + +--- + +## 任务分解 + +### Task 1 — IAM 数据库迁移(`feat(db)`) + +新建 `deploy/postgres/goose/00015_iam_core.sql`: + +- `users`(id, username, display_name, email, status, department, employee_id, locale, timezone, created_at, updated_at) +- `user_credentials`(user_id, password_hash, password_changed_at, failed_count, locked_until) +- `auth_sessions`(id, token_hash, user_id, created_at, last_seen_at, idle_expires_at, absolute_expires_at, revoked_at, ip_hash, user_agent) +- `roles` / `permissions` / `role_permissions` / `user_role_bindings` +- seed:`role-admin` + 核心 permissions + 从 MemoryStore dev 用户回填(仅 dev/test 迁移脚本) + +约束:username unique;token_hash unique;至少一个 super-admin binding。 + +### Task 2 — PostgresAuthStore(`feat(auth)`) + +- `internal/auth/pg_store.go` 实现 `AuthStore` +- 会话:Login 写 `auth_sessions`(只存 SHA256(token));ValidateToken 查库 + 更新 last_seen +- Logout/RevokeAll 标记 revoked_at +- `server.go`:有 `ContextDbHost` 时用 PgStore,否则 dev 仍 MemoryStore + +### Task 3 — AuthorizationService(`feat(authz)`) + +- `internal/authz/service.go`:`Capabilities(ctx, userID) []string` +- `HasPermission(ctx, userID, perm, scope)` 组合系统 role_bindings + `project_members` +- 替换 scattered `role-admin` 硬编码 → `HasSystemPermission(..., "system.admin")` 或保留 admin role_id 映射 +- `requireAdmin` / `requireProjectAccess` 改调用 Authorizer + AuthzService + +### Task 4 — Auth API 扩展(`feat(api)`) + +- `GET /api/v1/auth/me` 增加 `capabilities: string[]` +- 会话列表/撤销(用户设置 Phase 1 最小版):`GET/DELETE /api/v1/auth/sessions` +- Admin users/roles CRUD 对齐 DB(现有 handler 改接 PgStore) + +### Task 5 — 项目成员 API(`feat(api)`) + +- `GET/POST/PUT/DELETE /api/v1/projects/{id}/members` +- 仅 owner/creator + `projects.members.manage` 可写 +- 与 `project_members` 表对齐;禁止把 author/reviewer/approver 写入成员 role + +### Task 6 — 前端 capabilities(`feat(web)`) + +- `authClient.me()` 缓存 capabilities +- `engine/rbac.ts`:`hasPermission` 优先读 capabilities;localStorage roles 只读迁移提示 +- `AdminSettingsModal` / `UserProjectRightsModal` 成员编辑走 API +- 移除 `loadRoles(DEFAULT_ROLES)` 作为权威初始化(保留 demo 数据只读展示直至导入完成) + +### Task 7 — 测试与报告(`test` / `docs(test)`) + +- `internal/auth/pg_store_test.go`(testcontainers 或 stub pg) +- `internal/authz/service_test.go` +- 扩展 `security_p0_test` + 跨项目 403(需 DB fixture) +- `.doc/test-reports/2026-09-12-phase1-iam-authz-test-report.md` + +--- + +## 建议提交节奏 + +1. `feat(db):` IAM goose migration + seed +2. `feat(auth):` PostgresAuthStore + session persistence +3. `feat(authz):` AuthorizationService + admin gate +4. `feat(api):` members CRUD + auth/me capabilities +5. `feat(web):` frontend capabilities consumer +6. `test(docs):` Phase 1 report + +--- + +## 风险 + +- **双写期**:MemoryStore 与 PG 并存时须单一 Store 注入,避免混用。 +- **ID 对齐**:现有 `projects.creator_user_id` / memory user id 与 PG users.id 迁移需一次性回填脚本。 +- **前端降级**:capabilities 未加载前 fail closed(禁用敏感按钮,不默认 allow)。