FR-048 全站統一授權守門 — 完工 SUMMARY(2026-07-07 收尾)

user 已手測通過全部 phase(含 4b 五件與 4a 語意變化確認)。branch fix/v1.8.0-bugs,未 push。 起源:FR-047 spec 手冊已知坑盤點 §SEC 桶(75 條)→ 實查升級為全站系統性缺口 → 一天內設計拍板 + 六波落地。

1. 一句話

把「寫入端點只有 JWT、無角色守門」的全站缺口,收斂成 common/authz/ 單一守門機制(五軸), 全站 373 支寫入端點逐支判軸掛守,RBAC capability 從「只藏 FE 按鈕」變成 BE 真 enforce。

2. 最終形態(開發者視角)

  • canonical 只有一個common/authz/(決策表在其 __init__.py),禁止另立 helper。
  • 兩層半模型:主體層 RBAC(capability/platform-admin/super-admin=break-glass)+ 資源層成員資格(project/SSP/workflow 單軸三解析器)+ signed-token(免 bearer 投遞)。
  • 雙軌放置:主體域守門=route decorator(@require_capability / @require_platform_admin_route); 資源域守門=app service 層(assert_project_manager / assert_project_role / assert_project_participant / SspPermissionChecker / workflow guard)。
  • 能力點單一真相:BE 守門讀的=FE 角色矩陣勾的(121 顆既有 granular cap,動詞精準對 HTTP verb); super_admin 為 break-glass 旁路。

3. 六波落地(BE 48 commits + FE 1 commit)

Phase 內容 關鍵 commits
設計 五軸模型/兩層半/全站盤點定 scope/P1–P4+D1–D15+Q1/Q2 拍板 4aa8edce b2270dab f97e8fd5
1 common/authz/(4 套搬家 shim+require_super_admin 正名)+CLAUDE.md 回寫 69e043c4 ee21764a
2a 全站 373 支端點授權矩陣(8 subagent 盤點+交叉驗證 75 pit) f0c8d304
3 主體域 decorator+116 支掛點+插隊件(schedule-report 任意檔讀取、debug mail route 移除)+C 類 22 處 inline is_admin 收編 f462c2a8249d293a
2b/2b-2/2b-3 資源域補守(grc D6/D7/D8、SSP export、PSR、留言、batch-complete)+flow_engine 守門復活(v2 鏈)+evidence_classification 統一 manager+MF 敏感 GET+D14 補 JWT 80514dff 0f50bbd0 a83a8619
2c 7 份私有 _check_* 收編 assert_project_role 委派(行為保真)+AR manager 代行對齊(user 定調) 616d84dc 9bb154b4
4a capability guard(memoize+break-glass)+seed migration(3 組缺口,DEV 已套)+35 檔換裝、@require_super_admin_route 歸零 eb590ae4 7828653e e8b28a4a
4b signed-token 機制+五件免 bearer 端點(otp-qrcode 自我限定/框架下載/file 雙軌/survey/task-survey 判 dead);FE 79c0133(17 檔) 40a7d9c5

4. 行為差異(user 已逐項手測)

  1. 系統管理頁寫入(user/role/org/設定/選單/設備/公告/問卷/範本…):無對應能力點的帳號 → 403 GRC_CAPABILITY_REQUIRED持 Administrator 角色的一般帳號可過(放寬到 RBAC 正軌);super_admin 恆過。
  2. GRC 專案寫入:非該專案 manager(或規定角色)→ 403;AR 寫入 manager 可代行 auditor(對齊全站 override)。
  3. flow_engine 任務/證據:非該專案參與者 → 403(守門自 FR-038 停用以來首次恢復)。
  4. 免 bearer 端點:QR/下載改走 120 秒簽章 token;otp-qrcode 只能拿自己的(原「知 uid 拿他人 TOTP」洞關閉); file download 雙軌、既有 axios 呼叫方零影響。
  5. 未認證洞全關:log export(SEC-001)、schedule-report 任意檔讀取、debug 寄信 route、issue/get_members、MF 靜態範本。

5. 規範文件

  • 設計:docs/analysis/2026-07-07-unified-auth-guard-design.md(拍板紀錄 P1–P4+兩層半模型+反悔條件)
  • 台帳:endpoint-authz-matrix.md(373 支逐支狀態,§6–§9 各 phase 落地紀錄)— living tracker,後續改權限先看這份
  • 追蹤:docs/analysis/2026-07-07-known-pits-remediation-tracker.md §SEC(75 條銷帳)
  • 手冊:Notion「Guidant AI 權限控管使用手冊」(本次收尾新建,見 Notion)
  • CLAUDE.md 權限段+docs/claude/domain-capabilities.md 已於 Phase 1 回寫

6. Follow-ups(未完事項)

說明
e2e 兩條 4b 前科件(QR 顯示/框架下載)在 test repo 補;含負向案(登出直打→401)+token 過期實測
STG/POC migration 2026-07-07-fr048-phase4a-capability-seed.sql 只套了 DEV,部署前要套
push BE 48+FE 1 commits 全未 push,等 user 指示
頁面 spec §權限矩陣批次更新 67 頁 spec 的權限段與新守門對齊(FR-047 手冊模式,量大另排)
api-spec 新端點補登 4b 新增 token 發放端點(otp-qrcode-token / oscal token / file access-token / survey token)
Phase 5(另案) 守門下沉 jedi-auth service、platform-admin→capability 併軸、context enrich 評估、process/comments PUT
零星 subtask_status_history 隨 v1 退役;D 族資訊洩漏(issue token 明文等)在其他桶

7. 部署 handover

  1. 套 STG/POC migration(cmmgr、--single-transaction
  2. 部署 BE+FE 必須同版(4b 的 token 流程 BE/FE 成對,只上一邊會壞 QR/下載)
  3. 部署後煙測:登入→個資頁 QR、框架 OSCAL 下載、任一檔案下載、一般帳號打系統設定寫入 403