FR-094 · 需求索引 · 本頁由 build 掃資料夾生成

FR-094 租戶隔離修正(RLS 第三波)——13 張表+4 支 view 真的把「每個客戶只看自己資料」關上

🟢 已開卡待派,前置 CM-1559 In progress(2026-09-13)。母卡 CM-1766;子卡 CM-1767~1773 七張+既有 CM-1559 共 8 棒。順序硬相依:.1a(CM-1767)→ CM-1559 → .2c(CM-1770);其餘五棒可平行。吸收 CM-1445/CM-1453 結案。只套 DEV+基線庫,STG/POC 等放行。

狀態:詳見下方 文件 0 份

FR-094 一頁看完

§1

結論

  1. 產品靠資料庫的 RLS(Row Level Security,資料庫自己擋、讓每個客戶只查得到自己的資料)做多租戶隔離。FR-087 盤點(CM-1663)查出 13 張表、4 支 view 的隔離實際上是關的:有的規則寫好但開關沒開、有的連規則都沒寫、view 用「建立者身分」查底層而繞過隔離。決策者 2026-09-11 親測:切到子租戶後仍看到別家待辦 39 筆、專案 213 筆。本案把這些一張一張補齊、打開,並驗證登入、切租戶、我的任務、兩支凌晨排程都還活著。
  2. 三個定案:D1 公版機制沿用「policy 內加旗標 OR 分支」,不動 app_tenant_allowed_for_session helper(12+ 張表共用),既有 flow_templates.is_builtinmodule_framesdetection_profilesscope='SYSTEM' 不回改,新開的表一律用 scope;D2 問卷不加公版旗標(引用是複製進任務),要修的是 survey schema 另 12 張沒 RLS 沒 tenant_id 的裸表;D3 projects 的 RLS 是 2026-06-25 環境對齊順手關的(commit e7709295),非產品決策,補 is_super_admin 分支後重開、DEV 造跨租戶樣本驗。
  3. 順序硬相依:03:10 孤兒清理與 01:00 框架解析清理兩支排程靠「無身分=super admin」跑,那正是 CM-1559 要收緊的洞。必須 .1a 先給排程具名系統身分 → CM-1559 收緊 → .2c 才開 job_executionsframework_parse_jobs,反過來清理程式會安靜失效不報錯。
  4. 平台管理員不受影響(viewer_is_platform_admin() 走 root 路徑,不是靠隔離沒開)。不做log_forwarding_settings(本質平台層,能力點守門已擋)、任務詳細 API 不驗 project_uid(歸 FR-086)、surveys/survey_folders 公版旗標(D2)。
  5. 每張開隔離的卡必做「開前 vs 開後」對照(模擬非 super_admin 租戶帳號查筆數);migration 只套 DEV(localhost)+ 188:25432 基線庫並重產 02-schema;帶舊資料升級不破。
§2

📊 總進度

做什麼 規模 順序 狀態
1 CM-1767 .1a 兩支凌晨排程具名系統身分(core/scheduler.py:202,386;jedi-common system_context()is_system_context BE 1 檔+jedi-common 1~2 檔 序列組 S 第一棒
2 CM-1559 .1b RLS fail-open 收緊(jedi-common db.py+jedi-iam signed_token.py,併 jedi 1.1.0) 既有卡 序列組 S:.1a 後 🔵 In progress(第一步盤點已回寫)
3 CM-1768 .2a 甲組:tenant_drive_integrations 開;projects 補 super_admin 分支+開;DEV 跨租戶樣本;重產 02(吸收 CM-1453) 1 migration 可立即派
4 CM-1769 .2b 乙組高敏感:user_rolesuser_tenantsuser_org_units 補 policy+開(吸收 CM-1445) 1 migration 可立即派
5 CM-1770 .2c 乙組其餘:poamsevidence_classification_*job_executionsframework_parse_jobsinformation_systems 基線對齊;驗兩支排程 1 migration 序列組 S:.1a+1559 收完
6 CM-1771 .2d 丙丁組:workflow_executions 補 select+開;4 支 view security_invokerv_user_routesv_role_routes 無讀者 DROP 等令) 1 migration+view SQL 可平行;與 .2c 同輪驗我的任務
7 CM-1772 .2e 戊組:workflow_templatesscope、回填無主凍結副本、policy 加公版分支+開;凍結根因修 1 migration+jedi-flow-engine 1~2 檔 可平行;無連結無主列處置等首腦裁
8 CM-1773 .3a 問卷 12 張裸表:實查引用鏈選「加 tenant_id 回填」或「JOIN-based policy」,定案後補 policy+開 jedi-survey model+1 migration 可平行;方案定案前不動 schema
§3

需求討論紀錄

  • 2026-09-13 決策者裁定 D1–D3 與順序硬相依(見結論 2、3)。同日開卡 runner 在 DEV(localhost)實查校正盤點數字:projects 221 筆全屬 tenant 102;workflow_templates 18,135 筆、本機 tenant_id IS NULL 為 0 筆(FR-087 於 188 快照查到 191 筆)——.2e 卡要求對 188 快照與基線庫再各查一次,回填 SQL 不論本機是否為 0 都寫進 migration(冪等);information_systems DEV 已由 jedi-asset 002 開 RLS(基線未開),.2c 只做基線對齊;tenant_drive_integrations DEV 在 public schema(盤點寫 compliance),.2a 動手前確認。
  • 2026-09-13 吸收兩張舊安全債卡:CM-1445(三張授權關聯表無 RLS,FR-069 D9 附帶發現)→ 併 CM-1769;CM-1453(projects RLS 停用是否刻意)→ 查證為環境對齊順手關、非刻意,併 CM-1768。兩張卡已 append 併入說明並改 Done。
  • 待裁記帳:.2d v_user_routesv_role_routes 三方(BE/FE/e2e+pg_proc)確認零讀者後是否 DROP;.2e 無連結的無主凍結副本刪或掛 root;.3a 問卷裸表方案 A(加 tenant_id)或 B(JOIN-based policy)。
  • 前作:FR-087 盤點報告 ../FR-087-2609-tenant-isolation-audit/scan-T1-isolation-gap-audit.md(§3.1 十三張表、§3.2 四支 view、§5.2 無主副本、§6.1 兩支排程、§8 分組);CM-1559 第一步盤點(31 張 RLS 表、8 支排程、引導悖論三類分流)。
§4

座標

  • RLS 設計:docs/system-design/database/RLS_DESIGN.md;helper 定義 scripts/init/02-schema.sql:623;標準 policy 樣板 scripts/sql/2026-04-23-google-drive-oauth-integration.sql:48-79
  • 兩支排程:core/scheduler.py:202(01:00 framework_parse_jobs)、:386(03:10 job_executions)
  • fail-open 判定:jedi-common jedi_common/session/database/db.py:100-119
  • 對照帳號:blsit(tenant 102,非 super_admin)/blsadmin(super_admin,路徑 /1/);DEV 庫 psql -h localhost -p 5432 -U cmmgr -d guidant_ai_dev;基線庫 188:25432 guidant_ai
  • branch:BE feature/FR-075、jedi feature/FR-075(2026-09-13 查)
  • skill:sql-migrationjedi-package-dev
§5

Notion 卡

卡片內容(決策紀錄、驗收條件)以 Notion 為準,本頁只記座標。

關係 卡號 標題 狀態
母案 CM-1766 FR-094 租戶隔離修正(RLS 第三波)——13 張表+4 支 view 把「每個客戶只看自己資料」真的關上(7 棒,實作;含既有 CM-1559)
子卡 CM-1767 .1a 兩支凌晨排程具名系統身分 Not started
子卡 CM-1559 .1b RLS fail-open 收緊(既有 FR-075 卡,併 jedi 1.1.0) In progress
子卡 CM-1768 .2a 甲組純開關:tenant_drive_integrations/projects(吸收 CM-1453) Not started
子卡 CM-1769 .2b 乙組高敏感:user_roles/user_tenants/user_org_units(吸收 CM-1445) Not started
子卡 CM-1770 .2c 乙組其餘+排程相依表 Not started
子卡 CM-1771 .2d 丙丁組:workflow_executions+4 支 view security_invoker Not started
子卡 CM-1772 .2e 戊組:workflow_templates scope+回填+開 Not started
子卡 CM-1773 .3a 問卷 12 張裸表隔離 Not started