| 項目 | 內容 |
|---|---|
| 緣由 | FR-058 分批出貨。第一批(ID 解耦 + 任務層敏感參數 + ZAP,CM-958〜970)實作已完成、agent 已 bump 0.2.12 部署 DEV 中。本文是第二批(InSpec/CINC → GCB)實作 session 的派工單 |
| Branch | BE:feature/FR-058(不切 branch);evidence-agent:當下 branch(HEAD c775fc8 bump 0.2.12) |
| 本棒角色 | 實作者。 完成 FR-058.2(InSpec/CINC connector)與 FR-058.3(GCB),依 T-2.1〜T-2.4 + T-3.1〜T-3.3 順序做,每個子任務完成即 commit + 回寫 Notion 卡 |
| 接手前必讀 | 本文全份 + design.md §2(D5/D6/D7/D8)+ §4.3〜§4.4(InSpec 與 GCB 詳細設計)+ §5.5〜§5.6(子任務表) |
| 上游文件 | docs/features/FR-058-2607-detection-tools-expansion/handoff/2026-07-30-fr058-planning-complete-handoff.md(全案大圖與需求演變;本文已摘實作所需部分,卡住時才回頭讀) |
design.md §4.3(FR-058.2 InSpec/CINC 詳細設計)+ §4.4(FR-058.3 GCB 詳細設計)全讀design.md §2 的 D5 / D6 / D7 / D8 定案原文(本文 §2 是摘要,原文含被排除方案與理由)第二批 = FR-058.2(InSpec / CINC Auditor)→ FR-058.3(GCB),共 7 個子任務,序列執行(.3 依賴 .2 的 connector,不可對調)。
| # | 子任務 | Repo | 一句話 |
|---|---|---|---|
| T-2.1 | seed InSpec/CINC(connection_type 涵蓋 SSH 與 WinRM)+ config_field_schema(雙 transport 憑證,含條件顯示)+ param_schema + setup_guide(含 CINC 授權說明與 WinRM 啟用前提);三環境套用 | BE | migration |
| T-2.2 | Dockerfile 加入 CINC Auditor + inspec.py 骨架(雙 transport 連線參數解析)+ probe()(連線 / 認證 / CINC 可執行三段檢查與錯誤分類) |
evidence-agent | connector 骨架 |
| T-2.3 | run() 執行 profile + --reporter json 統一解析 + 逐台多檔證據 + host_failures 逐台失敗回報 + cancel_event / timeout |
evidence-agent | connector 主體 |
| T-2.4 | 結案 Notion CM-953(本 FR 吸收,於 T-2.3 完成時一併標記) | Notion | 結案 |
| T-3.1 | seed GCB 條目(引擎指向 .2 的 CINC,Windows 與 Linux 共用)+ param_schema(含 content 來源指定欄位)+ setup_guide;三環境套用 | BE | migration |
| T-3.2 | content 外部載入接口(profile 由外部提供給 connector,不硬編、不隨 agent image 發布) | evidence-agent | 接口 |
| T-3.3 | 一份 Windows 最小 Demo profile(必須落在 HKLM\Software\Policies 正規政策區)——端到端鏈路的驗收留到全案最後(見 §5),本子任務交付 profile 本體與載入驗證 |
evidence-agent | Demo content |
https://app.notion.com/p/3ad346da4cd081859d2ed8b21ca2697c)| 卡 | 對應 | Notion URL |
|---|---|---|
| CM-971(FR-058.2 母卡) | InSpec / CINC Auditor | https://app.notion.com/p/3ad346da4cd0811faa85fd15a38df059 |
| CM-972 | T-2.1 | 從母卡 CM-971 子卡清單進入 |
| CM-973 | T-2.2 | 同上 |
| CM-974 | T-2.3 | 同上 |
| CM-975 | T-2.4(結案 CM-953) | 同上 |
| CM-976(FR-058.3 母卡) | GCB | https://app.notion.com/p/3ad346da4cd08120b9f1cf9b1f976847 |
| CM-977 | T-3.1 | 從母卡 CM-976 子卡清單進入 |
| CM-978 | T-3.2 | 同上 |
| CM-979 | T-3.3 | 同上 |
CM-953(https://app.notion.com/p/3ac346da4cd0819390d2c5b85c754bf8,「FR-057 後續:異質 OS 環境的檢測支援方案」):規劃階段已先標 Done 並指向 CM-971;T-2.4 時確認其結案敘述指向實際落地的 commit 與 connector,補上一段白話結案說明(InSpec/CINC 即該案選項 2 的具體答案,「一任務一工具、多任務處理異質環境」模型沿用未改)。
逐條列出,違反任一條即為錯誤實作:
setup_guide 與部署文件都要寫明這一點。--reporter json(兩個 transport 輸出格式一致,connector 只寫一套解析)。不要只做 WinRM——GCB 的 Linux 線之後就要回頭補一次。inspec.py,T-3.x 不新增任何 connector 檔案。content 只做一份 Windows 最小 Demo profile;驗收條件是「鏈路可運作」,不是「涵蓋多少規則」——不要做 content 工程。tenant_detection_tool_configs 加密鏈(與 SSH 同模型)。只有「每台主機不同帳密」的情境才走 FR-058.0 的任務層敏感參數(平台能力已就緒,見 §3.3),不要一開始就往任務層推。HKLM\Software\Policies 正規政策區。非 Policies 路徑的設定套用前不會被清空、會殘留(tattoo settings),讀到殘留舊值會誤判為通過——稽核情境屬嚴重問題。Demo 選題時就要挑正規政策區的項目。result_ref.upload_uids 多檔回收鏈直接沿用),host_failures 逐台失敗回報——其中一台失敗不可拖垮其他台,也不可靜默假成功。connection_type 的 WinRM 為新值(SSH 已存在);detection_tools.connection_type 需涵蓋兩種型態,seed 時注意欄位值與 FE 渲染相容。遇到 D1–D11 沒涵蓋的新決策:停下來回報,不要自己開新方向(判斷原則見 design.md §2 各條的「被排除方案與原因」欄)。
f17a311,D11)get_connector() 現在優先吃 detection_tool_code,detection_tool_id 降為 fallback(走 fallback 記 warning log)。core/task_executor_connectors/__init__.py 加一個 _build_inspec() builder(import 留在 builder 內部,維持 lazy import 慣例——某支 connector 的第三方相依缺失時只有該工具不可用),並在 _CONNECTOR_BUILDERS dict 加 "inspec": _build_inspec(實際 code 以 T-2.1 seed 的 detection_tools.code 為準)。_LEGACY_TOOL_ID_TO_CODE——檔頭註解已明訂該表只涵蓋 FR-056/057 已出貨四筆,新工具加入等於把剛移除的脆弱性種回去。ZAP 已照此模式(參考 _build_zap)。detection_tool_code(BE commit 5151fb2c,T-X.1 已上線)_collect_pending_tasks() 已加欄位,第二批不需要動 BE 派工鏈——seed 進 detection_tools 後派工自然帶 code,agent 端照 §3.1 註冊即可接上。
5151fb2c,T-0.1〜0.3)param_schema 欄位標 secret: true 即自動走 Fernet 加密落庫 / 派工解密下發 / FE 與稽核 log 剝除(實作在 common/util/detection_secret_params.py)。第二批預設用不到(WinRM 憑證走租戶層,見 §2 第 6 條),但若真遇到「每台主機不同帳密」需求,直接標 secret: true 即可,不需自建機制。
ZAP 原定用 reports.generate 產 PDF,實作時發現該 API 只把檔案寫進工具主機磁碟、回傳路徑字串,官方沒有回傳檔案內容的端點(zaproxy issue #7821)——遠端部署模型下 agent 拿不到,被迫改案(改 core.htmlreport 取 bytes)。
通則:任何「工具端產檔」的設計,動手前都必須先驗證取得管道回的是內容本體而不是「對方主機上的路徑」。InSpec 走 CLI --reporter json 輸出 stdout / agent 本機檔,天然沒有此問題——但若 T-3.2 content 載入或任何環節出現「由目標主機/工具主機產檔再取回」的設計,先驗這一點再寫。
第一批已 bump 0.2.12(部署 DEV 中)。第二批出貨版 bump 0.2.13,bump pattern 照 evidence-agent commit c46aeeb——四處版號同步:pyproject.toml / config/config.py(AGENT_VERSION 預設值)/ deploy/docker-compose.yml(AGENT_IMAGE + AGENT_VERSION 兩處)/ rebuild.sh(註解範例)。注意依 §5 測試紀律,開發期間不重建 image、不部署,bump commit 做完留著等全案端到端才出貨。
scripts/sql/2026-07-30-fr058-1-zap-seed.sql(見 §4)——檔頭把決策背景寫成註解、ON CONFLICT DO NOTHING、用 nextval 自然拿 id 且註明「code 派工後 id 不影響正確性」、schema_migrations 收尾。test/test_zap_connector.py(485 行,47 項全 mock + 突變測試驗斷言真咬)——InSpec connector 測試照此水準寫 test_inspec_connector.py。| 檔案 | 用法 |
|---|---|
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/scripts/sql/2026-07-30-fr058-1-zap-seed.sql |
最新範本,優先照抄——nextval 拿 id + 「code 派工後 id 不影響正確性」註解、ON CONFLICT (code) DO NOTHING、param_schema 的 condition / secret / default 寫法、setup_guide 的 E'' 多行 markdown 寫法、schema_migrations 收尾 |
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/scripts/sql/2026-07-28-fr057-1-openscap-seed.sql |
FR-057 版範本,SSH 型工具的 config_field_schema(SSH 帳號 / 金鑰欄位)可參考 |
| 檔案 | 用法 |
|---|---|
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/openscap.py(578 行) |
InSpec 最像它——SSH 多目標多檔型:逐台掃、每台一個證據檔、host_failures 逐台失敗回報、SSH 私鑰暫存處理、probe() 分段檢查與錯誤分類。InSpec 在它之上多一個 WinRM transport 分支 |
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/zap.py(480 行,剛出爐) |
第一批的新 connector——cancel_event / timeout 輪詢寫法、summary 解析容錯、log 紀律(憑證絕不進 log)的最新範例 |
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/base.py |
DetectionConnector ABC、ScanResult、ScanCancelledError、cancel_event / host_failures / content_mismatch_hosts 注入點——介面不動 |
~/Projects/Billows/Audit-Manager/evidence-agent/core/task_executor_connectors/__init__.py——f17a311 之後改依 code 註冊(見 §3.1)。照 _build_zap 的形狀加 builder + _CONNECTOR_BUILDERS 一列,不動 _LEGACY_TOOL_ID_TO_CODE。factory 迴歸測試在 test/test_connector_factory.py(90 行),新 code 註冊後補對應 case。
| 檔案 | 用途 |
|---|---|
~/Projects/Billows/Audit-Manager/evidence-agent/Dockerfile |
T-2.2 加入 CINC Auditor(授權紅線見 §2 第 1 條) |
~/Projects/Billows/Audit-Manager/evidence-agent/test/(跑法 PYTHONPATH=. poetry run pytest test/ -q,repo 缺 conftest.py 必帶 PYTHONPATH) |
單元測試落點 |
BE app/remote_agent/service/agent_enrollment_service.py |
派工鏈(只讀參考,第二批預期不動——code 夾帶已上線) |
端到端驗收延後到全案最後一次做(與第一批、第三批合併驗收)。開發期間:
版號 bump 0.2.13 的 commit 照做(§3.5),但不出貨。
| 檢查 | 做法 |
|---|---|
| import / 語法檢查 | PYTHONPATH=. poetry run python -c "from core.task_executor_connectors.inspec import ..." 之類,改完即驗 |
| mock 單元測試 | 全 mock、不碰網路與真實主機;水準對齊第一批 test/test_zap_connector.py(47 項全 mock + 突變測試驗斷言真咬——刻意改壞被測邏輯確認測試會紅,避免寫出永遠綠的假測試) |
| SQL 套 DEV 後 SELECT 驗證 | seed 檔套 DEV 後 SELECT id, code, connection_type, status FROM config.detection_tools ORDER BY id + 查 detection_tool_param_schemas 確認 schema 進去且 is_current 正確 |
DEV → STG → POC 三環境(指令照 CLAUDE.md「DB 環境清單」段;密碼請查 .env 的 DB_SECRET 或部署文件,禁入任何版控檔案):
# DEV
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev \
--single-transaction -v ON_ERROR_STOP=1 -f scripts/sql/<fr058-2 seed 檔>.sql
# STG(同台不同 DB)
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_stg \
--single-transaction -v ON_ERROR_STOP=1 -f <同上>
# POC(另一台)
psql -h 192.168.50.189 -p 25432 -U cmmgr -d guidant_ai_poc \
--single-transaction -v ON_ERROR_STOP=1 -f <同上>SQL 撰寫鐵則:檔頭 -- Date:、每個語句加日期註解、收尾 INSERT public.schema_migrations(本批只 seed 不建表,若意外需建表則必加 GRANT ... TO cm_app + sequence 權限)。
git checkout <branch> / git switch <branch> 一律不執行。BE 永遠在 feature/FR-058 工作;發現 branch 不對停下回報,不自己 fix(「為了在正確 branch commit 而切 branch」也不允許)-am——避免誤 add 其他 arc 留下的 untracked / modified 檔案.env 或部署文件」tail -200 log/app.log | grep -A 30 -i 'Traceback\|ERROR',log 沒線索才回報接手 FR-058 第二批(InSpec/CINC → GCB)的實作工作。
完整讀序入口:
/Users/chouraymond/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-058-2607-detection-tools-expansion/handoff/2026-07-30-fr058-batch2-dispatch.md
先讀它全份(含 §2 硬性決策約束與 §3 第一批新事實),再照它的 §0 讀序開 design.md §4.3-§4.4。
範圍:T-2.1〜T-2.4(CM-972〜975,母卡 CM-971)+ T-3.1〜T-3.3(CM-977〜979,母卡 CM-976),
序列執行,T-2.4 完成時一併結案 CM-953。
硬紅線速記:CINC Auditor 不可換官方 InSpec 商業版(D5);SSH+WinRM 雙 transport 一次到位、
--reporter json 統一解析(D6);GCB 複用 inspec.py 不另寫 connector、content 必須可外部
載入不打包進 image、只做一份 Windows 最小 Demo profile(D7/D8);Demo 規則必讀
HKLM\Software\Policies 正規政策區;新 connector 依 code 註冊、絕不加 _LEGACY_TOOL_ID_TO_CODE。
測試紀律:端到端驗收整批延後到全案最後,開發期間不重建 image、不部署、不跑真實掃描;
只做 import 檢查 + 全 mock 單元測試 + SQL 套 DEV 後 SELECT 驗證;seed 三環境都要套。
BE 在 feature/FR-058 工作,不切 branch、不 push、顯式 git add 禁 -am;每個子任務完成即
commit 並回寫 Notion 卡(修正待驗證 + 白話說明 + commit hash + 執行紀錄);收尾動作等我下令。
📌 寫完自檢:下個 session 只看這一份 + design.md §4.3-§4.4,能不能不回頭問任何人就開工?——本文所有路徑 / 卡號 / commit hash / SQL 指令皆可直接使用;密碼類資訊一律指向
.env。