原始碼弱點掃描與 SBOM 報表(給非技術顧問看的)

白話需求草稿,Phase 0。起稿 2026-10-10,起因是同日排查 SBOM 工具相容性時決策者提出。 下一步:開新 session 照 big-feature-workflow 討論,登記 FR 號(2026-10-10 時最大號 FR-133)。

§1

原由

產品現況:我們出貨時已經會產 SBOM(軟體物料清單),走 scripts/build/sbom.sh: Syft 掃 poetry.lock/package-lock.json 與五顆 image,輸出 CycloneDX 1.7 JSON; 弱點由 pip-audit(Python 套件)與 Trivy+Grype 雙掃(image)判定,vuln_gate.py 對照 白名單,白名單外有 Critical 就不出包。這整套只服務我們自己的出貨流程,客戶看不到、 也用不上。

觸發事件:2026-10-10 拿國家資通安全研究院的 ex-sbom(圖形化 SBOM 檢視工具)試讀我們的 SBOM,被擋在「不認 CycloneDX 1.7」(它內建的解析套件停在 1.6)。排查過程順帶發現: 市面上解析 SBOM、呈現弱點的工具,全部是給工程師看的——CVE 編號、CVSS 向量、purl、 依賴拓撲圖。沒有一個是讓非技術人員能看懂「這個專案現在有多危險」的。

真正的痛點(決策者原話整理):顧問在輔導客戶時,理論上專案弱點狀況該由客戶的工程師 盤點並回報,但實務上工程師最愛閃躲——「那個不嚴重」「我們環境打不到」「下個版本會修」, 顧問沒有技術背景,無從判斷是真是假,只能被敷衍帶過。這個功能的用意,就是讓不會工程技術 的顧問,自己就能知道專案/產品的弱點在哪、多嚴重、修了沒,拿著有工具原始輸出背書的報表 去跟工程師對話,工程師閃不掉。

為什麼是我們做:Guidant AI 的使用者就是顧問與稽核人員,而且我們手上已經有整條 「產 SBOM → 雙工具掃弱點 → 判定」的管線(FR-127/FR-128 建的),只差把它從出貨腳本搬進 產品、加上給人看的那一層。「給非技術人看、可交付、品牌化的弱點報表」這塊市面上是空的, 可以是產品亮點。

§2

我想解決什麼問題

顧問拿到客戶的原始碼或 git repo 後,不需要工程師協助,就能:

  1. 產出這個專案的 SBOM(支援多種格式、多種工具)
  2. 用多種工具解析,看各工具各自報了什麼弱點
  3. 在系統內瀏覽結果——用白話呈現,不是 CVE 清單
  4. 匯出各類報表(PDF/HTML/DOCX),可以直接交給客戶或拿去跟工程師對質
§3

客戶情境

  • 顧問 A 輔導某客戶做 ISO 27001,客戶有一套自己開發的內部系統。顧問想知道這套系統用了哪些 第三方套件、有沒有已知弱點,問工程師得到「都有在更新」。顧問把 repo 位置丟進 Guidant AI, 十分鐘後拿到報表:568 個 npm 套件、12 個高風險弱點、其中 3 個有公開攻擊程式、最老的一個 2023 年就該修。顧問拿這份報表開會,工程師無法再說「都有在更新」。
  • 顧問 B 要出客戶的年度資安評估報告,其中一節是「第三方元件風險」。以前這節要請工程師提供 資料、再自己整理成客戶看得懂的文字,來回一兩週。現在系統直接產這一節的 DOCX,附上 SBOM 當附件。
  • 顧問 C 三個月後回訪同一客戶,重掃一次,報表直接顯示「上次 12 個高風險,這次剩 4 個,新增 2 個」——修了沒,一眼看到。
§4

預期效果

  • 輸入:上傳原始碼壓縮檔,或填 git repo 位置(含私有 repo 的憑證)
  • 輸出 SBOM:CycloneDX 與 SPDX 兩種格式都要(應用安全圈偏 CycloneDX,法規與授權合規偏 SPDX, 美國政府採購兩者皆可),版本可選(有些下游工具只認舊版,如 ex-sbom 只認 1.6)
  • 解析:包現成工具(Syft/cdxgen 產生;Trivy/Grype/osv-scanner 查弱點),絕對不自己造輪子, 成本放在把各工具輸出正規化成我們自己的資料模型
  • 瀏覽:同一份 SBOM 跨工具對照——Trivy 說有、Grype 說沒有、各自的分數不同,都攤開讓顧問看到; 再加授權風險、SBOM 品質分數(NTIA 最低要素齊不齊)
  • 報表:給非技術人看的版本(這專案有多危險、哪幾個最急、修了沒),每個數字都能追到工具原始 輸出(顧問說「Trivy 10 月 8 日就報了這個 Critical」,工程師不能說沒有)。PDF 走 WeasyPrint、 DOCX 走 python-docx,兩者產品內都有先例
  • 歷次比對:同一專案多次掃描的差異(修了幾個、新增幾個)
§5

已知限制 / 風險(白話想法,待精化)

  • 從原始碼產 SBOM 的準確度取決於有沒有 lock 檔。只有 package.json 沒有 lock 時,工具只能 猜版本範圍;要準就得實際跑建置工具解析(cdxgen 走這條路),代價是要在我們環境執行客戶的 建置腳本,這是安全問題,要在設計時決定做不做、做到哪
  • 跑客戶的 repo 等於執行不受信任的輸入。clone 與掃描都要隔離。產品已有 guidant-sandbox (FR-122,純拆檔、無金鑰、不出網、唯讀 rootfs、cap_drop ALL),但掃描沙箱有兩個不同處: 要能出網 clone git(白名單 git host)、要裝掃描工具與弱點資料庫。所以不是直接塞進現有容器, 而是把「沙箱」從「一個容器」升級成「一種容器樣板」——共用加固形狀,各自不同 image 與網路 政策。決策者已明示未來會越來越多類似功能,這個抽象該做。守衛測試 test/security/code/test_security_shape_container_hardening.py 把 sandbox 列在自家四容器, 形狀改動會被擋,要有意識地改
  • 弱點資料庫要能離線。落地版客戶常是封閉網路,Trivy/Grype 的資料庫(Grype 約 3GB)要能 隨安裝包帶進去並定期更新,不然裝好弱點永遠是零。這是出貨包與升級流程的一環,不只是功能本身。 ex-sbom 必須連網查 OSV,正是落地版不能直接用它的原因
  • 多工具結果不一致是常態。osv-scanner 對 Debian/Ubuntu 判不準(這是我們出貨管線不用它的 原因),各工具 CVSS 來源也不同。對顧問來說「兩個工具說法不同」本身要有白話解釋,不能丟兩張表
  • 掃描時間與資源。大型 repo 加弱點比對可能要跑好幾分鐘,走背景 job(RUN_MODE=worker 已有 機制);沙箱資源上限要訂
  • 私有 repo 憑證:顧問填的 git token 是客戶的祕密,儲存、使用、銷毀都要照 .claude/rules/security/ 祕密與上傳解析兩支的規則
§6

參考資料

  • 現有出貨管線:scripts/build/sbom.sh、scripts/build/vuln_gate.py、scripts/build/vuln-allowlist.txt、 scripts/build/README.md「sbom.sh」列與 CI 段
  • 現有沙箱:docs/features/FR-122-2609-ai-gateway-and-sandbox/design.md、 docker/production/docker-compose.yml 的 guidant-sandbox 服務段與 guidant-sandbox network 段
  • 既有報表產出先例:摘要報告 PDF(WeasyPrint)、docs/system-design/ DOCX(python-docx,見 docs/claude/docs-conventions.md)
  • 業界對照:
    • 產生:Syft、Trivy、cdxgen(OWASP/CycloneDX 官方,支援語言最廣)、osv-scalibr(Google)
    • 平台:OWASP Dependency-Track(開源平台事實標準,是我們最直接的對照組——但它是給工程師的)
    • 圖形化:ex-sbom(https://github.com/nics-tw/ex-sbom)——只認 CycloneDX 1.6、底層 osv-scanner、 須連網
    • 品質:sbomqs(NTIA 最低要素評分);格式工具:CycloneDX CLI(驗證、轉版本、比對)
    • 商用:Snyk、Black Duck、FOSSA、Mend——客戶可能已在用,我們的報表會被拿來跟它們比
  • 2026-10-10 實測紀錄:188 的 syft 1.54.0 可用 -o cyclonedx-json@1.6 降版輸出,元件數與 dependencies 與 1.7 相同;1.7 相對 1.6 新增 CBOM/citations/專利欄位,我們都沒用到
§7

UI 想法(粗略)

  • 入口:新模組「原始碼掃描」(名稱待定),列出掃描過的專案與歷次掃描
  • 新增掃描:上傳壓縮檔 或 填 repo URL+憑證 → 選要跑哪些工具 → 送出變背景 job
  • 結果頁三層:
    1. 顧問層(預設):風險總評一句話+紅黃綠數字+「最急的五個」+「跟上次比」
    2. 對照層:每個弱點一列,欄位是各工具的判定(有/無/分數),點開看白話說明
    3. 原始層:各工具原始輸出可下載,SBOM 可下載(選格式與版本)
  • 匯出:選報表樣式(顧問摘要/完整技術/客戶交付)與格式(PDF/HTML/DOCX)
§8

待討論的問題(給 Phase 1 brainstorm 釐清)

  1. 沙箱抽象怎麼切:共用樣板的邊界在哪、network policy 怎麼參數化、守衛測試怎麼跟著改
  2. 要不要支援「實際跑建置工具解析依賴」(準但要執行客戶程式碼)?第一版建議先不做,只吃 lock 檔
  3. 第一版支援哪些語言生態系?建議從我們自己能驗的開始(Python/npm/Java)
  4. 弱點資料庫的離線更新機制:隨安裝包帶?獨立更新包?跟 agent 升級走同一條?
  5. 第一版工具組合:Syft+Trivy+Grype(我們已熟)就夠?cdxgen/osv-scanner 第一版要不要?
  6. 顧問層的「風險總評」怎麼算?不能只拿 CVSS 最高值,要考慮數量、有無公開攻擊程式(EPSS/KEV)、 修正版本是否存在
  7. 報表「每個數字追到原始輸出」的呈現形式:附錄?超連結?
  8. 這功能算哪條能力點、哪些角色能用、掃描結果屬於哪個租戶
  9. 要不要跟現有專案(稽核專案)綁定,還是獨立模組?
§9

不在本次範圍

  • 動態掃描(DAST)、滲透測試
  • 修弱點(只報告、不改客戶程式碼)
  • 替代我們自己的出貨管線(sbom.sh 維持不動;產品功能若成熟,日後可反過來讓出貨管線吃產品的服務,但不是這次)
  • 把 ex-sbom 或 Dependency-Track 整包嵌進產品