建置證明
建置證明描述了映像檔是如何建置的,以及它包含了什麼。這些證明由 BuildKit 在建置時建立,並作為中繼資料附加到最終的映像檔中。
證明的目的是讓使用者能夠檢查映像檔,了解其來源、建立者、建立方式以及內容。這使您能夠就映像檔如何影響應用程式的供應鏈安全做出明智的決定。它還能讓您使用原則引擎,根據您定義的規則來驗證映像檔。
提供兩種建置證明類型
- 軟體物料清單 (SBOM):映像檔所包含,或用於建置映像檔的軟體成品清單。
- 來源證明 (Provenance):映像檔是如何建置的。
證明的目的
開源和第三方套件的使用比以往任何時候都更加普遍。開發人員分享和重複使用程式碼是因為它有助於提高生產力,使團隊能更快地創造出更好的產品。
匯入並使用未經審核的外部程式碼會帶來嚴重的安全風險。即使您確實審查了所使用的軟體,新的零時差漏洞仍頻繁被發現,這要求開發團隊採取行動來修復它們。
建置證明讓使用者更容易查看映像檔的內容及其來源。利用證明來分析並決定是否使用某個映像檔,或查看您現有的映像檔是否暴露於漏洞風險中。
建立證明
當您使用 docker buildx build 建置映像檔時,可以使用 --provenance 和 --sbom 選項將證明記錄新增到生成的映像檔中。您可以選擇新增 SBOM 或來源證明類型,或者兩者皆新增。
$ docker buildx build --sbom=true --provenance=true .
注意預設的映像檔儲存庫不支援證明。如果您使用的是預設儲存庫,並透過預設的
docker驅動程式,或使用帶有--load旗標的其他驅動程式來建置映像檔,證明將會遺失。為確保證明被妥善保存,您可以
- 使用
docker-container驅動程式並配合--push旗標,將映像檔直接推送到登錄檔。- 啟用 containerd 映像檔儲存庫。
注意來源證明預設為啟用,並使用
mode=min選項。您可以使用--provenance=false旗標,或設定BUILDX_NO_DEFAULT_ATTESTATIONS環境變數來停用來源證明。使用
--provenance=true旗標會預設附加mode=min的來源證明。詳細資訊請參閱 來源證明 (Provenance attestation)。
BuildKit 會在建置映像檔時產生證明。證明記錄會以 in-toto JSON 格式封裝,並附加到最終映像檔清單中的映像檔索引裡。
儲存
BuildKit 產生的證明符合 in-toto 格式,這是由 Linux Foundation 支援的標準 in-toto 框架所定義的。
證明以清單形式附加到映像檔索引中。證明記錄的資料儲存為 JSON blob。
由於證明作為清單附加到映像檔中,這意味著您可以檢查登錄檔中任何映像檔的證明,而無需下載整個映像檔。
所有 BuildKit 匯出程式皆支援證明。local 和 tar 匯出程式無法將證明儲存到映像檔清單中,因為它們輸出的是檔案目錄或 tarball,而非映像檔。相反地,這些匯出程式會將證明寫入匯出根目錄中的一個或多個 JSON 檔案。
範例
以下範例顯示了 SBOM 證明的簡化 in-toto JSON 表示法。
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://spdx.dev/Document",
"subject": [
{
"name": "pkg:docker/<registry>/<image>@<tag/digest>?platform=<platform>",
"digest": {
"sha256": "e8275b2b76280af67e26f068e5d585eb905f8dfd2f1918b3229db98133cb4862"
}
}
],
"predicate": {
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-15T11:47:54.546747383Z",
"creators": ["Organization: Anchore, Inc", "Tool: syft-v0.60.3"],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-da0f600b-7f0a-4de0-8432-f83703e6bc4f",
"name": "/run/src/core",
// list of files that the image contains, e.g.:
"files": [
{
"SPDXID": "SPDXRef-1ac501c94e2f9f81",
"comment": "layerID: sha256:9b18e9b68314027565b90ff6189d65942c0f7986da80df008b8431276885218e",
"fileName": "/bin/busybox",
"licenseConcluded": "NOASSERTION"
}
],
// list of packages that were identified for this image:
"packages": [
{
"name": "busybox",
"originator": "Person: Sören Tempel <soeren+alpine@soeren-tempel.net>",
"sourceInfo": "acquired package info from APK DB: lib/apk/db/installed",
"versionInfo": "1.35.0-r17",
"SPDXID": "SPDXRef-980737451f148c56",
"description": "Size optimized toolbox of many common UNIX utilities",
"downloadLocation": "https://busybox.net/",
"licenseConcluded": "GPL-2.0-only",
"licenseDeclared": "GPL-2.0-only"
// ...
}
],
// files-packages relationship
"relationships": [
{
"relatedSpdxElement": "SPDXRef-1ac501c94e2f9f81",
"relationshipType": "CONTAINS",
"spdxElementId": "SPDXRef-980737451f148c56"
},
...
],
"spdxVersion": "SPDX-2.2"
}
}若要深入了解證明儲存方式的詳細資訊,請參閱 映像檔證明儲存 (BuildKit)。
證明清單格式
證明儲存為清單,由映像檔的索引參照。每個證明清單 (attestation manifest) 都參照單一的映像檔清單 (image manifest)(映像檔的一種平台變體)。證明清單包含單一層,即證明的「值」。
以下範例顯示了證明清單的結構
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 167,
"digest": "sha256:916d7437a36dd0e258e64d9c5a373ca5c9618eeb1555e79bd82066e593f9afae"
},
"layers": [
{
"mediaType": "application/vnd.in-toto+json",
"size": 1833349,
"digest": "sha256:3138024b98ed5aa8e3008285a458cd25a987202f2500ce1a9d07d8e1420f5491",
"annotations": {
"in-toto.io/predicate-type": "https://spdx.dev/Document"
}
}
]
}作為 OCI 成品的證明
您可以透過 image 和 registry 匯出程式的 oci-artifact 選項來設定證明清單的格式。若設為 true,證明清單的結構會變更如下:
- 證明清單中會新增一個
artifactType欄位,值為application/vnd.docker.attestation.manifest.v1+json。 config欄位會變成一個空的描述符 (empty descriptor),而不是「虛擬」配置。- 同時新增一個
subject欄位,指向該證明所參照的映像檔清單。
以下範例顯示了使用 OCI 成品格式的證明
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"artifactType": "application/vnd.docker.attestation.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.empty.v1+json",
"size": 2,
"digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
"data": "e30="
},
"layers": [
{
"mediaType": "application/vnd.in-toto+json",
"size": 2208,
"digest": "sha256:6d2f2c714a6bee3cf9e4d3cb9a966b629efea2dd8556ed81f19bd597b3325286",
"annotations": {
"in-toto.io/predicate-type": "https://slsa.dev/provenance/v0.2"
}
}
],
"subject": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 1054,
"digest": "sha256:bc2046336420a2852ecf915786c20f73c4c1b50d7803aae1fd30c971a7d1cead",
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
}接下來
進一步了解可用的證明類型及其使用方式