FR-132 新拆權限補給舊角色:對照表

新拆權限補給舊角色:對照表

FR-132 改三段式名稱時新拆出 90 個沒有舊名的權限。從舊版升級上來的角色只帶著舊權限改名後的那幾顆,新拆出的一顆都沒有——今天「只記錄不擋」的那些到真擋那天,原本做得到的事會突然做不到,而且沒有錯誤訊息說為什麼。scripts/sql/2026-10-07-fr132-grant-split-capabilities.sql 依這張表補,讓升級前做得到的事升級後還做得到。

§1

三類怎麼補

類別 判準(附錄 A「舊名」欄) 補給誰
A 該 route 今天有舊權限守 持有「來源權限」任一顆的角色(舊權限已改名,來源寫新名)
B 該 route 今天只驗登入 所有未刪除角色
C 附錄 A 沒有 route(四個基本動詞的空殼),或是這版才有的新功能 只補 is_admin 角色
N FR-132 之後的新功能,升級前不存在對應操作 由該功能自己的 migration 發給既有角色;登記在下方「新功能能力點」節,不進本表與 FR-132 補授 migration

共通規則:

  • 不補的角色:持有 *.*.* 的內建系統管理員(本來就涵蓋全部)、出貨範例角色(is_template,裝機時寫的就是完整定稿)。
  • is_platform 的權限只補 root 租戶的角色,與 role_capabilities 的寫入 trigger 一致;原廠層端點另有平台管理員那道門。
  • 一顆權限寫一列 role_capability_patterns,不寫萬用字元;ON CONFLICT DO NOTHING,重跑不重複。
  • 一條 route 對到同一顆新權限但舊名欄不一致時(例:grc.job.update 多數只驗登入、少數守 survey.update),取最寬的那類——升級後不能比今天少。
  • 挑選用下拉(通則 B,例 /devices/menu 跟呼叫頁的 grc.job.read)不影響歸類:那是呼叫頁的權限,不是該權限本身今天的守門。
§2

對照表

守衛測試 test/test_fr132_split_capability_grants.py 從本表讀「權限」與「類別」兩欄,斷言程式宣告的每一顆無舊名權限都在表內、且類別是 A/B/C;日後新增權限沒歸類就紅。新增權限時在這裡補一列,並決定要不要另開 migration 補給既有角色。

權限 類別 來源權限(A 類) 依據
ai.ai-provider-config.create A system.storage-config.create 附錄 A L1083:泛用 POST /system/config,AI_PROVIDER_CONFIG 群組改名前對到 storage-config.create
ai.ai-provider-config.delete A system.storage-config.delete 附錄 A L1078、L1082:泛用 DELETE,AI_PROVIDER_CONFIG 群組改名前對到 storage-config.delete
ai.ai-provider-config.read A system.storage-config.read 附錄 A L1092(模型下拉)、L428-429(AI 服務設定頁今天借 storage-config)
ai.ai-provider-config.update A system.storage-config.update 附錄 A L1077、L1081:泛用 PUT,AI_PROVIDER_CONFIG 群組改名前對到 storage-config.update;L428-429
ai.assistant.create C — 附錄 A 無 route,四個基本動詞空殼
ai.assistant.delete C — 附錄 A 無 route,四個基本動詞空殼
ai.assistant.read B — 附錄 A L1218-1219:/ai-chatbot 今天只驗登入
ai.assistant.update C — 附錄 A 無 route,四個基本動詞空殼
ai.call-log.create C — 附錄 A 無 route,四個基本動詞空殼
ai.call-log.delete C — 附錄 A 無 route,四個基本動詞空殼
ai.call-log.export A ai.call-log.read 附錄 A L1222、L1224:兩支匯出今天守 ai-call-log.read
ai.call-log.update C — 附錄 A 無 route,四個基本動詞空殼
ai.dashboard.create C — 附錄 A 無 route,四個基本動詞空殼
ai.dashboard.delete C — 附錄 A 無 route,四個基本動詞空殼
ai.dashboard.update C — 附錄 A 無 route,四個基本動詞空殼
ai.quota.create C — 附錄 A 無 route(還原預設的 DELETE 歸 ai.quota.update,L1236),四個基本動詞空殼
ai.quota.delete C — 附錄 A 無 route(還原預設的 DELETE 歸 ai.quota.update,L1236),四個基本動詞空殼
asset.device.export A asset.device.read 附錄 A L1210:/devices/export 今天守 device.read
asset.device.import A asset.device.create 附錄 A L1207-1209:匯入三支今天守 device.create
detection.scan-zone.create A detection.scan-zone.update 附錄 A L988、L991:今天守 scan-zone.update;附錄 B #90 明寫升級時一併給
detection.scan-zone.delete A detection.scan-zone.update 附錄 A L990:今天守 scan-zone.update;附錄 B #90 明寫升級時一併給
evidence.classification-profile.create A system.storage-config.update 附錄 A L1027:今天守 storage-config.update
evidence.classification-profile.delete A system.storage-config.update 附錄 A L1029:今天守 storage-config.update
evidence.classification-profile.read A system.storage-config.update 附錄 A L1026:今天讀也要 storage-config.update
evidence.classification-profile.update A system.storage-config.update 附錄 A L1028:今天守 storage-config.update
evidence.classification.create B — 附錄 A L1010:今天只驗登入
evidence.classification.delete B — 附錄 A L1013、L1019:今天只驗登入
evidence.classification.execute B — 附錄 A L1017:今天只驗登入(附錄 D 裁 7:送分類與 update 分開授權,先只記錄)
evidence.classification.read B — 附錄 A L1011-1012、L1020-1024、L1030:今天只驗登入
evidence.classification.update B — 附錄 A L1014-1016、L1018、L1021、L1025:今天只驗登入
flow.template.publish A flow.template.update 附錄 A L917-918:發布/取消發布今天守 flow_template.update
grc.audit.close B — 附錄 A L650:今天只驗登入
grc.audit.import B — 附錄 A L661-664、L679-682:今天只驗登入
grc.job-comment.create B — 附錄 A L709:今天只驗登入
grc.job-comment.delete B — 附錄 A L711:今天只驗登入
grc.job-comment.read B — 附錄 A L708:今天只驗登入
grc.job-comment.update B — 附錄 A L710:今天只驗登入
grc.job-evidence.create B — 附錄 A L716-717:今天只驗登入
grc.job-evidence.delete B — 附錄 A L720:今天只驗登入
grc.job-evidence.read B — 附錄 A L715、L718:今天只驗登入
grc.job-evidence.update B — 附錄 A L719:今天只驗登入
grc.job.assign B — 附錄 A L645、L697、L704-707:今天只驗登入
grc.job.create B — 附錄 A L694:今天只驗登入
grc.job.delete B — 附錄 A L693:今天只驗登入
grc.job.import B — 附錄 A L700-702:今天只驗登入
grc.job.read B — 附錄 A L690-691、L695-696、L703、L714、L734-748 等:今天只驗登入(L926、L965、L1201 是通則 B 挑選下拉,不影響歸類)
grc.job.update B — 附錄 A L692、L698、L712-713、L736-749、L955-963 等:今天只驗登入(L750-751 改刪自己的討論今天守 survey.update/delete,B 類已涵蓋)
grc.summary-report.export B — 附錄 A L730:今天只驗登入
iam.role.export C — 附錄 A L1134:新功能(T-3.7);附錄 D 待裁 6 裁定只有系統管理員拿得到
iam.role.import C — 附錄 A L1135:新功能(T-3.7);附錄 D 待裁 6 裁定只有系統管理員拿得到
iam.user.assign A iam.user.create、iam.user.update 附錄 A L1108(建帳號帶角色,今天守 user.create)、L1110(改帳號角色,今天守 user.update);L1113-1114 是 T-3.8 新 route
iam.user.import A iam.user.create 附錄 A L1120-1122:匯入三支今天守 user.create(L1123 範本下載守 user.read,只是下載範本,不據此把匯入給 read)
oscal.framework.import B — 附錄 A L778-781:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
oscal.ssp.create C — 附錄 A 無 route(SSP 隨建專案產生,守 grc.project.create),四個基本動詞空殼
oscal.ssp.delete C — 附錄 A 無 route,四個基本動詞空殼
oscal.ssp.export B — 附錄 A L890、L896:今天只驗登入(L895 範本下載守 module-frame.read,B 類已涵蓋)
oscal.ssp.import B — 附錄 A L891-894、L898-899、L902-903:今天只驗登入(L897、L900-901、L904 與資源庫共用、守 module-frame.*,B 類已涵蓋)
oscal.ssp.read B — 附錄 A L846、L848、L852 等 13 列:今天只驗登入
oscal.ssp.update B — 附錄 A L847、L849-851 等 31 列:今天只驗登入
platform.ai-quota-ceiling.create C — 附錄 A 無 route,四個基本動詞空殼
platform.ai-quota-ceiling.delete C — 附錄 A 無 route,四個基本動詞空殼
platform.ai-quota-ceiling.read B — 附錄 A L1229-1230:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.ai-quota-ceiling.update B — 附錄 A L1231:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.api-log.create C — 附錄 A 無 route,四個基本動詞空殼
platform.api-log.delete C — 附錄 A 無 route,四個基本動詞空殼
platform.api-log.export A platform.api-log.read 附錄 A L1186:今天守 log.read(只綁選單,進得了頁面的人才按得到匯出)
platform.api-log.update C — 附錄 A 無 route,四個基本動詞空殼
platform.drive-app-credential.create A system.system-config.create 附錄 A L1083:泛用 POST,GOOGLE_DRIVE_APP_CONFIG 改名前未登記、走兜底 system_config.create(L466)
platform.drive-app-credential.delete A system.system-config.delete 附錄 A L1078、L1082:泛用 DELETE,改名前走兜底 system_config.delete(L466)
platform.drive-app-credential.read A system.storage-config.read 附錄 A L1001:驗證憑證今天守 storage-config.read
platform.drive-app-credential.update A system.system-config.update 附錄 A L1077、L1081:泛用 PUT,改名前走兜底 system_config.update(L466)
platform.license.assign B — 附錄 A L1176-1177:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.license.create C — 附錄 A 無 route;附錄 D 裁示 2 補的空殼
platform.license.delete C — 附錄 A 無 route;附錄 D 裁示 2 補的空殼
platform.license.import B — 附錄 A L1171:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.license.update B — 附錄 A L1178-1180:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.support.create C — 附錄 A 無 route,四個基本動詞空殼
platform.support.delete C — 附錄 A 無 route,四個基本動詞空殼
platform.support.export B — 附錄 A L1188:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.support.read B — 附錄 A L1187:今天只驗登入(另有平台管理員那道門,is_platform 只補 root)
platform.support.update C — 附錄 A 無 route,四個基本動詞空殼
survey.survey.import A survey.survey.create 附錄 A L1048:Excel 匯入今天守 survey.create(L1049 範本 token 只驗登入)
survey.survey.publish A survey.survey.update、survey.survey.delete 附錄 A L1053(發布,今天守 survey.update)、L1054(取消發布,今天守 survey.delete)
system.log-forwarding.create C — 附錄 A 無 route(Log 轉發走專屬端點,只有 read/update),四個基本動詞空殼
system.log-forwarding.delete C — 附錄 A 無 route(Log 轉發走專屬端點,只有 read/update),四個基本動詞空殼
system.notify-config.create A system.notify-config.update 附錄 A L405、L1083:泛用端點今天把通知設定的新增對到 notify_config.update
system.notify-config.delete A system.notify-config.update 附錄 A L405、L1078:泛用端點今天把通知設定的刪除對到 notify_config.update
system.security-policy.create C — 附錄 A 無專屬 route;泛用端點改名前對到不存在的 security-policy.create,今天只有超級管理員做得到
system.security-policy.delete C — 附錄 A 無專屬 route;泛用端點改名前對到不存在的 security-policy.delete,今天只有超級管理員做得到
system.system-config.read B — 附錄 A L1076、L1079-1080:泛用讀取未登記群組今天只驗登入(is_platform 只補 root)
§3

新功能能力點(N 類)

FR-132 之後才出現的功能,舊版本來就沒有對應操作,升級上來的角色沒有「原本做得到、升級後做不到」的問題,不需要走上表與 FR-132 補授 migration。但仍要有人發給既有角色,否則新功能上線後只有內建管理員看得到。

規則:每顆登記一列,寫明哪一支 migration 負責發給既有角色。守衛檢查該檔存在、且內容真的出現這顆能力點名稱——不是寫個檔名就算數。

權限 類別 發放 migration 依據
detection.source-scan.create N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
detection.source-scan.delete N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
detection.source-scan.execute N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
detection.source-scan.export N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
detection.source-scan.read N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
detection.source-scan.update N 2026-10-10-fr134-source-scan-grant-admin-roles.sql FR-134 原始碼弱點掃描;既有租戶 is_admin 角色由此支補(FR-132 C 類規則);出貨範例稽核員由 2026-10-10-fr134-source-scan-capabilities.sql 回補 create/execute/export
oscal.pre-engagement.manage-category N 2026-10-23-fr161-pre-engagement-capabilities.sql FR-161 事前資料大類設定;持 oscal.resource-library.update 的系統角色由此支補;出廠系統管理員 *.*.* 已涵蓋
oscal.pre-engagement.upload N 2026-10-23-fr161-pre-engagement-capabilities.sql 同上,另補 IT執行人員(用角色名稱比對)
system.vulndb.read N 2026-10-10-fr134-vulndb-settings-page.sql FR-134 系統設定「弱點資料庫」頁;既有租戶 is_admin 角色由此支補,出廠系統管理員 *.*.* 已涵蓋,範例角色不給
system.vulndb.update N 2026-10-10-fr134-vulndb-settings-page.sql 同上;SaaS 模式下寫入另要求平台管理員(全機共用一份資料)
§4

既有顆的連帶補授

上表只管「新拆出、沒有舊名」的能力點。改名既有顆不在補授範圍,會漏人:grc.audit.read 就是—— 輪次總覽頁(輪次列表、階段資訊、AP 儀表板)守它,但升級上來的自建角色只被補了輪次核准/關閉/匯入,沒有輪次讀取。

規則:自建角色(非系統、非範例)只要持有任一 grc.audit.* 或 grc.project.read,一律補 grc.audit.read; 已被 *.*.*、grc.*.*、grc.*.read 之類 pattern 涵蓋的跳過。 理由:輪次總覽是專案頁的一部分,能進專案或能動輪次的人不該讀不到輪次。 實作:scripts/sql/2026-10-08-fr132-grant-audit-read-to-project-roles.sql(不改 enforce_mode)。

功能全在別顆門檻頁上的權限:跟那顆門檻走

workspace.feedback.export 的匯出鈕只在「系統回饋管理」頁(守 workspace.feedback-review.read); 只有匯出、沒有審閱的角色勾了也沒地方用。規則:自建角色沒有 feedback-review.read 就不給 feedback.export。 實作:scripts/sql/2026-10-08-fr132-revoke-feedback-export-without-review.sql。 全站用矩陣掃過「功能全落在別顆門檻頁上」的權限:其餘命中的是專案情境權限(通則 A,grc.job.*/oscal.ssp.* 在專案頁上本來就跟 grc.project.read 走)與原廠頁權限(原廠管理員才進得去),都屬設計,不處理。

行號指 a1-capability-tree.md。沿革見 FR-132-LOG 與 git log。