跳轉到

系統管理 功能群總覽

本檔放「本功能群多個頁面共用的知識」:頁面地圖、三層 RBAC 權限模型、租戶/部門/使用者組織模型、system_configs key-value 慣例、角色權限基調、核心資料模型。

各頁面 spec 引用本檔,只寫自己頁面的差異——改共用邏輯時改這裡一份。

事實基準:2026-07-05 從 FE src/config/router/index.js + BE routes.json / db_schema.json + docs/system-design/permission/ 設計說明書掃出;§1 頁面地圖、§2 權限模型、§5 角色基調 2026-10-08 依 FR-132 實作(jedi-iam 判定層、本機 DEV DB)重掃。

變更紀錄:2026-10-08 FR-132 —— 存取管理四頁取代角色權限管理;權限改三段式名稱、角色存萬用字元規則;208 項權限全部真擋

1. 頁面地圖

本功能群是產品的「後台設定層」,橫跨權限治理(存取管理 / 選單 / 使用者)、組織主檔(租戶 / 部門 / 設備 / 資訊系統)、系統參數(通知 / SMTP / LDAP / 議題整合 / 工具外掛)與稽核與個人(操作日誌 / 個人資料)四塊。

頁面 FE route 用途一句話 spec
存取管理:角色 /access/roles 角色列表、新增複製刪除、匯出匯入角色 JSON ✅ 角色
存取管理:角色明細 /access/roles/:uid(+ /access/roles/new) 權限樹勾選、可見選單即時預覽 ✅ 角色明細
存取管理:指派 /access/assignments 誰 × 角色 × 範圍 × 起訖日;到期自動失效 ✅ 指派
存取管理:檢查存取 嵌在指派頁(?check=<uid>) 某人每項權限的來源角色、到期日、可見選單 ✅ 檢查存取
使用者管理 /auth/user-manage(+ user-form) 帳號 CRUD、所屬租戶與部門、帳號頁的角色、批次匯入、狀態切換 ✅ 使用者管理
選單管理 /system/system-menu-manage system_menus group/key 選單項維護 ✅ 選單管理
部門管理 /department/department-manage org_units 樹狀部門 CRUD ✅ 部門管理
租戶管理 /tenant/tenant-manage tenants 樹狀租戶 CRUD ✅ 租戶管理
設備管理 /device/device-manage devices 設備主檔 CRUD+Excel/CSV 匯入匯出;檢測線逐台型目標的授權來源 ✅ 設備管理
授權掃描網段 /system/scan-zone tenant_scan_zones 租戶授權網段(網段型掃描目標必須落在內;agent 心跳下發);只給租戶管理員改 ✅ 授權掃描網段
資訊系統盤點 /information-system/manage compliance.information_systems 稽核範圍系統主檔 ✅ 資訊系統盤點
通知頻道設定 /system/notify-config system_configs NOTIFY group(Telegram / Discord)+ 測試寄送 ✅ 通知頻道設定
SMTP 伺服器設定 /system/smtp-config(-manage) system_configs SMTP group + 測試寄送 ✅ SMTP 伺服器設定
LDAP 設定 /system/ldap-config system_configs LDAP group + 連線測試 ✅ LDAP 設定
Log 轉發設定 /system/log-forwarding 系統 log 轉發到客戶自有 log 平台(Syslog / GELF)+ 測試送出 ✅ Log 轉發設定
議題整合設定 /system/issue-integrate-config GitLab / GitHub 整合(餵回饋鏡像) ✅ 議題整合設定
工具外掛管理 /plugin/tool-plugin-manage 外部檢測工具 / 外掛模組管理 ✅ 工具外掛管理
掃描設定檔管理 /plugin/detection-profile-manage 檢測工具掃描設定檔(profile / content)庫——公用版+租戶自有雙軌 ✅ 掃描設定檔管理
弱點資料庫 /system/vulndb 第三方元件風險掃描用的弱點資料:日期、上傳更新包、連網檢查更新、更新紀錄(全機共用) ✅ 弱點資料庫
操作日誌 /log/user-log api_logs 稽核軌跡查詢(不含 system_logs,見頁面 spec §1) ✅ 操作日誌
個人資料 /user/user-profile 自身資料 / 改密 / MFA(TOTP)設定 ✅ 個人資料
License 授權管理 /license/manage 平台方對客戶租戶發照/換照/停權/查授權歷程(root 專屬) ✅ License 授權管理
我的授權狀態 /license/status 租戶側唯讀:自己的模組集 / 到期日 / 現處階段 ✅ 我的授權狀態
背景服務與排程 —(無 UI) 全系統背景 job / 排程 / socket / 心跳盤點 ✅ 背景服務與排程
錯誤追蹤站 —(產品外,/bugsink/ 子路徑) 落地版內建錯誤追蹤站:三個專案、收件開關、遮罩、前端與 Agent 轉送 ✅ 錯誤追蹤站

sitemap(/sitemap,「網站導覽」)已除名:router 有孤兒條目 + menu.json 有 label,但 public.ui_routes 無對應列(非選單項)、FE 全域零 nav 進入點,屬 dead route(比照已除名的 project-task-setup)。功能本身(SiteMap.vue)只是把 permissions[0].items 畫成 OrganizationChart,未獨立成頁。

舊「角色權限管理」(/auth/role-manage、/auth/role-form)已退役,舊網址轉到存取管理;舊規格 留作對照。

user-form-mtrbac(/auth/user-form)是使用者管理表單的 multi-tenant RBAC 變體,併入使用者管理 spec。smtp-config-manage 是 SMTP 設定的列表 / 管理變體,併入通知 / SMTP spec。

2. 三層 RBAC 權限模型(全群樞紐,先讀)

Guidant AI 採 Role-Based Access Control:使用者經指派取得角色、角色以規則涵蓋一組權限、權限決定 API 能不能用與選單看不看得到。判定在 jedi-iam 套件。

flowchart LR
  U["使用者"] -- "指派 user_roles<br/>範圍 × 起訖" --> R["角色 roles"]
  R -- "規則 role_capability_patterns<br/>例 grc.project.*、*.*.read" --> C["權限 capabilities<br/>module.resource.action"]
  C -- "API 守門" --> API["放行/403"]
  C -- "route_capabilities ALL/ANY" --> M["側欄選單可見"]
層級 表 說明
使用者 public.users 帳號本體
指派 public.user_roles 使用者 × 角色 × 範圍(scope=tenant/org_unit、tenant_id、org_unit_id)× 起訖(starts_at/ends_at)
角色 public.roles 屬於某租戶;is_system=內建系統管理員、is_template=出貨範例
角色規則 public.role_capability_patterns 角色 × 規則字串;判定唯一來源
權限 public.capabilities 三段名;is_platform、license_module、enforce_mode、home_route_name
路由 ↔ 權限 public.route_capabilities 進頁門檻(ALL 全要/ANY 任一)
UI 路由 public.ui_routes 選單樹;is_menu=出現在側欄、tree_page=角色樹上的子頁

role_capabilities(角色 ↔ 權限 id)已退役、不再寫入。

2.1 權限名與萬用字元

  • 三段式:<模組>.<資源>.<動作>,三段小寫、資源名內用連字號,例 grc.project.approve、system.ldap-config.update。共 208 項,12 個模組:grc、oscal、flow、detection、evidence、survey、system、iam、platform、asset、ai、workspace。
  • 動作:每個資源固定 read/create/update/delete;另有 approve、close、publish、export、assign、import、execute——只給「給了 update 卻不想一起給」的動作。
  • 萬用字元規則:grc.*.*(某模組全部)、*.*.read(全部唯讀)、*.*.*(全部)。含星號的規則會自動涵蓋日後新增的權限;畫面勾選則存具體權限名,不自動合成星號。
  • 內建系統管理員:規則固定 *.*.*,每租戶恰一個,不可改不可刪。出貨另附四個範例角色(稽核主管、稽核員、一般成員、唯讀),可改可刪可複製,見 角色 §4。
  • 原廠層權限(platform.*,is_platform=true):只有原廠(總部)租戶的角色可持有,且端點另要平台管理員身分,兩道都過。

2.2 判定規則

  1. 只採計有效指派:期間內、角色與帳號都啟用、屬當前租戶。到期的指派仍列在指派頁並標「已到期」,但判定與選單不再採計。
  2. 把有效指派的角色規則展開成權限集合(Redis 快取,鍵含權限目錄版本號)。
  3. 要的權限在集合內就放行,否則 403 GRC_403022,回應帶缺的權限名(data.required),畫面顯示「使用者不具備此操作所需的權限(需要權限:<權限名>)」。
  4. 208 項權限全部真擋(enforce_mode=enforce)。
  5. 部門範圍目前只當屬性:指派可記部門,判定上與整個租戶相同;部門資料隔離本版不做。

任務情境通則:

通則 規則
A 任務情境看任務權限 在任務/專案頁做的事看 grc.job.*/grc.project.*,不看功能模組自己的權限(任務頁開始掃描=grc.job.update,不是 detection)。例外:已結案問卷的內容與檢測工具執行紀錄,持 grc.job-evidence.read(檢視任務證據)亦可讀
B 挑選名單看呼叫頁權限 下拉、挑選用名單看當下頁面的權限,被挑模組的 read 只管它自己的管理頁;挑人、挑部門豁免
C 一支 API 服務多種資源 先解析資源歸屬,再判單一權限,不開「擇一放行」

升級時自動補授:權限改名時,角色上的勾選跟著改名;拆出的權限依「升級前由什麼把關」補給既有角色——升級前由某權限守的補給持有那項的角色;升級前只驗登入的補給既有角色;全新功能只補管理員角色。系統管理員與出貨範例不補(前者本來就涵蓋,後者照定稿)。

2.3 選單可見性(GET /user/web-menu)

BE 依使用者的有效權限集合,對每個 ui_routes 節點:

  1. 無需求(route_capabilities 無設定)→ 預設可見(「登入即可見」)
  2. ANY 命中任一 → 可見
  3. ALL 全部擁有 → 可見

外加 ui_routes.enable=1 與授權照過濾。慣例:read 設 ALL(無讀權限看不到選單)、寫入類設 ANY。側欄、角色明細的可見選單預覽、檢查存取、前端路由守門都走同一條判定(/user/web-menu、/ui-routes/visible-by-capabilities、/users/me/capabilities)。頁內按鈕另依各自權限隱藏,沒有權限的按鈕不顯示。

新功能要進角色樹被勾選授權:在程式碼宣告 Capability(含 home_route)→ ui_routes → route_capabilities → FE route 與 v-can;守衛測試 test/test_fr132_capability_home_route.py 擋「沒綁頁又沒填歸屬頁」。

3. 租戶 / 部門 / 使用者 組織模型

系統是多租戶架構:租戶(tenants)為頂層、可樹狀階層;部門(org_units)隸屬租戶、亦可樹狀。使用者可屬多租戶、多部門。

組織模型:tenants 樹→org_units 樹;users 帶預設 tenant/org,多對多關係存 user_tenants(is_default) / user_org_units(is_primary)

關係 表 說明
使用者預設歸屬 users.tenant_id / users.org_unit_id 單一預設值(欄位)
使用者 ↔ 租戶 public.user_tenants N:M;is_default 標預設租戶
使用者 ↔ 部門 public.user_org_units N:M;is_primary 標主要部門
租戶樹狀 tenants.parent_id / tenants.path(/1/2/ 格式) 多層租戶
部門樹狀 org_units.parent_id / org_units.path 部門內含子部門

RLS:DB 層以 PostgreSQL RLS 做租戶隔離,session_scope() 自動注入 app.user_id / app.allowed_tenant_paths,Python 查詢不需另加 tenant filter(見專案 CLAUDE.md「RLS 注意事項」)。但功能定義表 ui_routes / capabilities / route_capabilities 不加 RLS(全租戶共用同一份功能定義),隔離改由 user_roles.tenant_id 處理。

4. system_configs key-value 設定慣例

多個設定頁(通知 / SMTP / LDAP / 議題整合)不各自建表,而是共用 public.system_configs 這張 group / key / value(jsonb) 的鍵值表:

欄位 說明
group 設定群組(如 SMTP / NOTIFY / LDAP / ISSUE;實際 group 名以各設定頁 spec 查證為準)
key 設定鍵名
value jsonb 設定值
tenant_id / org_unit_id 設定的歸屬範圍(可為租戶級或全域)

主要 endpoint:GET/POST/PUT/DELETE /api/1.0/system/config、GET /api/1.0/system/configs/<group>、GET/PUT/DELETE /api/1.0/system/config/<group>/<key>。設定頁不寫 value 明文憑證進 spec(密碼 / token 只描述欄位)。

選單項另有 public.system_menus(group / key / value / sort / enable / public)——這是「選單管理」頁維護的下拉 / 分類選單資料(如國家、產業別等 code table),與 ui_routes(權限選單樹)是兩回事,別混。

5. 角色權限基調

角色是誰:

  • 平台 admin(root tenant)——治理全系統的角色、能力點、選單結構,是所有其他角色權限的源頭。「身為平台 admin,我要新增一個角色、勾選它能看到哪些選單與能做哪些操作。」
  • 租戶 admin——管理自己租戶內的使用者、部門、設備、資訊系統盤點等主檔資料。「身為租戶 admin,我要新增一個部門、把新進使用者分派進去並指派角色。」
  • 一般使用者——管理自己的個人資料、密碼、MFA 設定,不涉及他人資料。「身為一般使用者,我要改自己的密碼、設定雙因子驗證。」

系統管理群整體是管理員 / 平台層功能,理應鎖後台角色。實務上各頁 BE 強制程度不一:

面向 應由誰 常見 BE 現況
角色 / 指派 / 選單治理 平台 / 租戶 admin iam.role.*、iam.user.assign 守門;原廠層另要平台管理員(GRC_403060)
使用者 / 租戶 / 部門 / 設備 CRUD 租戶 admin 各資源 iam.*/asset.* 權限守門
個人資料 / 改密 / MFA 使用者本人 僅 JWT(操作自身)

重要:route_capabilities 控制的是選單是否顯示;API 是否放行由端點上的權限守門決定,兩者各自設定。各頁 §3 權限矩陣以 FE 判定 vs BE 強制分欄對照,發現不一致標 ⚠️ 收進該頁 §12。

error code 前綴:權限 / 平台層多為 GRC_(如 GRC_NOT_PLATFORM_ADMIN=403060),但各模組不保證同前綴——寫每頁 §6 前先 grep 該模組 common/code/*_error_code.py 查證,勿假設全 GRC_。

6. 核心資料模型

系統管理核心資料模型:RBAC 五表(users/roles/capabilities/ui_routes/關聯)+ 組織主檔(tenants/org_units)+ system_configs 設定

表 schema 角色
users public 帳號本體(login_name / nickname / status / 預設 tenant+org / mfa)
roles public 角色(tenant_id、is_system、is_template、is_admin、enable、is_delete)
capabilities public 權限(name 三段名 UNIQUE / module / is_platform / license_module / enforce_mode / home_route_name)
role_capability_patterns public 角色 ↔ 規則字串(判定唯一來源)
route_capabilities public 路由 ↔ 能力(複合 PK + requirement ALL/ANY)
ui_routes public 選單 / 路由樹(pid 自參考 / enable / sort / is_menu / tree_page;name=i18n key)
user_roles public 指派(scope / tenant_id / org_unit_id / starts_at / ends_at)
tenants public 租戶(parent_id / path 樹狀)
org_units public 部門(tenant_id / parent_id / path 樹狀)
user_tenants public 使用者 ↔ 租戶(is_default)
user_org_units public 使用者 ↔ 部門(is_primary)
system_configs public 系統設定 key-value(group / key / value jsonb / tenant_id)
system_menus public 下拉 / 分類選單 code table(group / key / value;≠ ui_routes)
devices public 設備主檔
information_systems compliance 稽核範圍資訊系統主檔
api_logs / system_logs public 操作日誌(api_logs vs event_code 事件日誌,見操作日誌頁)
user_auth_providers public 使用者第三方登入綁定
user_change_password_request / user_change_pwd_logs public 改密請求 / 歷史

7. 本群共用的已知坑

  1. ui_routes vs system_menus 別混:前者是權限選單樹(RBAC 可見性)、後者是下拉分類 code table(選單管理頁維護),兩張不同用途的表。
  2. ui_routes 控可見性 ≠ BE 端點強制:route_capabilities 只決定選單顯不顯示;API 放行看端點守門。新增端點兩邊都要設。
  3. ui_routes.name 已加 UNIQUE(2026-07-08 FR-047 SCHEMA,DEV+STG 已套、POC 待部署):FE 功能樹強依賴 name 當 i18n key,原無 DB 約束、重名顯示錯亂;已加 uq_ui_routes_name UNIQUE(name)(capabilities.name 本就有 UNIQUE)。POC 未套前新增仍建議先 SELECT 確認沒重名(設計文件 §9.1)。
  4. 跨環境 id 漂移:DEV / STG / POC 的 ui_routes.id / capabilities.id 用 serial 各自編號、不一致,程式碼與 migration 一律用 name 查、勿 hardcode id(設計文件 §9.7)。
  5. is_platform 權限:原廠層權限(root tenant 專屬)在一般租戶角色樹不出現、寫入端擋(GRC_403060)。
  6. sort 預留 gap:ui_routes.sort / system_menus.sort 用 10/20/30 間隔,別連號(設計文件 §9.2)。
  7. 設定頁共用 system_configs:通知 / SMTP / LDAP / 議題整合都是同一張 key-value 表的不同 group,非各自專表;改一個設定頁的讀寫慣例前,先確認沒影響同表其他 group。
  8. jedi-iam 套件擁有大半 RBAC 邏輯:users / roles / 指派 / ui_routes / web-menu / 判定的 service / repo 在 jedi-iam 套件內(~/Projects/Jedicogy/module/jedi-python-package/jedi-iam/),不在主專案;改行為要分清邊界(見 CLAUDE.md「外部套件異動規範」)。