SBOM
SBOM 範例
了解 SBOM 最快的方法,就是讀一份。以下以 CycloneDX 與 SPDX 兩種格式呈現同一個小型應用程式,並說明每個欄位的意義、品質不佳的 SBOM 長什麼樣子,以及如何檢查您自己的 SBOM。
更新日期
這些範例中的應用程式
兩個檔案描述的都是 example-api 2.4.0,這是一個示意用的 Node.js 服務,只有一個直接相依套件 express。Express 又相依於 accepts,因此範例中也包含一個遞移相依套件。真實 Express 應用程式的 SBOM 會列出更多元件,但結構相同。
CycloneDX SBOM 範例
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"metadata": {
"timestamp": "2026-10-30T09:00:00Z",
"lifecycles": [{ "phase": "build" }],
"tools": {
"components": [
{ "type": "application", "name": "example-sbom-tool", "version": "1.0.0" }
]
},
"component": {
"type": "application",
"bom-ref": "example-api",
"name": "example-api",
"version": "2.4.0"
}
},
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/[email protected]",
"name": "express",
"version": "4.21.2",
"purl": "pkg:npm/[email protected]",
"licenses": [{ "license": { "id": "MIT" } }]
},
{
"type": "library",
"bom-ref": "pkg:npm/[email protected]",
"name": "accepts",
"version": "1.3.8",
"purl": "pkg:npm/[email protected]",
"licenses": [{ "license": { "id": "MIT" } }]
}
],
"dependencies": [
{ "ref": "example-api", "dependsOn": ["pkg:npm/[email protected]"] },
{ "ref": "pkg:npm/[email protected]", "dependsOn": ["pkg:npm/[email protected]"] }
]
}
| 欄位 | 它告訴您什麼 |
|---|---|
specVersion |
檔案使用的格式版本,讓工具能夠解析。 |
serialNumber、version |
這是哪一份 SBOM,以及它的第幾個修訂版。 |
metadata.lifecycles |
SBOM 產生的時機。此處為建置期間。 |
metadata.tools |
由哪個工具產生。兩個工具對同一個 commit 的回報可能不同。 |
metadata.component |
SBOM 所描述的產品。 |
purl |
套件 URL,讓工具能將元件與資安公告比對的識別碼。 |
licenses |
元件宣告的授權。 |
dependencies |
誰帶入了誰。正是這個欄位讓 accepts 以遞移相依套件的身分顯現出來。 |
SPDX SBOM 範例
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "example-api-2.4.0",
"documentNamespace": "https://example.com/spdx/example-api-2.4.0",
"creationInfo": {
"created": "2026-10-30T09:00:00Z",
"creators": ["Tool: example-sbom-tool-1.0.0"]
},
"packages": [
{
"name": "example-api",
"SPDXID": "SPDXRef-Package-example-api",
"versionInfo": "2.4.0",
"downloadLocation": "NOASSERTION"
},
{
"name": "express",
"SPDXID": "SPDXRef-Package-express",
"versionInfo": "4.21.2",
"downloadLocation": "NOASSERTION",
"licenseDeclared": "MIT",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:npm/[email protected]"
}
]
},
{
"name": "accepts",
"SPDXID": "SPDXRef-Package-accepts",
"versionInfo": "1.3.8",
"downloadLocation": "NOASSERTION",
"licenseDeclared": "MIT",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
"referenceType": "purl",
"referenceLocator": "pkg:npm/[email protected]"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relationshipType": "DESCRIBES",
"relatedSpdxElement": "SPDXRef-Package-example-api"
},
{
"spdxElementId": "SPDXRef-Package-example-api",
"relationshipType": "DEPENDS_ON",
"relatedSpdxElement": "SPDXRef-Package-express"
},
{
"spdxElementId": "SPDXRef-Package-express",
"relationshipType": "DEPENDS_ON",
"relatedSpdxElement": "SPDXRef-Package-accepts"
}
]
}
資訊相同,只是編排方式不同。SPDX 保有一份 packages 清單,並在 relationships 中說明項目之間的每一個關聯。licenseDeclared 是套件對自身的描述,而當工具不知道時,downloadLocation 可能為 NOASSERTION。兩種格式除了編排之外還有哪些差異,請參閱 CycloneDX 與 SPDX 比較。
品質不佳的 SBOM 長什麼樣子
檔案可能格式正確,卻幾乎毫無用處。請留意以下幾點:
- 沒有相依關係。扁平的清單只能告訴您某個套件存在,卻無法告訴您是什麼帶入了它,而這正是修正遞移相依套件所需要的資訊。
- 沒有套件 URL。少了 purl 這類識別碼,將元件與資安公告比對就只能靠名稱猜測。
-
缺少授權。許多欄位留為
NOASSERTION,代表這份 SBOM 無法回答授權相關問題。 - 元件數量少得可疑。大型應用程式只有寥寥幾個元件,通常代表只列了直接相依套件,或只列了某個 lockfile 宣告的內容。
- 沒有說明何時與如何產生。沒有工具與產生脈絡,您就無法判斷這份 SBOM 可信賴的涵蓋範圍。
- 對缺漏隻字未提。好的 SBOM 會說明它看不到什麼。多數檔案就這樣結束,讀者便以為內容是完整的。
如何檢查您自己的 SBOM
- 驗證格式。以對應其格式與版本的結構描述驗證工具檢查,因為無法解析檔案的工具也就無法使用它。
- 檢查欄位。與 2026 Minimum Elements 或客戶要求的清單比對。
- 搜尋您知道的東西。挑選一個遞移相依套件、一個來自基礎映像檔的套件和一個建置工具,看看其中哪些有出現。
- 比較兩個來源。以不同方法再產生一份 SBOM,觀察兩者的差異。一份檔案中多出的每個元件,都是對另一份檔案的疑問。
每項檢查與 NTIA、CISA 及 BSI 欄位清單的對應,請參閱 SBOM 品質檢查清單。
來自 CRACI 的建置時 SBOM
CRACI 匯出相同的格式。不同的是內容的來源:它記錄每個 GitHub Actions 作業取用了什麼,因此 SBOM 中的每個元件都確實被帶入了建置,而從 CI 快取還原的套件也會如實標示。工作流程執行的 GitHub Actions 也會列為元件,並鎖定在所使用的 commit。每個作業的 SBOM 也帶有完整性狀態,因此缺漏會被明確說明,而不是留給您自己去發現。請參閱建置時 SBOM 產生,或SBOM 工具比較。
SBOM 範例:常見問題
SBOM 長什麼樣子?
通常是 JSON 檔案,有時是 XML。它一開始是 SBOM 本身的資料,例如工具與時間戳記,接著列出每個元件的名稱、版本、識別碼與授權,最後描述元件之間的相依關係。
SBOM 是 JSON 檔案嗎?
通常是,因為 JSON 是 CycloneDX 與 SPDX 最廣泛使用的編碼方式。兩種格式也都有其他編碼方式,SPDX 另外還有 tag-value 文字格式。
SBOM 中的 purl 是什麼?
purl(package URL,套件 URL)是套件的標準識別碼,例如 pkg:npm/[email protected]。它以一個字串標示生態系、套件與版本,讓工具能可靠地將元件與漏洞資料比對。
一份 SBOM 應該有多少個元件?
沒有標準答案,但應該包含遞移相依套件,而遞移相依套件的數量通常遠多於直接相依套件。大型應用程式的元件少得出奇,通常代表工具只看到了其中一部分。
可以查看開源專案的 SBOM 嗎?
有時可以。有些專案會隨版本發布一併公開 SBOM,而 GitHub 也能從儲存庫的相依關係圖匯出一份。這份匯出反映的是儲存庫宣告的內容,而不是某次特定建置實際使用的內容。