檢測工具管理(Detection Tool Management)
事實基準:2026-07-27 從 FE
src/views/plugin/ToolPluginManage.vue(317 行)+ BEapp/detection_tools/全模組掃出(FR-056 檢測工具整合平台,T-1.1~T-1.5)
變更紀錄
| 日期 | FR | 內容 |
|---|---|---|
| 2026-07-27 | FR-056 | 全面改寫:本頁自 T-1.5 起已從前端 mock
占位頁改為完整接後端功能——工具目錄(config.detection_tools)+
租戶設定 CRUD(含加密憑證)+ 測試連線(雲端直推 Agent)+ 動態參數 schema
+ D6 引用計數軟提醒 + 重置金鑰;舊版「hardcoded 工具清單、無
API」的紀錄已完全過時 |
1. 功能描述
檢測工具管理是租戶層級的外部資安檢測工具設定介面:管理平台工具目錄中已啟用的檢測工具(首發 OpenVAS 弱點掃描),供租戶填寫連線資訊(主機位址、帳密等)、測試連線、並在 任務配置 頁把工具綁定到「檢測工具執行」型任務上。
平台維護的「工具目錄」(config.detection_tools)是
DB
驅動而非程式寫死:每筆工具定義代碼、顯示名稱、連線類型(API/CLI)、設定欄位結構(config_field_schema,動態表單
JSON)與平台層
status(available/coming_soon)。本頁的設定表單、任務配置頁的掃描參數表單,皆完全依
BE 回傳的 schema 動態渲染——FE
對工具型別零硬編,新增工具(如未來 Nessus/SonarQube 轉正)只需目錄補資料
+ Agent 端補 connector,前端不用改代碼。
主要使用者:租戶層級管理者(過渡期以帳號層
super_admin 守門,見 §3)。
角色速覽:
| 角色 | 一句話 |
|---|---|
| 租戶 admin(過渡期=帳號 super_admin) | 本頁唯一使用者——新增/修改工具設定、測試連線、停用、重置金鑰 |
| (Agent 本身) | 不是本頁使用者,而是「測試連線」與真實掃描的實際執行者;透過雲端 mTLS 直推指令運作,不經過本頁 UI |
1.1 功能總覽(本頁全部功能)
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 1 | 工具目錄清單 | 卡片呈現平台工具目錄(GET /detection-tools,僅回
available 者,coming_soon
由目錄本身標記過濾邏輯在 BE) |
主畫面 Card grid | §6.2 |
| 2 | 搜尋工具 | 依工具名稱前端本地過濾(searchedTool) |
搜尋框 | 純前端 |
| 3 | 待啟用工具灰化 | status==='coming_soon' 的工具卡片降低透明度 +
顯示「敬請期待」Tag,動作按鈕全部隱藏 |
工具卡片 | §5 |
| 4 | 設定 / 編輯連線資訊 | 開 Dialog,依 config_field_schema 動態渲染欄位(含
secret 遮罩);首次設定按鈕文案「設定」,已有設定後文案「編輯」 |
Dialog | UC-TPM-01 |
| 5 | 測試連線 | 以已存檔設定值,透過雲端直推內網 Agent 實際連線工具端驗證 | 工具卡片按鈕(僅已設定才顯示) | UC-TPM-02 |
| 6 | 啟用 / 停用 | 已有設定的工具可切換
status(enabled/disabled);停用前查詢引用任務數(D6
軟提醒,不擋) |
工具卡片按鈕 | UC-TPM-03 |
| 7 | 重置金鑰 | 清空該工具設定的加密憑證,需重新輸入才能再用 | 工具卡片按鈕(僅已設定才顯示) | UC-TPM-04 |
UC(§2)展開本頁所有具實質後端寫入/呼叫邏輯的功能:新增/編輯設定(4,UC-TPM-01)、測試連線(5,UC-TPM-02)、停用(6,UC-TPM-03)、重置金鑰(7,UC-TPM-04)。純顯示/前端過濾類(1 目錄清單、2 搜尋、3 灰化)於 §5 說明。
2. Use Case
角色速覽:見 §1。
流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
UC-TPM-01 新增 / 編輯工具連線設定
| 項目 | 內容 |
|---|---|
| 角色 | 租戶 admin(過渡期=帳號 super_admin) |
| 前置條件 | 該工具目錄項 status==='available'(非
coming_soon) |
| 產出 / 後置條件 | 新增:config.tenant_detection_tool_configs
新增一列;編輯:更新既有列(secret 欄位留空=不動既有密文) |
流程:開 Dialog(依 config_field_schema 動態渲染)→
必填欄位未填且已 touched → 顯示「{欄位名} 為必填」→ 送出時 secret
欄位分流進 credentials(有值才帶)、其餘進
field_values → POST(新增)或
PUT(編輯)→ 成功關閉 Dialog 並重整清單。
UC-TPM-02 測試連線
| 項目 | 內容 |
|---|---|
| 角色 | 租戶 admin |
| 前置條件 | 該工具已有設定(config 非 null)且已存檔 |
| 產出 / 後置條件 | 無寫入設定內容;僅更新 last_tested_at /
last_test_result |
流程:按「測試連線」→ BE 解密該租戶已存憑證 →
挑一台本租戶啟用中、capabilities 含
detection_scan 的 Agent → 透過既有 FR-039 mTLS 通道推送
POST /detection/probe(帶解密後憑證)→ Agent
用與真實掃描相同的連線方式(OpenVAS 為 python-gvm GMP over TLS)實連驗證
→ 結果同步回傳 → 記錄
last_tested_at/last_test_result。三種失敗原因分開呈現:①未設定憑證
②本租戶無可用 detection_scan Agent ③Agent
連得到但工具端連不通/帳密錯(訊息由 Agent 回傳原樣顯示)。
UC-TPM-03 停用工具設定
| 項目 | 內容 |
|---|---|
| 角色 | 租戶 admin |
| 前置條件 | 該工具已有設定且目前為 enabled |
| 產出 / 後置條件 | status 改為
disabled;停用後任務配置頁該工具仍列在下拉(下拉來源未过滤
status,見 §12 坑 3) |
流程:按「停用」→ 先查詢
count_referencing_tasks(該工具目錄項被幾個
job_execution_detection_tools 綁定引用)→ 引用數 >0 時
confirm 訊息加註「有 {count} 個任務正使用此工具設定,仍要停用嗎?」,=0
時純確認訊息 → 不論引用數多少,確認後一律直接停用(D6
軟提醒,非阻擋)→ PUT 更新 status。
UC-TPM-04 重置金鑰
| 項目 | 內容 |
|---|---|
| 角色 | 租戶 admin |
| 前置條件 | 該工具已有設定(config 非 null) |
| 產出 / 後置條件 | credentials_encrypted 清空為
NULL;field_values(非機敏欄位)不受影響 |
流程:按「重置金鑰」→ confirm(「確定要重置 {name}
的憑證嗎?重置後需重新設定才能使用。」)→ 確認 →
POST /detection-tools/configs/{uid}/reset →
成功後重整清單,該工具的機敏欄位回到未設定狀態(下次開 Dialog 不再顯示
•••• 遮罩)。
3. 權限矩陣
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 進入本頁 | ui_routes web-menu 可見性 |
N/A(僅 JWT) | — |
| 讀工具目錄 / 讀租戶設定清單 | 無 | 僅 @jwt_required() |
api/detection_tools/routes/detection_tool_route.py::DetectionToolsRoute
/ TenantDetectionToolConfigsRoute |
| 新增 / 編輯 / 重置金鑰 | 無額外前端角色判斷 | ⚠️ 帳號層
require_super_admin()(過渡期)——非租戶層角色,是帳號是否為系統層
super_admin |
app/detection_tools/service/detection_tool_service.py::create_tenant_config
/ update_tenant_config /
reset_tenant_config_key |
| 測試連線 / 停用 / 查引用數 | 無 | 僅 @jwt_required()(無角色守門) |
test_connection /
update_tenant_config(停用走同一 update 端點)/
count_referencing_tasks |
⚠️ 已知過渡設計(非遺漏):新增/編輯/重置走帳號層
require_super_admin(),是因為本模組的租戶層 capability(detection-tools-manage.*)尚未 seed,過渡期先用帳號層守門頂著(見detection_tool_service.py:73-75註解引用 D6 附註 + implementation-plan Task 3 Step 9)。這與本群其餘管理頁「僅 JWT 無角色守門」的既有基調不同——本頁反而是「守太緊」而非「沒守」,日後 capability seed 完成後應改為租戶層權限模型,勿誤以為現況是終態設計。測試連線 / 停用兩個動作目前完全無角色檢查,只靠 RBAC 選單擋入口。
4. 狀態機與前置條件
本頁無輪次 / 階段狀態機,僅有工具目錄與租戶設定各自獨立的狀態:
| 條件 | 效果 | 出處 |
|---|---|---|
detection_tools.status === 'coming_soon' |
工具卡片灰化(opacity-60),動作按鈕全部隱藏(v-if="tool.status !== 'coming_soon'") |
ToolPluginManage.vue:230,247 |
detection_tools.status === 'available' |
才可新增設定(create_tenant_config 檢查,否則
DETECTION_TOOL_NOT_AVAILABLE) |
detection_tool_service.py:76-78 |
tenant_detection_tool_configs.status |
enabled:可被任務綁定使用;disabled:下拉未過濾,仍可能被選中(見
§12 坑 3) |
— |
Dialog:currTool.config 存在 |
「設定」按鈕文案變為「編輯」;onOpenConfigDialog 用既有
field_values/has_credentials 預填表單 |
ToolPluginManage.vue:56-65,248-254 |
欄位 field.secret && hasExistingValue |
該欄位 placeholder 顯示「••••(已設定,留空不變更)」,不回顯明文 | DetectionConfigField.vue:21-26 |
5. UI 設計
版面骨架(Card grid + 設定 Dialog):
📸 實機截圖待補:工具卡片 grid、設定 Dialog(含 secret 遮罩)、測試連線成功/失敗 toast。
狀態呈現:每張工具卡片右上角狀態 Tag——coming_soon
顯示「敬請期待」(secondary);有設定則依 config.status
顯示綠色「啟用」或紅色「停用」。設定 Dialog
標題固定為「啟用檢測工具」(t('lang.plugin_manage.active_plugin'),即使是編輯既有設定也沿用此標題,屬既有文案非新坑)。無
socket;所有動作後重打 fetchAll()
重新整理整頁資料(未做局部 state 更新)。
6. API 規格
Envelope:成功 {"code": 1, "data": …}、失敗
{"code": 0, "msg": "…"}(return_response)。
6.1 總清單(本頁呼叫的全部 endpoint)
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 目錄 | GET /detection-tools |
工具目錄清單(僅回平台層啟用者) | §6.2 |
| 目錄 | GET /detection-tools/{uid} |
單筆工具目錄項(本頁未直接用,供他頁/除錯) | GAI-SD-02 |
| 目錄 | GET /detection-tools/{uid}/param-schema |
取工具當前生效版本的任務參數 schema(本頁不用,供 任務配置頁 動態渲染掃描參數) | GAI-SD-02 |
| 租戶設定 | GET /detection-tools/configs |
本租戶所有工具設定清單 | §6.2 |
| 租戶設定 | POST /detection-tools/configs |
新增租戶工具設定(含加密憑證) | §6.3 |
| 租戶設定 | PUT /detection-tools/configs/{uid} |
更新租戶工具設定(含停用切換) | §6.3 |
| 租戶設定 | POST /detection-tools/configs/{uid}/reset |
重置憑證(清空為 NULL) | §6.4 |
| 租戶設定 | POST
/detection-tools/configs/{uid}/test-connection |
測試連線(雲端直推 Agent) | §6.4 |
| 租戶設定 | GET
/detection-tools/configs/{uid}/referencing-tasks-count |
停用/重置前查引用任務數(D6 軟提醒) | §6.4 |
任務執行相關端點(
/detection-tools/jobs/{job_uid}/execute、.../executions)屬 任務執行抽屜 功能,非本頁呼叫,列在該頁 spec。
6.2 工具目錄 / 租戶設定清單
[GET] /detection-tools
無 query。Response
data[](DetectionToolResponse):
| 欄位 | 型別 | 說明 |
|---|---|---|
| uid / code / name / description | string | 工具識別與顯示資訊 |
| connection_type | string | API / CLI(目前皆為 API) |
| config_field_schema | array | 動態表單欄位定義:[{key, type, label, secret, required}];type
為
text/password/number/select |
| status | string | available / coming_soon |
| enabled | bool | 平台層總開關 |
出處:api/detection_tools/serializers/detection_tool.py:4-12(DetectionToolResponse)、route
DetectionToolsRoute、service
detection_tool_service.py::list_tools(get_tools(enabled=True))。現況種子資料(DEV
實查
config.detection_tools):openvas(available,4
欄位:base_url/username/password(secret)/port)、nessus(coming_soon,空
schema)、sonarqube(coming_soon,空 schema)。
[GET] /detection-tools/configs
無 query。Response
data[](TenantDetectionToolConfigResponse):
| 欄位 | 型別 | 說明 |
|---|---|---|
| uid | string | 設定識別碼 |
| detection_tool_id | int | → config.detection_tools.id |
| detection_tool_code | string|null | 服務層補算(list_tenant_configs 依
detection_tool_id 對照目錄),供 FE 依 code
合併進工具卡片 |
| field_values | object | 非機敏欄位值(如 base_url) |
| status | string | enabled / disabled |
| has_credentials | bool | 是否已設定機敏欄位——絕不回傳憑證明文/密文,只回布林 |
| last_tested_at / last_test_result | datetime|null / string|null | 最近一次測試連線時間與結果 |
出處:api/detection_tools/serializers/detection_tool.py:16-38(TenantDetectionToolConfigResponse.dump_entity
手動補 has_credentials)、service
detection_tool_service.py:58-69::list_tenant_configs。FE
合併邏輯:ToolPluginManage.vue:16-28(tools
computed,依 detection_tool_code === tool.code 配對)。
6.3 新增 / 更新設定
[POST] /detection-tools/configs
Request:
{
"tool_uid": "<detection_tools uid>",
"credentials": {"password": "..."},
"field_values": {"base_url": "https://...", "username": "...", "port": 9390},
"status": "enabled"
}| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
| tool_uid | string | 是 | 目標工具目錄項 |
| credentials | object | 否 | 機敏欄位(field.secret===true)→ 加密後存
credentials_encrypted;FE 全部留空則整個 key 省略 |
| field_values | object | 否 | 非機敏欄位(如 base_url) |
| status | string | 否 | 預設 disabled |
工具目錄項 status !== 'available' →
DETECTION_TOOLS_400002(DETECTION_TOOL_NOT_AVAILABLE)。出處:api/detection_tools/serializers/detection_tool.py:41-45(TenantDetectionToolConfigCreateRequest)、route
TenantDetectionToolConfigsRoute.post、service
detection_tool_service.py:71-90::create_tenant_config。
[PUT] /detection-tools/configs/{uid}
Request(全部選填,partial-update
語意——None 欄位不更新):
| 欄位 | 型別 | 說明 |
|---|---|---|
| credentials | object | 有值才加密覆寫;FE 不帶(機敏欄位皆留空)→ None → repo
update()
skip,保留既有密文(幽靈覆寫防護) |
| field_values | object | 覆寫非機敏欄位 |
| status | string | 單獨送 {status: "disabled"}
即可只切換啟用狀態(本頁「停用」按鈕即此用法) |
出處:api/detection_tools/serializers/detection_tool.py:48-51(TenantDetectionToolConfigUpdateRequest)、service
detection_tool_service.py:92-105::update_tenant_config。
FE
送出邏輯(ToolPluginManage.vue::buildPayload:71-89):遍歷
config_field_schema,值為
null/undefined/空字串一律跳過(不塞進
payload);secret 欄位分流進
credentials,其餘進
field_values;credentials 物件若無任何 key
則整個欄位設為 undefined(axios
序列化時省略),確保「全部留空=不動既有密文」。
6.4 重置 / 測試連線 / 引用計數
[POST] /detection-tools/configs/{uid}/reset
無 body。Response
data:{"success": true}。清空
credentials_encrypted 為 NULL(專用
clear_credentials 方法,區別於 update() 的
None=skip 語意——重置要的正是清空,不能被 skip
邏輯擋住)。出處:service
detection_tool_service.py:107-112::reset_tenant_config_key。
[POST] /detection-tools/configs/{uid}/test-connection
無 body。Response
data:{"success": bool, "message": string}。
三種失敗訊息(皆 success=false,非 HTTP 錯誤):
| 情境 | message(i18n key) |
|---|---|
| 該設定未存憑證 | detection_probe_no_credentials |
本租戶無 detection_scan capability 的 Agent |
detection_probe_no_agent |
| Agent 連得到但工具端連不通/帳密錯 | Agent 回傳的原始訊息(透傳) |
出處:service
detection_tool_service.py:114-142::test_connection;憑證合併邏輯(field_values
+ 解密後的 credentials)於 :137;實際 mTLS
直推見
infra/detection_tools/connector/agent_probe_client.py(PROBE_PATH = "/detection/probe")。
[GET] /detection-tools/configs/{uid}/referencing-tasks-count
無 query。Response data:{"count": int}——D6
軟提醒,不擋停用/重置動作,僅供 FE
組確認訊息文案。出處:service
detection_tool_service.py:144-155::count_referencing_tasks(解出
tenant_config → detection_tool_id 後查
job_execution_detection_tools 引用數)。
7. 前端檔案地圖(compliance-manager-fe/)
| 檔案 | 角色 |
|---|---|
src/views/plugin/ToolPluginManage.vue |
主檢視(317 行):目錄+設定合併、搜尋、設定 Dialog、啟用/停用、測試連線、重置金鑰 |
src/components/detection-tools/DetectionConfigField.vue |
動態欄位渲染元件(73 行):依 field.type 渲染
InputText/Password/InputNumber/Dropdown,secret 遮罩邏輯 |
src/service/DetectionToolService.js |
API 包裝(70 行):listTools / listConfigs
/ createConfig / updateConfig /
testConnection / getReferencingTaskCount /
resetConfig / getParamSchema |
src/config/router/index.js:614-627 |
route tool-plugin-manage,path
/plugin/tool-plugin-manage |
src/config/api/api.js:341-347 |
DETECTION_TOOLS / DETECTION_TOOL_CONFIGS /
DETECTION_TOOL_TEST_CONNECTION /
DETECTION_TOOL_REF_COUNT /
DETECTION_TOOL_RESET /
DETECTION_TOOL_PARAM_SCHEMA 常數 |
src/config/locales/i18n/{zh-tw,en}/pages.json(plugin_manage
namespace) |
頁面
i18n:title/setup/coming_soon/field_required/secret_placeholder/reset_confirm/disable_with_refs
等 + 各工具說明(openvas_desc 等) |
src/config/locales/i18n/{zh-tw,en}/menu.json |
選單標題「檢測工具管理」——選單本身已完全啟用,非停用狀態(動態依帳號
permissions 顯示,非硬編停用清單) |
8. 後端檔案地圖(本頁核心鏈路)
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| 工具目錄 | api/detection_tools/routes/detection_tool_route.py::DetectionToolsRoute(GET)/
DetectionToolDetailRoute |
app/detection_tools/service/detection_tool_service.py::list_tools
/ get_tool |
domain/detection_tools/service/detection_tool_domain_service.py
→
infra/detection_tools/repository/detection_tool_repo_impl.py |
| 租戶設定 CRUD | TenantDetectionToolConfigsRoute(GET/POST)/
TenantDetectionToolConfigDetailRoute(PUT) |
DetectionToolService.list_tenant_configs /
create_tenant_config /
update_tenant_config(皆 @transaction) |
domain/detection_tools/service/tenant_detection_tool_config_domain_service.py
→
infra/detection_tools/repository/tenant_detection_tool_config_repo_impl.py |
| 重置金鑰 | TenantDetectionToolConfigResetRoute |
DetectionToolService.reset_tenant_config_key |
同上 repo clear_credentials |
| 測試連線 | TenantDetectionToolConfigTestConnectionRoute |
DetectionToolService.test_connection |
infra/detection_tools/connector/agent_probe_client.py::AgentProbeClient(mTLS
+ 短效 JWT,直推 Agent) |
| 引用計數 | TenantDetectionToolConfigRefCountRoute |
DetectionToolService.count_referencing_tasks |
domain/detection_tools/service/job_execution_detection_tool_domain_service.py |
| 參數 schema | DetectionToolParamSchemaRoute(本頁不用,任務配置頁用) |
DetectionToolService.get_param_schema |
domain/detection_tools/service/detection_tool_param_schema_domain_service.py |
DDD 提醒:route 不碰 DB、app service 全數
@transaction、domain service 不依賴 infra、repo
遵循既有分層。唯一偏離常態的是新增/編輯/重置走帳號層
require_super_admin()(過渡期設計,見 §3
說明),測試連線/停用則完全無角色守門——兩者是不同方向的偏離,改動時務必分開看待。
9. DB
9.1 資料表總清單(本頁讀寫的全部表)
| 表 | 讀/寫 | 說明 | 欄位詳述 |
|---|---|---|---|
| config.detection_tools | 讀 | 平台工具目錄(種子資料,本頁不寫) | §9.3 |
| config.tenant_detection_tool_configs | 寫 | 租戶工具連線設定(加密憑證 + 非機敏欄位 + 狀態) | §9.3 |
| config.detection_tool_param_schemas | 讀(間接,供 任務配置頁) | 工具任務參數 schema(版本化,is_current
標記生效版) |
§9.3 |
| config.job_execution_detection_tools | 讀(供引用計數) | 任務↔︎工具綁定(本頁不寫,寫入在 任務配置頁) | 任務配置頁 §9.3 |
9.3 核心表欄位(取自 DEV DB dump)
config.detection_tools — 平台工具目錄
| 欄位 | 型別 | 說明 |
|---|---|---|
| id | bigint | 內部主鍵(config.job_execution_detection_tools.detection_tool_id
FK 目標) |
| uid | varchar(36) | 對外識別碼 |
| code | varchar(50) | 工具代碼(openvas/nessus/sonarqube),FE
用來比對合併租戶設定 |
| name / description | varchar / text | 顯示名稱 / 說明 |
| connection_type | varchar(20) | API / CLI |
| config_field_schema | jsonb | 動態設定表單欄位定義:[{key, type, label, secret, required}] |
| status | varchar(20) | available / coming_soon |
| enabled | boolean | 平台層總開關 |
config.tenant_detection_tool_configs — 租戶工具連線設定
| 欄位 | 型別 | 說明 |
|---|---|---|
| uid | varchar(36) | 對外識別碼 |
| tenant_id | bigint | 租戶(RLS 隔離) |
| detection_tool_id | bigint | →
config.detection_tools(uq_tdtc_tenant_tool
唯一約束:每租戶每工具僅一筆設定) |
| credentials_encrypted | text|null | 機敏欄位加密後 JSON(對稱加密,金鑰
DETECTION_TOOL_ENCRYPTION_KEY 環境變數,不進版控) |
| field_values | jsonb | 非機敏欄位值(如 base_url) |
| status | varchar(20) | enabled / disabled(預設
disabled) |
| last_tested_at | timestamp|null | 最近一次測試連線時間 |
| last_test_result | varchar(20)|null | success / fail |
config.detection_tool_param_schemas — 工具任務參數 schema(版本化)
| 欄位 | 型別 | 說明 |
|---|---|---|
| detection_tool_id | bigint | →
config.detection_tools(uq_dtps_tool_version
唯一約束:(detection_tool_id, version)) |
| version | int | 版本號,遞增(如 OpenVAS v1→v2 新增 port_list_id
欄位) |
| param_schema | jsonb | 任務掃描參數欄位定義(供 任務配置頁 動態渲染) |
| is_current | boolean | 是否為當前生效版本(get_current_schema 依此篩選) |
與
config_field_schema的差異:detection_tools.config_field_schema是連線設定欄位(本頁用,如帳密/主機),detection_tool_param_schemas.param_schema是任務掃描參數欄位(任務配置頁用,如 hosts/timeout_sec)——兩者是不同層次的 schema,命名相近容易混淆。
10. 頁面邏輯與資料對應
載入時序:onMounted 平行觸發
listTools() + listConfigs(),FE 端依
detection_tool_code === tool.code 合併成 tools
computed(工具卡片資料來源)。
關鍵欄位對應(畫面 ↔︎ API):
| 畫面元素 | FE state | API 欄位 |
|---|---|---|
| 工具卡片清單 | tools(computed,目錄+設定合併) |
GET /detection-tools +
GET /detection-tools/configs |
| 設定 Dialog 欄位 | form[field.key] |
依 tool.config_field_schema 動態產生,預填
tool.config.field_values |
| secret 欄位遮罩 | DetectionConfigField 的 hasExistingValue
prop |
config.has_credentials |
| 狀態 Tag | 直接綁定 | tool.config?.status(無設定 = 不顯示) |
| 測試連線結果 | toast | test-connection 回傳
{success, message} |
儲存流程:onSaveConfig 先做 client
端必填檢查(略過已有憑證的 secret 欄位)→ buildPayload()
分流 credentials/field_values →建立走 POST、既有走 PUT → 成功後關閉
Dialog + fetchAll() 整頁重新整理(非局部更新)。
錯誤對應:BE error envelope → toast
顯示;本頁常見碼:DETECTION_TOOLS_400002(工具非 available
不可新增設定)、DETECTION_TOOLS_404002(設定不存在)。測試連線刻意不用例外,而是回
{success:false, message},避免整頁被連線失敗中斷。
11. 背景行為與外部依賴
| 類型 | 內容 |
|---|---|
| 通知 | 無——本頁不觸發、也不消費任何通知 |
| Socket | 無 socket / 輪詢;動作後皆整頁 fetchAll() |
| mTLS / Agent 直推 | 測試連線走 FR-039 既有 mTLS
通道(AgentProbeClient,mode=full 時 mTLS
client 憑證 + 短效 JWT;mode=none 裸 HTTP
demo),與真實掃描派工共用同一認證機制 |
| 憑證加密 | DETECTION_TOOL_ENCRYPTION_KEY(BE
部署環境變數,非資料庫值,不進版控)——對稱加密租戶填寫的機敏欄位;api_log
對本模組請求 body 遮罩憑證欄位,不落明文(D9,e2eb1c2c
修正) |
| jedi-* 套件 | 無直接依賴(本模組為 FR-056 全新自研,未借用既有 jedi-* 套件) |
| 系統參數 | DETECTION_TOOL_ENCRYPTION_KEY(環境變數,非 DB feature
flag) |
12. 邊界情況與已知坑
- 新增/編輯/重置走帳號層
require_super_admin(),非租戶層權限:本模組租戶層 capability(detection-tools-manage.*)尚未 seed,過渡期直接卡帳號是否為系統層 super_admin——這與「租戶 admin」的直覺角色定位不完全一致(見 §3),日後 capability seed 完成需改為租戶層權限模型。 - 測試連線 / 停用完全無角色守門:僅
@jwt_required(),任何登入者理論上都能對已知 config uid 呼叫測試連線或停用——與新增/編輯的「守太緊」形成不一致的守門粒度,改動時勿混為一談。 - 停用後任務配置頁下拉未過濾
status:config.tenant_detection_tool_configs.status='disabled'後,任務配置頁的工具下拉來源是GET /detection-tools(工具目錄,非租戶設定),本身不檢查租戶設定狀態——理論上使用者仍可能選到一個已停用設定的工具,實際派工時會因缺憑證(_resolve_credentials找不到enabled設定)失敗。此為現況行為,未做前端過濾。 config_field_schema(連線設定)與param_schema(任務參數)是兩層不同 schema:命名相近但用途、消費頁面都不同(見 §9.3 附註),維護時勿混淆——改一邊不會影響另一邊。- 憑證合併邏輯:測試連線時
field_values(如base_url)與解密後的credentials(如password)需合併才是完整連線資訊(test_connection:137),單看其中一邊資訊不全——早期版本曾漏合併(b26f83f1修正)。 credentials全空時整個欄位省略,非傳空物件:FEbuildPayload()若無任何 secret 欄位有值,credentials設為undefined(非{})——若改成送空物件{},BEcreds = payload.get("credentials")會判定為 truthy(非 None)而觸發加密覆寫,把既有密文洗成加密後的空字串,是需要留意的坑(現況實作正確,記錄供未來重構參考)。coming_soon工具無法被選為連線設定或任務綁定:create_tenant_config明確擋status != 'available'(DETECTION_TOOLS_400002),FE 也把按鈕全部隱藏——nessus/sonarqube目前只是目錄佔位,尚無 Agent connector 實作。
13. 開發與驗證
- 跑起來:BE
python main_socketio.py(port 8000,log 在log/app.log);FE 在compliance-manager-fe/起 Vite dev server。BE 改 service code 後必須重啟(無 hot reload) - 測試帳號:dev 環境系統層 super_admin 帳號(密碼見
.env/ 部署文件)——新增/編輯/重置需此權限 - 導航路徑:登入 → 合規稽核 →
「檢測工具管理」(
/plugin/tool-plugin-manage) - 前置資料:
config.detection_tools需已 seed(scripts/sql/2026-07-26-fr056-1-detection-tools-config-schema.sql);測試連線需本租戶已部署具detection_scancapability 的 Agent(見 檔案 Agent 管理 §12 坑 10——capabilities 欄位目前僅能直接改 DB 設定) - E2E:
compliance-manager-test/repo(Cucumber + Playwright);以檢測工具/detection-tool/tool-plugin搜尋 - 相關文件:完整使用手冊見
docs/features/FR-056-2607-detection-tool-integration/user-manual.html;任務綁定與掃描參數見 任務配置與啟動;執行歷史與重新執行/取消機制見 任務執行抽屜;Agent capabilities 設定見 檔案 Agent 管理