SSP 利用授權(Leveraged Authorizations)
功能群:專案管理|上層見 系統安全計畫編輯器(本頁=其 Tab「元件·授權·資產」的利用授權子區)
事實基準:2026-07-06 從 FE / BE code 掃出;表結構對
db_schema.json、endpoint 對routes.json、欄位對 route 組裝碼 + mapper 逐條核
1. 功能描述
利用授權是 SSP
系統實作(system-implementation)底下的
leveraged-authorizations
維護區:登錄這套受評系統所「利用」的外部已授權服務(如 AWS FedRAMP
認證的雲服務、上游已通過稽核的平台)。對應 OSCAL SSP 的
system-implementation.leveraged-authorizations,掛在
ssp_system_implementations(首次新增
get_or_create
自動建父)。建立的每筆授權可被同頁「元件」子區的元件透過
leveraged_authorization_uid 關聯引用。
掛在 SSP 編輯器
Tab「元件·授權·資產」的第二子區(元件 → 授權 →
資產),三子區共用同一個 Vue
元件(SspComponentsLeveragedInventoryTab.vue)。與 SSP
其餘子區共用可編輯 gate(manager + AP=planning),凍結後唯讀。
主要使用者:專案 manager(寫)、專案任一參與者(讀)。
角色速覽(完整定義見 _overview §3):
| 角色 | 一句話 |
|---|---|
| manager | 專案經理 — 唯一能增改刪利用授權者(需 AP=planning) |
| 參與者 | auditor / reviewer / viewer — 可讀不可寫 |
1.1 功能總覽(本頁全部功能)
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 1 | 利用授權清單 | 此 SSP 全部利用授權(DataTable,含關聯元件數) | 利用授權區 | §5 |
| 2 | 新增 / 編輯利用授權 | title + 提供者 + 授權日 + 類別 + 狀態 + 描述/用途 | Dialog | UC-SL-01 |
| 3 | 刪除利用授權 | 移除一筆(元件以 uid 軟參照,見 §12) | 每列 | §6.2 |
UC(§2)展開 UC-SL-01(新增/編輯利用授權),涵蓋 NN 欄補值(party_uuid NIL 哨兵 / 日期預設今日)、必填 title、編輯 not-found 三個關鍵分支;清單顯示屬純顯示見 §5。
2. Use Case
角色速覽(同 §1)。流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
UC-SL-01 新增 / 編輯利用授權
| 項目 | 內容 |
|---|---|
| 角色 | 專案 manager |
| 前置條件 | 已載入 living SSP;AP=planning |
| 產出 / 後置條件 | 寫 oscal.ssp_leveraged_authorizations(掛
ssp_system_implementations,首次
get_or_create);核心欄 title/party_uuid/date_authorized +
props(provider/description/purpose/status/category);NN
欄空值補哨兵 / today();回傳 DTO + enrich |
3. 權限矩陣
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 讀清單 | 參與者即可 | require_participant |
app/oscal/service/ssp_leveraged_app_service.py:66(list_items) |
| 新增 / 編輯 / 刪除 | readonly prop(非 manager / AP 非 planning
隱藏鈕) |
require_manager(manager + AP 可編輯,否則
GRC_403051 / GRC_412028) |
同檔 add_item:74 / update_item:95 /
delete_item:118 |
route 層僅
@jwt_required(),且收 rawrequest.get_json()、無 marshmallow schema 驗證(ssp_leveraged_route.py:43,62);角色守門與欄位處理都在 app service。
4. 狀態機與前置條件
承接 SSP 可編輯 gate(見 SSP 編輯器
§4):AP=planning 且 manager
才可寫,凍結後唯讀。額外前置:system_implementation
不存在時,新增第一筆會 get_or_create_system_implementation
自動建立(ssp_leveraged_app_service.py:76)。
5. UI 設計
版面骨架與區塊職責(一張利用授權 DataTable + 新增/編輯 Dialog;彩色區塊可點跳本頁小節錨點,API 僅標代表性):
📸 截圖待補(亮色模式):利用授權 DataTable + 新增/編輯 Dialog
sspleveraged-list.png。
一張 DataTable +「新增利用授權」開 Dialog。DataTable
欄位:服務名稱(name || title)/
提供者(provider)/ FedRAMP Package
ID(⚠️未實現) / 影響等級(⚠️未實現,Tag) /
資料類型(⚠️未實現) /
授權日期(date_authorized)/
關聯元件數(laReferenceCounts 前端反查)/
操作。三個未實現欄綁 data.fedramp_package_id /
data.impact_level / data.data_types,但 CRUD
DTO 不回傳 → 恆顯示「—」(見 §12)。
Dialog
欄位(SspComponentsLeveragedInventoryTab.vue
利用授權 Dialog):
| # | label | 型別 | 必填 | 列舉 / 來源 | 儲存 | 備註 |
|---|---|---|---|---|---|---|
| 1 | la_title 授權名稱 |
InputText | 是 | — | title |
空 → FE toast warn(無 BE 守門,見 §12) |
| 2 | 提供者 | InputText | 否 | — | props['provider'] |
|
| 3 | la_date_authorized 授權日期 |
Calendar(yy-mm-dd) |
否 | — | date_authorized(核心欄) |
FE 空 → BE 補 date.today() |
| 4 | 描述 | Textarea | 否 | — | props['description'] |
|
| 5 | 用途 | Textarea | 否 | — | props['purpose'] |
|
| 6 | 類別 | Dropdown(showClear) |
否 | 4 值:leveraged-authorization /
external-service / interconnection /
other |
props['category'] |
FE 預設 leveraged-authorization |
| 7 | 狀態 | Dropdown(showClear) |
否 | 5 值(同元件:operational / under-development / under-major-modification / disposition / other) | props['status'] |
FE 預設 operational |
⚠️ Dialog 無
party_uuid欄(提供授權的單位 picker 未實作,BE 硬帶 NIL 哨兵)、無remarks欄(DB 有remarks核心欄但 UI 不填)。
狀態呈現:無 socket,寫入後 loadAll
重載;readonly 隱藏新增/編輯/刪除鈕。
6. API 規格
Envelope:成功 {"status": true, "data": …}、失敗
{"error_code": "…", "msg": "…"}。
6.1 總清單
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 利用授權 | GET / POST /ssp/{ssp_uid}/leveraged |
列出 / 新增 | §6.2 |
| 利用授權 | PUT / DELETE /ssp/{ssp_uid}/leveraged/{item_uid} |
編輯 / 刪除 | §6.2 |
6.2 核心 endpoint
[POST] /ssp/{ssp_uid}/leveraged
新增利用授權。Request(route 收 raw JSON,無 schema):
{
"title": "AWS GovCloud (FedRAMP High)",
"provider": "Amazon Web Services",
"date_authorized": "2025-01-15",
"description": "受評系統託管於此雲",
"purpose": "IaaS 基礎設施",
"category": "leveraged-authorization",
"status": "operational"
}| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
| title | string | 是* | → title(*FE 端擋空,BE 無守門) |
| provider | string | 否 | → props['provider'] |
| date_authorized | string(YYYY-MM-DD)|null |
否 | → date_authorized 核心欄;空 → BE 補
date.today() |
| description / purpose | string | 否 | → props['description'] /
props['purpose'] |
| category | string | 否 | 4 值之一 → props['category'] |
| status | string | 否 | 5 值之一 → props['status'] |
| party_uuid | uuid | 否 | 提供授權的單位(Dialog 未送);空 → NIL 哨兵
00000000-… |
| remarks | string | 否 | → remarks 核心欄(Dialog 未送) |
出處:app/oscal/service/ssp_leveraged_app_service.py:72-91、mapper
app/module_frame/service/module_frame_leveraged_service.py:_build_props:200-211
[GET] /ssp/{ssp_uid}/leveraged
Response data(陣列,_to_dict +
enrich):
| 欄位 | 型別 | 說明 |
|---|---|---|
| uid | string | 授權 uuid(改刪用;元件以此軟參照) |
| title | string | ← title |
| party_uuid | string|null | ← party_uuid(NIL 哨兵 reshape 回
null) |
| date_authorized | string|null | ← date_authorized(isoformat) |
| provider / description / purpose / status / category | string|null | ← props 對應鍵 |
| remarks | string|null | ← remarks 核心欄 |
| created_user / updated_user | string|null | login_name(+ enrich *_name) |
⚠️ 無
fedramp_package_id/impact_level/data_types:DataTable 顯示這三欄但 CRUD DTO 不回傳(只在 Excel / docx 匯入匯出路徑處理),恆顯示「—」(見 §12)。出處:module_frame_leveraged_service.py:_to_dict:146-168
[PUT] /ssp/{ssp_uid}/leveraged/{item_uid}
編輯。只更新 payload 帶到的鍵;date_authorized
只在送了可解析日期時更新(送 null 不覆寫,保留既有 NN
值);party_uuid 空 → NIL 哨兵。item_uid 不存在 →
GRC_404034。出處:ssp_leveraged_app_service.py:93-114
7. 前端檔案地圖(compliance-manager-fe/)
| 檔案 | 角色 |
|---|---|
src/components/grc/ssp/SspComponentsLeveragedInventoryTab.vue |
本子區(元件 / 授權 / 資產三表同元件;利用授權 DataTable +
Dialog;laReferenceCounts 反查關聯元件數) |
src/service/SspService.js |
listLeveraged(uid, 'ssp') /
createLeveraged / updateLeveraged /
deleteLeveraged(apiBase='ssp') |
8. 後端檔案地圖(本頁核心鏈路)
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| 利用授權 CRUD | api/oscal/routes/ssp/ssp_leveraged_route.py(raw
JSON、無 schema) |
SspLeveragedAppService(require_participant
讀 / require_manager 寫;經
SspPermissionChecker) |
oscal.ssp_leveraged_authorizations(掛
ssp_system_implementations);純 mapping 共用
ModuleFrameLeveragedService(_to_dict /
_build_props / _parse_date /
_NIL_PARTY_UUID,單一真相) |
DDD 提醒:mapping 共用範本版 helper。⚠️ SSP 版
add_item無同名去重、MF 版有(MODULE_FRAME_LEVERAGED_NAME_EXISTED)——public method 各自實作(見 §12)。
9. DB
9.1 資料表總清單(本頁讀寫的全部表)
| 表 | 讀寫 | 說明 | 詳述 |
|---|---|---|---|
| oscal.ssp_leveraged_authorizations | 讀 / 寫 | 利用授權本體 | §9.3 |
| oscal.ssp_system_implementations | 讀 / 首次新增自動建 | containment 父 | GAI-SD-03 |
| oscal.parties | 讀 | party_uuid 軟參照目標(提供授權的單位;目前 UI
未接) |
參與方 |
9.2 ER 圖
利用授權隸屬
ssp_system_implementations(containment),以
party_uuid 軟式參照 parties.uuid,見 SSP 編輯器 §9.2 ER;本頁不另繪。
9.3 核心表欄位(取自 DEV DB dump,含 DB comment)
oscal.ssp_leveraged_authorizations
| 欄位 | 型別 | 說明 |
|---|---|---|
| system_implementation_id | bigint | containment FK(結構必填) |
| uuid | uuid | [必填] 授權身分(對外 uid;元件以此軟參照) |
| title | text | [必填] 授權名稱 |
| party_uuid | uuid | [必填] 軟式參照
oscal.parties.uuid(全系統 party-uuid 皆軟式,不建 FK);UI
未接 → 存 NIL 哨兵 |
| date_authorized | date | [必填] 授權日期;FE 空 → date.today() |
| props | jsonb | [選填] [{name,value}];本頁保留鍵 provider
/ description / purpose / status
/ category |
| remarks | text | [選填] 補充說明(DB 有欄、Dialog 未填) |
⚠️ schema 註:
provider/status/category等 一律存props、非獨立欄位(v2 LA 無對應核心欄);party_uuid/date_authorized是 NN 核心欄,空值分別以 NIL 哨兵 /today()補(見 §12)。DataTable 的 FedRAMP / 影響等級 / 資料類型三欄在本表無對應欄位,CRUD 完全不處理。
10. 頁面邏輯與資料對應
loadAll 以 listLeveraged(sspUid, 'ssp')
拉全部授權存
leveragedAuths。欄位對應:
| 畫面元素 | FE state | API 欄位 → DB |
|---|---|---|
| 授權名稱 | laEditing.title |
title → title |
| 提供者 | laEditing.provider |
provider → props['provider'] |
| 授權日期 | laEditing.date_authorized |
同名 → date_authorized |
| 類別 / 狀態 | laEditing.category / .status |
→ props['category'] / props['status'] |
| 描述 / 用途 | laEditing.description / .purpose |
→ props['description'] /
props['purpose'] |
儲存流程:saveLeveraged 先 client 檢查
title.trim()(空 → toast warn 不送)→ POST/PUT →
loadAll
重載。關聯元件數:DataTable「關聯元件數」由
laReferenceCounts[uid](元件的
leveraged_authorization_uid
反查)。錯誤對應:GRC_404034(授權不存在)/
GRC_403051 / GRC_412028 → toast。
11. 背景行為與外部依賴
| 類型 | 內容 |
|---|---|
| socket | 無(loadAll 重載) |
| 被依賴 | 同頁「元件」子區以 leveraged_authorization_uid
關聯本子區項目 |
| 共用 | 同一 mapping 被 module-frame
範本編輯(SspLeveragedSection.vue +
apiBase='module-frame')復用;⚠️ add 去重行為兩端不同 |
12. 邊界情況與已知坑
- 三個顯示欄未實現(fedramp_package_id / impact_level /
data_types):DataTable 綁
data.fedramp_package_id/data.impact_level/data.data_types,但 CRUD_to_dict不回傳、DB 也無對應欄(只在 Excel / docx 匯入匯出路徑另處理)→ UI 恆顯示「—」。要在 CRUD 支援需加 DB 欄 + mapper + serializer(follow-up)。 party_uuidpicker 未實作:Dialog 無「提供授權的單位」欄,BE 一律寫 NIL 哨兵00000000-0000-0000-0000-000000000000,_to_dict再 reshape 回null。DB 是 uuid NN 欄,若直接寫""會 DataError,故用哨兵而非空字串(日後接 party picker 時填真 uuid)。remarks無 Dialog 欄:DB 有remarks核心欄、payload 也支援,但 UI Dialog 不填——目前只能經 API / 匯入寫入。date_authorized是 NN 欄、update 送 null 不覆寫:新增空日期補today();編輯時只在送了可解析日期才更新(送 null / 空保留既有值),避免把 NN 欄清空。- title 必填只有 FE 擋、BE 無守門:route 收 raw
JSON、service 用
payload.get('title') or ''——直接打 API 送空 title 不會被拒(無等價 error code)。 - SSP 版新增無同名去重、MF
版有:
ModuleFrameLeveragedService.add_item有同名 ConflictError(MODULE_FRAME_LEVERAGED_NAME_EXISTED);SspLeveragedAppService.add_item沒有。 - SSP 寫入無 phase guard(BE):唯讀由 FE 鎖;凍結後直接打 API 仍會改 living SSP——同 SSP 編輯器 §12。