FR-165 · 需求討論稿 · 2026-10-26(v1 待審)

掃描工具資源管理

把「掃描設定檔管理」與「弱點資料庫」收進同一個入口,之後再多工具也不再多一頁

掃描工具跑起來要吃的東西現在散在兩個地方:掃描設定檔管理(合規稽核群組,給 CINC/GCB 挑基準)與弱點資料庫(系統設定群組,給第三方元件掃描用)。兩者都是「工具要吃的內容,都要管來源、日期、送到 Agent」,卻各長一頁、各走一套。本案把它們收進一個入口「掃描工具資源管理」,兩個分頁對應兩種形狀;資料層不合併。並定下一條規則:之後任何工具的設定檔或參考資料庫進來,都只能掛在這裡,不准再開新頁。

已拍板 D1、D2、D4 待確認 D3、D5、D6 前作:FR-059/060(設定檔庫)、FR-134/156(弱點資料) 雛形:prototype/index.html
§1

需求背景

我們現在的 Agent 組態檔好像沒有統一在一個功能內……未來應該還會有很多掃描套件的組態檔案或是 profile 或是資料庫等等要管理,是不是應該整理在一個功能裡面?不然每次多一個工具又多一個功能頁面,實在太亂也四散各處,像這次新的弱點資料庫就是這樣,當初做的時候完全忘記有掃描設定檔管理。 — 決策者原話(2026-10-26)

1.1 現況:兩頁各自為政

掃描設定檔管理 弱點資料庫
出身 FR-059/060(2026-08) FR-134/156(2026-10)
選單位置 合規稽核群組 /plugin/detection-profile-manage(排序 35,在「工具插件管理」旁) 系統設定群組 /system/vulndb(排序 38)
幾份 每個工具很多支:DEV 現況 CINC 2 支、GCB 9 支(含 1 支租戶私有) 全機一份,不分租戶
誰挑 派掃描任務時使用者在下拉選要用哪支 沒人挑,掃描自動用現行那份
版本 每支有版本鏈,可回看歷史版、切現行版 只有「現行+更新紀錄」,切換後舊版即刪
來源 使用者上傳檔案或填網址 自家發布站每日出包帶簽章,主系統自動抓;也可手動上傳
送到 Agent 派工時 Agent 依任務參數去主系統拉檔 心跳告知有新版,Agent 自己來拉整包
權限點 detection.profile.{read,create,update,delete} system.vulndb.{read,update}
資料表 config.detection_profiles/_versions/_controls(有 RLS) public.vulndb_updates(平台層、無 RLS、只增不改)
前端 DetectionProfileManageView.vue(947 行)+控制項頁(723 行) VulndbManage.vue(254 行)+更新紀錄+Agent 同步面板

1.2 它們像在哪、不像在哪

像的部分:都是掃描工具要吃的內容;都要管「從哪來、多新、送到 Agent 沒有」;都是管理員在維護。

不像的部分是形狀,而且未來進來的東西也會落在這兩種形狀之一:

形狀 A:設定檔/基準

使用者挑的東西。一個工具有很多支、租戶可以自己上傳、要有版本、派任務時要選。

已有:CINC 基準、GCB 基準。 會來:OpenSCAP 的 SCAP 內容、ZAP 掃描政策、Nmap 腳本組、SonarQube 品質設定檔。

形狀 B:參考資料庫

沒人挑的東西。全機一份、不分租戶、只求新鮮、自動更新。

已有:弱點資料庫(Trivy/Grype/KEV/EPSS)。 會來的判準:我們自己帶在 Agent 裡、資料要獨立於程式版本更新的工具。客戶自裝的產品(OpenVAS、Nessus、SonarQube、ZAP)的特徵庫由它們自己更新,不算。短期內沒有明確的第二個。

FR-059 當初就把形狀 A 設計成「不綁工具」:新工具接入零開發,seed 一筆就能用(FR-059 design §5.7)。形狀 A 的問題已經解掉了。真正沒解的是形狀 B:弱點資料庫是第一個參考資料庫,被做成一支專用頁、專用服務、專用的 Agent 同步接線。下一個 feed 進來,工程師只能整套複製一份改名,又多一頁。


§2

分工概述(30 秒版)

整案一句話:把兩頁收進一個入口「掃描工具資源管理」,兩個分頁、兩種版面;資料不動、後端只加一支紀錄分頁端點;再定一條「新資源只能掛這裡」的規則。

階段 做什麼 產出 完成怎麼判定(決策者檢查法)
第一期:入口合併 新選單「掃描工具資源管理」掛合規稽核群組;兩支既有頁面原樣掛進兩個分頁;兩張舊選單收掉、舊網址自動轉向 一支選單 migration、FE 一支殼頁、兩條轉向 登入後左側選單:合規稽核群組多「掃描工具資源管理」、少「掃描設定檔管理」;系統設定群組少「弱點資料庫」。點進去兩個分頁都能用,功能與今天一樣。在網址列打舊網址會自動跳到新頁對應分頁。用一個只有設定檔權限的帳號登入,只看得到第一個分頁
第二期:參考資料庫宣告驅動 後端開「參考資料庫清單」端點,各工具插件登記自己有哪個資料庫、支援哪些動作;前端照清單長卡片;Agent 心跳與拉包通道改成帶資料庫代號 一支清單端點、插件契約加一段、FE 卡片元件、Agent 同步改通用 畫面與第一期一樣(只有弱點資料一張卡)。工程師在 DEV 用假的「第二個資料庫」登記一筆,不改前端重整頁面就多一張卡

依賴:第一期不依賴任何人。第二期等第二個參考資料庫真的要進來時才做(D3)。決策者功課:D3、D5、D6 三項裁示。


§3

決策

D1 入口頁名稱與位置 — 已拍板

名稱「掃描工具資源管理」,放合規稽核群組、排在「工具插件管理」(30)之後、「第三方元件風險」(40)之前,接「掃描設定檔管理」原本的位子 35。

理由:設定檔是稽核員挑來派任務的,不該藏在管理員的系統設定區。系統設定群組的替代案被排除。

D2 權限點名字 — 已拍板:第一期不改

system.vulndb.* 與 detection.profile.* 兩組名字都保留。入口選單的可見條件是「任一組 read 權限」;各分頁各看自己那組。

理由:改名要連動出貨角色表、前端能力表、客戶已有角色的 pattern,牽動面大但沒換到任何行為。名字留到第二期與「參考資料庫」契約一起整。

D3 第二期(宣告驱動)現在做、還是等第二個資料庫?

第二期要動後端插件契約、Agent 心跳與拉包通道,比搬選單重得多。

建議:等。入口頁版面現在就照「一卡一庫」排好(雛形已如此),機制等第二個參考資料庫立案時一起做。為單一登記者蓋機制,等於為一個客人蓋一棟旅館。而且短期內看不到第二個:Agent 自帶工具裡只有弱點掃描的資料需要獨立更新,OpenSCAP 內容屬於「要挑的設定檔」走第一個分頁,Nmap 特徵隨版本走。反悔條件:任何「我們自己帶、資料要獨立更新」的工具進了排程,第二期就該立刻開。

D4 進行中文件的衝突 — 已拍板:先不管,做完要更新

FR-156 的 G1 卡(CM-3000)正在另一個 session 寫 SPEC 與使用手冊,內容是「弱點資料庫頁在系統設定底下」。本案入口搬了那份文件就過期。

定案:G1 照寫不擋。本案第一期收尾時必做:更新 docs/spec-site/current/ 弱點資料庫頁與掃描設定檔頁的入口位置、使用手冊對應段。已列入 §6 收尾待辦。

D5 舊網址怎麼處理?

/plugin/detection-profile-manage、/plugin/detection-profile-manage/versions/:uid/controls、/system/vulndb 三條舊路由。

建議:前端做永久轉向到新入口對應分頁(控制項頁轉到新入口下的對應路徑),後端不動。使用手冊與 SPEC 裡的連結同步改。替代「保留舊路由當別名」被排除:兩條路到同一頁會讓選單高亮與麵包屑亂掉。

D6 Agent 同步面板放哪?

今天弱點資料庫頁下方有一塊「Agent 同步情況」(每台 Agent 的資料日期與落後天數)。

建議:收進卡片——卡上一行摘要(幾台已同步、幾台落後、幾台離線),點「明細」展開每台清單(雛形已畫)。它是「這個資料庫送到 Agent 沒有」的資訊,屬於該資料庫,不該是頁面層級的獨立區塊;第二個資料庫進來時每張卡各自有自己的同步狀態,版面才對。


§4

第一期詳細設計

4.1 畫面

雛形:prototype/index.html。重點:

  • 頁首:標題「掃描工具資源管理」+一句說明。
  • 兩個分頁(PrimeVue TabView):「設定檔/基準」、「參考資料庫」。各分頁依權限顯示,沒權限的分頁整個不出現;只剩一個分頁時仍顯示分頁列(讓使用者知道這頁有兩類東西)。
  • 分頁一:掛既有 DetectionProfileManageView.vue,零改動。控制項頁 DetectionProfileControlsView.vue 路徑改掛在新入口底下。
  • 分頁二:一卡一庫。卡的版面固定:標題列(名稱、給哪個工具用、狀態膠囊)→ 連不到站的黃字提醒(只在發生時出現)→ 資訊列(資料日期含新鮮度色、來源與站台、自動更新開關、檢查頻率下拉(選項來自 system_menus 的 vulndb_check_interval)、下次檢查、四個來源明細常駐顯示、Agent 同步摘要與明細展開)→ 上傳進度條(上傳中才出現)→ 底列(檢查更新、上傳更新包、更新紀錄)。今天只有弱點資料一張,內容照 VulndbManage.vue 搬,把原本整頁的版面縮成一張卡。
  • 原頁功能一個不少:搬進卡片是換版面不是減功能。驗收時拿 VulndbManage.vue 現有的每個控制項逐一對照(決策者 2026-10-26 審雛形時抓到頻率下拉漏畫)。
  • 沒接上的不預告:設定檔分頁的「工具」下拉只列已接入設定檔庫的工具;參考資料庫分頁只列已登記的資料庫。不放「即將推出」、不放灰掉的選項。
  • 更新紀錄改成對話框(點卡上「更新紀錄」開,按鈕不帶筆數),內有分頁,不再佔頁面下方整塊。後端 status.recent 現在固定回 20 筆,改成分頁端點(本案唯一的後端改動,小)。
  • 不出現:任何「即將推出第二個資料庫」的預告。雛形上那張虛線卡只給決策者看形狀。

設計系統自檢

grep border-left 為零;卡片一律 dark-card;字級全站基準;狀態只出現一次(標題列膠囊)。

4.2 選單與路由(一支 migration)

動作 對象
新增 ui_routes scan-tool-resources,/plugin/scan-tool-resources,父 group-compliance-audit,sort 35,icon pi pi-box
新增 route_capabilities 綁 detection.profile.read 與 system.vulndb.read,requirement ANY(任一就看得到選單)
改 ui_routes detection-profile-manage 與 vulndb 兩筆 enable=0(不刪:升級客戶的 route_capabilities、使用手冊、稽核事件都還指著它們)
改 ui_routes detection-profile-controls 的 url 改為 /plugin/scan-tool-resources/profiles/versions/:versionUid/controls,pid 改指新入口
bump CAPABILITY_CATALOG.VERSION 加一

能力點不新增、不改名(D2)。migration 屬主線 phase=active,寫完回報「出貨基線待重產」。

4.3 前端

檔 動作
src/views/plugin/ScanToolResourcesView.vue(新) 殼頁:標題、TabView、依權限決定哪些分頁出現、?tab= 與 hash 記住分頁
src/views/detection-profile/DetectionProfileManageView.vue 不改。被殼頁當子元件掛進分頁一
src/views/vulndb/VulndbManage.vue 改成卡片形狀:移除頁首與整頁 card 外殼,更新紀錄改對話框,Agent 同步面板收進卡(D6)。邏輯(上傳、檢查、開關)全部不動
src/components/vulndb/ReferenceDbCard.vue(新) 卡片外觀元件:接「標題/用途/狀態/五行資訊/底列按鈕」的 slot,弱點資料是第一個使用者。第二期各資料庫共用這張
src/router 新路由 /plugin/scan-tool-resources、.../profiles/versions/:versionUid/controls;舊三條路由改 redirect(D5)
src/config/locales/i18n/*/menu.json 加 scan-tool-resources 標籤

超標提醒:DetectionProfileManageView.vue 947 行已超 800 行上限,本案不往裡加(它只是被掛進去)。

4.4 後端

只有一處:更新紀錄從 status.recent 固定 20 筆改成獨立分頁端點 GET /system/vulndb/updates?page=&size=(照既有分頁慣例)。其餘兩組端點(/detection/profiles/*、/system/vulndb/*)照用。

4.5 收尾文件(D4)

文件 動作
docs/spec-site/current/ 弱點資料庫頁 入口位置改「合規稽核 → 掃描工具資源管理 → 參考資料庫分頁」;畫面段改卡片形狀
docs/spec-site/current/ 掃描設定檔管理頁 入口位置改「… → 設定檔/基準分頁」;功能內容不變
使用手冊 兩處入口描述同步
docs/claude/frontend-overview.md 「BE 改什麼會牽動 FE」清單加一行:新工具的設定檔或參考資料庫一律掛掃描工具資源管理,不開新頁

§5

第二期輪廓(不在本期做,先把形狀講清楚)

為了讓第一期的版面不會到第二期被推翻,這裡把第二期長什麼樣先講一次。

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
  subgraph plugins[各工具插件]
    P1[jedi-source-scan<br/>登記:vulndb]
    P2[未來某個 Agent 自帶工具的插件<br/>登記:它的資料庫代號]
  end
  REG[參考資料庫登記表<br/>代號/名稱/用途/支援的動作]
  API[GET /scan-resources/reference-dbs<br/>回清單+每個的狀態]
  FE[參考資料庫分頁<br/>一卡一庫,照清單長]
  AG[Agent 心跳:帶每個資料庫的日期<br/>拉包:/agents/reference-dbs/&lt;代號&gt;/bundle]
  P1 --> REG
  P2 --> REG
  REG --> API --> FE
  REG --> AG
圖 1 — 第二期:參考資料庫宣告驅動。前端不認識任何一個資料庫,只問後端清單。

契約的五個動作(每個資料庫宣告支援哪幾個,不支援的按鈕不出現):看狀態(日期、來源、紀錄)、上傳更新包、檢查更新、自動更新開關與頻率、Agent 同步狀態。弱點資料庫今天五個都有,是契約的樣板。

不做的事:不把 vulndb_updates 改成通用表。每個資料庫自己的紀錄表自己管,契約只規範「回傳最近 N 筆的形狀」。


§6

現況接入點盤點

元件 現況 本案動作 期
public.ui_routes 兩筆舊選單 enable=1 enable=0,不刪 一
public.ui_routes 控制項子頁 pid 指 detection-profile-manage 改 pid 與 url 一
public.capabilities 兩組六個能力點 名字分屬 detection.profile.*/system.vulndb.* 不動 一(D2)
DetectionProfileManageView.vue 947 行 獨立頁 掛進分頁一,零改 一
VulndbManage.vue 254 行 整頁版面 縮成卡片,邏輯不動 一
AgentVulndbSyncPanel.vue 頁面層級區塊 收進卡片明細 一(D6)
BE vulndb_settings_app_service.py、vulndb_route.py 弱點資料專用;紀錄固定回 20 筆 加一支更新紀錄分頁端點,其餘不動 一;二期抽契約
core/plugins/_agent_vulndb.py 心跳接線 只認 vulndb 不動 二
jedi_remote_agent 心跳回應 data.vulndb 單一欄位 不動 二(改成帶代號的清單)
FR-156 G1 SPEC/手冊(CM-3000,進行中) 入口寫系統設定 等它收完,本案收尾時改 一(D4)

§7

拆棒(第一期)

四張卡,兩批。

卡 做什麼 改哪些檔 批 驗收
A1 選單與路由 migration 新入口選單、兩筆舊選單停用、控制項子頁改掛、能力綁定 ANY、bump 版本 scripts/sql/2026-10-XX-fr165-scan-tool-resources-menu.sql 1 DEV 套完,ui_routes 多一筆、兩筆 enable=0;用只有 system.vulndb.read 的帳號登入看得到新選單;回報「出貨基線待重產」
A2 前端殼頁與弱點資料卡片化 殼頁+TabView+權限分頁;VulndbManage 縮成卡片、紀錄改對話框、Agent 同步收進卡;ReferenceDbCard 元件;三條舊路由轉向;i18n FE:新 ScanToolResourcesView.vue、新 ReferenceDbCard.vue、改 VulndbManage.vue、router、menu.json 1 對照雛形:兩個分頁、卡片五行資訊、更新紀錄對話框、舊網址轉向。設定檔分頁功能與今天完全一樣(新增、篩選、版本、控制項頁)
A3 更新紀錄分頁端點 GET /system/vulndb/updates 分頁;FE 更新紀錄對話框改打它 BE vulndb_route.py、vulndb_settings_app_service.py、jedi-source-scan repo 加分頁查詢;FE VulndbUpdateHistory.vue 1 curl 帶 page/size 回正確筆數與 meta;對話框翻頁正常
B1 收尾文件 SPEC 兩頁、使用手冊、frontend-overview 規則一行 docs/spec-site/current/...、docs/user-manual/...、docs/claude/frontend-overview.md 2 等 FR-156 G1(CM-3000)收完才派;grep 兩份 SPEC 無「系統設定 → 弱點資料庫」字樣

A1、A2、A3 同批:A1 只動 SQL、A2 只動 FE 殼與卡、A3 動 BE 與紀錄元件,不撞檔;A2 的對話框先接現有 status.recent,A3 做完再換端點(卡內寫明);A2 的路由名要與 A1 的 ui_routes.name 一致(scan-tool-resources),卡內寫死。


§8

收尾待辦