2026 年每日通報的 CVE 數量比前一年多 131%。

SBOM

Docker SBOM:如何產生,以及會遺漏什麼

您只需一道指令就能取得 Docker 映像檔的 SBOM:在建置時使用 BuildKit,或在事後使用 Docker Scout 或 Syft。每種做法都會讀取它在映像檔中找到的套件中繼資料。就中繼資料所及的範圍而言,這是映像檔內容的正確紀錄,但它並不是映像檔如何建置的紀錄。

更新日期

如何為 Docker 映像檔產生 SBOM

常見的做法有三種。BuildKit 可以在建置映像檔時寫出 SBOM,並以證明(attestation)的形式附加到映像檔上。Docker Scout 與 Syft 則從已存在的映像檔產生 SBOM,不論映像檔在本機或登錄庫中。

在建置時使用 BuildKit

將 --sbom=true(或其完整形式 --attest type=sbom)加到 docker buildx build。BuildKit 會對建置結果執行其 Syft 掃描外掛,並將 SBOM 以 SPDX JSON 文件的形式附加到映像檔上。若想在推送任何內容前先查看 SBOM,請使用 local 匯出器進行建置:

# Build the image, attach an SBOM attestation and push it
docker buildx build --sbom=true -t registry.example.com/app:1.0 --push .

# The long form of the same option
docker buildx build --attest type=sbom -t registry.example.com/app:1.0 --push .

# Check the SBOM before pushing: write the build result to ./out
docker buildx build --sbom=true --output type=local,dest=out .
# out/sbom.spdx.json is the SBOM

讀取附加在映像檔上的 SBOM

docker buildx imagetools inspect 會從登錄庫讀回證明。所有與 SBOM 相關的內容,都位於其 Go 範本中的 .SBOM 之下:

# Print the SPDX document attached to the image
docker buildx imagetools inspect registry.example.com/app:1.0 \
  --format "{{ json .SBOM.SPDX }}"

# List each package and its version
docker buildx imagetools inspect registry.example.com/app:1.0 \
  --format "{{ range .SBOM.SPDX.packages }}{{ .name }}@{{ .versionInfo }}{{ println }}{{ end }}"

從現有映像檔產生,使用 Docker Scout

docker scout sbom 會在映像檔有 SBOM 證明時使用該證明;沒有時,則自行為映像檔內容建立索引。它預設輸出 JSON,並可使用 --output 寫入檔案:

# List the packages in an image
docker scout sbom --format list registry.example.com/app:1.0

# Write an SPDX or CycloneDX SBOM to a file
docker scout sbom --format spdx --output app.spdx.json registry.example.com/app:1.0
docker scout sbom --format cyclonedx --output app.cdx.json registry.example.com/app:1.0

從現有映像檔產生,使用 Syft

Syft 是 BuildKit 外掛所採用的開源掃描工具。將它指向映像檔,並以 -o 選擇格式。加上 =file 即可將每種格式寫入各自的檔案:

# CycloneDX JSON to the terminal
syft registry.example.com/app:1.0 -o cyclonedx-json

# Both formats, each to its own file
syft registry.example.com/app:1.0 -o spdx-json=app.spdx.json -o cyclonedx-json=app.cdx.json

SPDX 還是 CycloneDX?

BuildKit 證明一律採用 SPDX。Docker Scout 可輸出 SPDX 或 CycloneDX,Syft 則兩者皆可輸出,另外還支援其他格式。兩種標準都會列出套件、版本、授權與套件 URL,因此選擇通常取決於接下來要讀取 SBOM 的工具。差異請參閱CycloneDX 與 SPDX 比較。

映像檔掃描工具如何建立 SBOM

這些工具的運作方式都相同:解開映像檔的各層,讀取其中找到的套件中繼資料,也就是作業系統的套件資料庫,以及語言套件管理工具留下的中繼資料。每個能被識別的套件都會成為一筆 SBOM 項目,包括來自基礎映像檔的套件。

納入建置階段與建置內容

BuildKit 預設只掃描最後一個階段。在多階段建置中,先前階段所用的編譯器、建置工具與套件並不在最終映像檔中,因此也不會出現在其 SBOM 裡。Docker 的 SBOM 證明文件說明了兩個可擴大掃描範圍的建置參數。BUILDKIT_SBOM_SCAN_STAGE 可加入某個階段,BUILDKIT_SBOM_SCAN_CONTEXT 則可加入建置內容(build context):

# syntax=docker/dockerfile:1
# Scan the build context as well as the image
ARG BUILDKIT_SBOM_SCAN_CONTEXT=true

FROM golang:1.25 AS build
# Include this build stage in the SBOM
ARG BUILDKIT_SBOM_SCAN_STAGE=true
WORKDIR /src
COPY . .
RUN go build -o /out/app .

FROM scratch
COPY --from=build /out/app /app
ENTRYPOINT ["/app"]

兩者都必須在 Dockerfile 中以 ARG 宣告。只用 --build-arg 設定並不會生效,不過 --build-arg 可以覆寫 Dockerfile 已宣告的值。使用 local 匯出器時,每個被掃描的階段都會有自己的檔案,例如 sbom-build.spdx.json 與 sbom.spdx.json 並列。

掃描仍會遺漏什麼

階段掃描補上了一個缺口。但掃描工具讀取的仍然是檔案,而建置所使用的某些內容不會留下檔案,或留下的檔案無法被識別:

  • 沒有套件中繼資料的檔案。以 curl 下載的二進位檔、在 RUN 步驟中解開的 tarball,或複製進來的內嵌程式碼。有些二進位檔(例如 Go 二進位檔)帶有掃描工具可讀取的建置資訊,但許多並沒有。
  • 建置下載後又刪除的內容。RUN 步驟在同一層中取得、使用並移除的套件或安裝程式,不會在檔案系統上留下任何可供掃描工具讀取的東西,無論是否為最後階段。
  • 內容是如何進來的。掃描產生的 SBOM 列出存在的內容,但不會說明套件來自哪個登錄庫或主機,也不會說明是哪個步驟取得的。
  • 您未標記的階段。階段掃描須主動啟用,可按階段或全域設定。未加上參數的階段仍會被排除。
  • 掃描設定。出現哪些內容取決於掃描工具的執行方式。在某個專案中,單一個 Syft 旗標就決定了 npm 套件是否會出現在結果中。

Yocto 建置中的相同問題,請參閱為什麼 SBOM 掃描工具會遺漏 Yocto 建置中的內容。

為什麼這很重要

遭入侵的建置工具或基礎映像檔,即使從未出現在最終映像檔中,也會影響您出貨的內容。而沒有中繼資料的二進位檔,可能帶有沒有任何 SBOM 項目指向的漏洞。資安公告發布時,您不只需要知道映像檔裡有什麼,也需要知道建置映像檔時用了什麼。

同時記錄建置

映像檔 SBOM 回答的是映像檔裡有什麼。建置紀錄回答的是建置引入了什麼:它拉取的基礎映像檔,以及每個步驟取得的套件,包括沒有任何 lockfile 列出的隱藏相依套件。CRACI 會在您的 GitHub Actions 作業執行時,透過執行器上可辨識套件的代理伺服器記錄這些內容,API 則會回傳該作業的 SBOM、網路追蹤與來源證明。以映像檔 SBOM 說明您出貨的內容,以建置紀錄說明它是如何產生的。

請參閱SBOM 工具比較、建置時 SBOM,以及如何在 GitHub Actions 中產生 SBOM。

Docker SBOM 常見問題

如何為 Docker 映像檔產生 SBOM?

常見做法有三種。將 --sbom=true 加到 docker buildx build,BuildKit 就會將 SPDX SBOM 附加到映像檔上。對現有映像檔執行 docker scout sbom。或執行 Syft,例如 syft IMAGE -o cyclonedx-json。三者都會讀取它們在映像檔中找到的套件。

什麼是 SBOM 掃描工具?

一種讀取檔案(例如原始碼目錄、lockfile 或容器映像檔),並針對其能識別的套件寫出 SBOM 的工具。Syft、Trivy、Docker Scout 與 BuildKit 的 Syft 外掛都是 SBOM 掃描工具。它們描述的是眼前的檔案,而不是產生這些檔案的建置。

Docker 會產生哪種 SBOM 格式?

BuildKit 證明是附加在映像檔上的 SPDX JSON 文件。Docker Scout 可以輸出套件清單,或寫出 SPDX 或 CycloneDX。Syft 兩者皆可輸出,還支援更多格式。請選擇使用該 SBOM 的工具所預期的格式。

掃描工具如何從 Docker 映像檔建立 SBOM?

它會解開映像檔的各層,讀取其中找到的套件中繼資料:作業系統的套件資料庫,以及語言套件檔案,例如已安裝的 npm 或 Python 套件中繼資料。每個能被識別的套件都會成為 SBOM 中的一筆項目。

映像檔 SBOM 為什麼會遺漏元件?

因為它只能列出在所讀取的檔案中能識別的內容。以 curl 下載的二進位檔沒有套件中繼資料,建置步驟下載後又刪除的套件不會留下任何可讀取的東西,而除非您啟用階段掃描,先前的建置階段也會被排除。

映像檔 SBOM 還有用嗎?

有用。它是您出貨映像檔內容的正確紀錄,包括來自基礎映像檔的套件。只是它不描述映像檔如何建置,因此在這點很重要時,請搭配建置紀錄使用。

看看您的映像檔建置引入了什麼

在 CRACI 上執行一次映像檔建置,將它取得的基礎映像檔與套件紀錄,和您掃描工具產生的映像檔 SBOM 並排比較。

預約示範