在 CI 流水線裏配置 SCA 門禁:從閾值設計到分級阻斷
開發團隊普遍面臨一個兩難困境:把 SCA 掃描接入 CI 流水線之後,要麼掃出一堆告警沒人處理,要麼直接阻斷導致流水線天天紅燈、工程師繞路提交。兩種結果都指向同一個失敗——門禁形同虛設,或者門禁成為團隊的對立面。
問題不在於"要不要掃",而在於"怎麼設計門禁策略"。
門禁的本質:風險分級,而非全量阻斷
很多團隊初次接入 SCA 時犯的第一個錯誤,是把"發現漏洞"直接等同於"阻斷構建"。這種做法在初期會製造大量噪音:歷史依賴積壓的已知漏洞、開發環境專用組件中的低危問題、以及工具本身的誤報,都會觸發阻斷,最終讓工程師養成忽略告警的習慣,或者繞過流水線。
更合理的設計是三檔分級:
- 阻斷(Block):高危及以上漏洞(CVSS ≥ 9.0)、存在已知公開利用鏈的嚴重漏洞、許可證衝突會影響產品發佈合規性的組件。這一檔必須在合併前解決,不允許例外。
- 告警(Warn):中危漏洞、EOL 組件(如仍在使用 Log4j 1.x 這類 早在 2015 年就已停止維護 的版本)、許可證存在潛在衝突但尚未確認影響範圍的情況。告警進入工單系統,納入下一個迭代處理,不阻斷當前構建。
- 放行(Pass):低危漏洞、僅出現在測試依賴中的問題、已有緩解措施並經安全團隊確認的已知風險。記錄在 SBOM 中,定期複查。
這一分級邏輯與 CleanSource SCA 的內置策略引擎基本對齊——它支持按 CVSS 評分、漏洞可達性、許可證類型、組件所在環境(生產/測試/構建)等多個維度組合配置門禁規則,避免一刀切帶來的誤傷。
閾值設計:讓數字有意義
"CVSS 評分多少才阻斷"是最常被問到的問題,但真正決定閾值的不是某個通用標準,而是你的業務場景。
以下幾個維度值得在閾值設計階段認真回答:
- 組件是否直接暴露在攻擊面上? 一個 CVSS 7.5 的漏洞,如果存在於僅用於內部批處理的後台服務,和存在於對外提供 API 的核心服務,處置優先級應該完全不同。
- 是否存在公開 PoC 或已知在野利用? Log4Shell(CVE-2021-44228)在 2021 年 12 月披露時 CVSS 僅為 10 分,但其在野利用速度之快讓打分本身的參考意義大打折扣——有時候漏洞的"熱度"比分數更值得關注。
- 修復版本是否可用? 如果上游沒有補丁,阻斷只會製造壓力,不會產生解法。這種情況下告警加緩解措施記錄更務實。
- 許可證風險邊界在哪裏? GPL 系許可證在商業閉源產品中的引入,和在內部工具中的引入,法律影響截然不同。許可證衝突檢測 需要結合產品形態單獨配置規則,不應與漏洞門禁混用同一套閾值。
一個可操作的起點:新增組件(增量部分)使用嚴格閾值,存量組件使用寬鬆閾值,併為存量設置消減計劃。這樣既不放任歷史債務無限擴張,又不因歷史問題每天阻斷正常開發。
增量掃描:速度是門禁能否堅持下去的關鍵
全量掃描對於大型項目來説耗時可能以分鐘甚至十幾分鍾計。如果每次 MR 都觸發全量掃描,流水線的等待成本會很快讓工程師產生牴觸。
增量掃描的核心思路是:只掃本次變更引入或升級的組件,以及與之存在依賴關係的直接上下游。對於未變更的組件,沿用上一次掃描緩存的結果,只在定時任務中做全量複查(例如每天凌晨跑一次完整掃描,更新漏洞情報匹配結果)。
CleanSource SCA 的增量掃描模式可以將單次 MR 觸發的掃描時間控制在 60 秒以內,這對於希望在 Pre-Merge 階段配置門禁的團隊來説是一個可接受的延遲區間。配合其覆蓋 600+ 包管理生態、沉澱 3.2 億組件指紋的數據基礎,增量掃描的覆蓋度不會因為"只掃變更部分"而出現漏洞盲區。
值得注意的是,片段級檢測(即對源代碼片段的成分溯源)與 manifest 級檢測的結合使用,能夠發現那些"隱藏在代碼裏而不是聲明在依賴文件裏"的組件引入。關於兩者的覆蓋邊界,可以參考 片段級 SCA 與 manifest 級 SCA 的對比分析。
誤報處理:沒有機制的門禁會自我崩潰
誤報是所有安全工具的固有問題。如果團隊沒有建立系統性的誤報處理流程,最終的結果要麼是告警被集體忽略,要麼是有人直接修改配置把規則關掉。CleanSource SCA 的誤報率控制在 15% 以內,但即便如此,在規模較大的項目中,誤報的絕對數量也足以製造認知負擔。
一套可運轉的誤報處理流程應當包含以下環節:
- 提報入口:工程師在 CI 界面直接標記"疑似誤報",附上判斷依據(例如漏洞影響的代碼路徑在當前項目中不可達)。
- 審核責任人:由安全團隊或指定的 Security Champion 在固定 SLA 內(例如 2 個工作日)給出確認或否定。
- 豁免記錄:確認誤報後,生成帶有有效期的豁免條目,寫入項目級配置文件並納入版本控制。豁免條目到期後自動重新觸發審核,不允許永久豁免。
- 反饋上游:對於工具側的系統性誤報,建立向工具提供商的反饋通道,追蹤修復進度。
這個流程的關鍵在於"有期限的豁免"而非"永久例外"——它讓門禁保持彈性,同時避免豁免列表無限膨脹變成另一種形式的規則失效。
接入 Jenkins 與 GitLab CI 的實操要點
Jenkins 接入
Jenkins 通常通過 Pipeline 腳本(Jenkinsfile)集成 SCA 掃描。推薦的位置是在單元測試之後、製品構建之前插入掃描步驟。CleanSource SCA 提供 CLI 工具和 REST API 兩種調用方式,可以通過 sh 步驟直接調用,掃描結果以 JSON 或 SARIF 格式輸出,便於後續解析。
門禁邏輯建議在 Jenkinsfile 中顯式編寫,而不是依賴工具默認行為。例如:讀取掃描結果中的嚴重漏洞數量,若大於零則調用 error() 終止流水線;中危漏洞數量寫入環境變量,通過 unstable() 標記構建為不穩定而非直接失敗。這樣的顯式控制讓策略調整不依賴工具升級,版本可追溯。
GitLab CI 接入
GitLab CI 的 .gitlab-ci.yml 支持將 SCA 掃描配置為獨立 stage,並通過 allow_failure: true/false 控制是否阻斷後續 stage。推薦配置方式:
- 在
scanstage 中運行 CleanSource SCA,輸出結果文件。 - 在
gatestage 中運行策略評估腳本,根據分級規則決定是否exit 1。 - 將掃描報告通過
artifacts保存,供 MR 界面展示和後續審計使用。
GitLab 的 Merge Request Approval Rules 可以配置為:當 gate stage 失敗時,必須由安全團隊成員手動審批才能合併。這比直接阻斷更靈活,適合需要快速迭代的業務線。
對於同時需要 SAST 能力的團隊,CleanCode Security Agent 可以與 CleanSource SCA 在同一流水線中並行運行,共用掃描觸發器,避免重複配置帶來的維護負擔。如果涉及二進制交付或固件場景,CleanBinary 可以在製品發佈階段補充成分分析覆蓋。
---
配置 SCA 門禁不是一次性的工程任務,而是一個需要持續校準的過程。漏洞情報在更新,組件生態在演變,業務風險偏好在變化——門禁策略也應當隨之迭代。從分級阻斷開始,把增量掃描的速度做到可接受,把誤報處理的流程跑通,門禁才能真正成為開發流程的一部分,而不是工程師需要繞過的障礙。
想了解如何在不同行業場景下設計差異化的 SCA 策略,可以參考 金融行業開源治理實踐 和 醫療器械 SBOM 合規 中的具體案例拆解。
