上個月,Seal 軟體供應鍊防火牆 v0.2(以下簡稱“Seal”)正式釋出,這一版本實作了可擴充架構,使用者可以根據自身需求插件式內建原生或第三方解決方案,靈活擴充掃描能力。
在前一個版本中,Seal 內建了 SCA、SAST 和配置檢查等功能,在這一架構中最大的優勢是調試友善、調用鍊路短,但同時也伴随着子產品耦合、依賴樹深以及擴充困難等問題。是以,在新版本中使用了新的 ⌈插件化架構⌋ 來重構了 SCA、SAST和配置檢查的內建,并以此解決上面談及的擴充性問題。
之前的示範中,我們展示了如何使用 v0.2.0 的插件管理:把IaC 配置檢查 ⌈插件⌋,⌈無縫⌋地內建到 Seal 裡。本文将介紹插件化架構的底層原理以及示範如何将代碼規範工具內建到 Seal軟體供應鍊防火牆中。
插件化架構的工作原理
通常,實作一個架構的插件化,我們需要考慮以下問題:
- 降低插件化的成本。
- 規範插件調用的輸入輸出。
- 配置(限制)插件調用的權限。
- (可選)管理插件調用的狀态資料。
Seal 通過讓插件的改動最小化來降低插件化的成本,換言之,Seal 可以讓插件保留其原有的配置方式,使用者僅需适配插件調用的輸入輸出即可。插件的配置項可以通過 Seal 的政策面闆暴露成政策,最終作用到 Seal 的各個攔截點上。
# policies.yaml
- code: # <string>, 政策代碼,唯一辨別
category: # <string>, 政策分類,所在的一級組
type: # <string>, 政策類型,所在的二級組
name: # <string>, 政策名稱(或原有配置項的名稱)
description: # <string>, 政策描述(或原有配置項的描述)
enabled: # <bool>, 預設啟用
builtIn: # <bool>, 預設内置(内置,是相對于使用插件的使用者而言)
bindings: # 作用的攔截點
isAllResource: # <bool>, 作用于源代碼倉庫
isAllProxy: # <bool>, 作用于代理
constraint: {} # 限制,結構化的配置
expression: "" # 表達式或原配置項
action: # <string>, 違反該政策後,應該做出的動作
severity: # <string>, 違反該政策後,應該聲明的嚴重程度
- code: ...
category: ...
...
然後, Seal 在某個攔截點上運作檢查時,會拉取相應的已啟用的政策,生成配置檔案和攔截點上的狀态資料(例如,對于源碼倉庫的檢測,攔截點為源碼倉庫,狀态資料為檢測時刻的源代碼)作為插件調用的輸入。當插件檢查完畢後,将結果以 SARIF的格式輸出到指定路徑。
最後, Seal 将所有插件的 SARIF 輸出彙總,并根據政策定義的行為(action)決定實施攔截、通過還是告警。
另外,對于信任(
trusted
)的插件,Seal 會在插件調用時注入 API Token (
SEAL_API_TOKEN
),進而允許插件獲得 Seal 的能力:風險評估、漏洞資料、合規資訊等。
內建代碼規範工具
假設,有個
style-checker
的元件,它可以檢查源代碼的書寫規範,支援豐富的風格檢查配置。其中,有一條配置項:K&R 風格檢查。當源代碼中有風格違反配置規則時,
style-checker
會輸出失敗資訊。
style-checker \
--path="/path/to/your/code" \
--kr-style="true" \
--msvc-style="false" \
--... \
--report="/path/to/record/illegal/result"
首先,需要給 style-checker 做一個包裹器(
wrapper-style-checker
),這個包裹器是用來接收 Seal 的輸入輸出。
wrapper-style-checker
可以用任何語言編寫,在運作時,從環境變量中擷取以下内容:
SOURCE_DIR="/path/to/your/code" \
PLUGIN_POLICY_FILENAME="/path/to/receive/configuration" \
PLUGIN_OUTPUT_FILENAME="/path/to/output/sarif_report" \
SEAL_API_TOKEN="" \
SEAL_URL="" \
wrapper-style-checker
然後,規整
style-checker
的配置項,按照合适的粒度建構出相應的政策。這裡,以每個配置項作為一條政策。Seal 會在安裝插件的階段閱讀這個政策檔案(
policies.yaml
),把其中的每一項都呈現到 Seal 的政策面闆。
# policies.yaml
- code: STYLE-CHECKER-POL-1
category: sast
type: style
name: kr-style
description: 檢查是否嚴格使用K&R風格編碼。
enabled: true
builtIn: true
bindings:
isAllResource: true
expression: |
KRStyle: true
MSVCStyle: false
接着,實作 wrapper-style-checker 對政策檔案的了解(轉換),把
expression
的資訊轉化成對 style-checker 的調用,并把執行後的結果按 SARIF 格式輸出。
# pseudo code
var policies = read(${PLUGIN_POLICY_FILENAME})
var config = parseInput(policies)
var result = call("style-checker") on (${SOURCE_DIR}) with (config)
var sarif = parseOutput(result)
write(${PLUGIN_OUTPUT_FILENAME}) with (sarif)
最後,用元資訊檔案(metadata.yaml)描述 wrapper-style-checker 插件的資訊,包括UI展示,多語言等。
category: sast
format: yaml
resourceKinds: ["repository"]
policies:
- type: style
conditions: []
locales:
en:
"policy.style": "Style Checker"
zh:
"policy.style": "風格檢查"
插件安裝
完成以上步驟後,可以把 wrapper-style-checker(二進制可執行檔案) 、政策檔案(
policies.yaml
)和元資訊檔案(
metadata.yaml
)打包成一個 tar.gz 包,并通過 Seal 的 ⌈插件管理⌋ 頁面進行下載下傳安裝,實作開箱即用。