Mais 123% CVE comunicadas por dia em 2026 do que no ano passado.

SBOM

SBOM de imagens Docker: como gerar uma e o que lhe escapa

Pode obter uma SBOM de uma imagem Docker com um único comando, durante o build com o BuildKit ou depois com o Docker Scout ou o Syft. Cada um lê os metadados de pacotes que encontra na imagem. É o registo certo do que a imagem contém, até onde os metadados chegam. Não é um registo de como a imagem foi construída.

Atualizado a

Como gerar uma SBOM para uma imagem Docker

Há três formas comuns. O BuildKit pode escrever a SBOM enquanto constrói a imagem e anexá-la à imagem como atestação. O Docker Scout e o Syft geram uma a partir de uma imagem que já existe, localmente ou num registo.

Durante o build, com o BuildKit

Acrescente --sbom=true, ou a sua forma longa --attest type=sbom, a docker buildx build. O BuildKit executa o seu plugin de scanner Syft sobre o resultado e anexa a SBOM à imagem como um documento SPDX JSON. Faça o build com o exporter local para ver a SBOM antes de fazer push de qualquer coisa:

# 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

Ler a SBOM anexada a uma imagem

docker buildx imagetools inspect lê a atestação a partir do registo. Tudo o que diz respeito à SBOM está em .SBOM no respetivo template Go:

# 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 }}"

A partir de uma imagem existente, com o Docker Scout

docker scout sbom usa a atestação SBOM da imagem quando existe uma. Quando não existe, indexa ele próprio o conteúdo da imagem. Imprime JSON por defeito e escreve para um ficheiro com --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

A partir de uma imagem existente, com o Syft

O Syft é o scanner open source em que assenta o plugin do BuildKit. Aponte-o para uma imagem e escolha o formato com -o. Acrescente =file para escrever cada formato no seu próprio ficheiro:

# 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 ou CycloneDX?

As atestações do BuildKit são sempre SPDX. O Docker Scout escreve SPDX ou CycloneDX, e o Syft escreve ambos, entre outros formatos. Ambas as normas listam pacotes, versões, licenças e package URLs, pelo que a escolha depende normalmente da ferramenta que vai ler a SBOM a seguir. Consulte CycloneDX vs SPDX para conhecer as diferenças.

Como um scanner de imagens constrói uma SBOM

Todas estas ferramentas funcionam da mesma forma. Desempacotam as camadas da imagem e leem os metadados de pacotes que encontram: a base de dados de pacotes do sistema operativo e os metadados que os gestores de pacotes de linguagens deixam para trás. Cada pacote que conseguem identificar torna-se uma entrada da SBOM, incluindo os pacotes vindos da imagem base.

Incluir as fases de build e o contexto de build

Por defeito, o BuildKit analisa apenas a fase final. Num build de várias fases, os compiladores, as ferramentas de build e os pacotes usados nas fases anteriores não estão na imagem final, pelo que também não estão na sua SBOM. A documentação de atestações SBOM do Docker descreve dois argumentos de build que alargam a análise. BUILDKIT_SBOM_SCAN_STAGE acrescenta uma fase e BUILDKIT_SBOM_SCAN_CONTEXT acrescenta o contexto de build:

# 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"]

Ambos têm de ser declarados com ARG no Dockerfile. Defini-los apenas com --build-arg não tem efeito, embora --build-arg possa substituir um valor declarado no Dockerfile. Com o exporter local, cada fase analisada recebe o seu próprio ficheiro, como sbom-build.spdx.json ao lado de sbom.spdx.json.

O que uma análise continua a não ver

A análise de fases fecha uma lacuna. Mas o scanner continua a ler ficheiros, e parte do que um build usa não deixa nenhum ficheiro para trás, ou nenhum que consiga identificar:

  • Ficheiros sem metadados de pacotes. Um binário descarregado com curl, um tarball desempacotado num passo RUN ou código vendorizado copiado para a imagem. Alguns binários incluem informação de build que um scanner consegue ler, como os binários Go; muitos não.
  • O que o build descarregou e apagou. Um pacote ou instalador que um passo RUN obtém, usa e remove na mesma camada não deixa nada no sistema de ficheiros para qualquer scanner ler, seja na fase final ou não.
  • Como as coisas entraram. Uma SBOM resultante de uma análise lista o que lá está. Não diz de que registo ou host veio um pacote, nem que passo o obteve.
  • Fases que não marcou. A análise de fases tem de ser ativada, por fase ou globalmente. Uma fase sem o argumento continua a ficar de fora.
  • Definições da análise. O que aparece depende de como o scanner é executado. Num projeto, uma única flag do Syft decide se os pacotes npm aparecem sequer no resultado.

Porque é importante

Uma ferramenta de build ou imagem base comprometida afeta o que distribui, mesmo que nunca apareça na imagem final. E um binário sem metadados pode conter uma vulnerabilidade para a qual nenhuma entrada da SBOM aponta. Quando surge um aviso de segurança, precisa de saber o que entrou na construção da imagem, além do que está nela.

Registe também o build

A SBOM da imagem responde ao que está dentro da imagem. Um registo do build responde ao que o build trouxe: as imagens base que obteve e os pacotes que cada passo obteve, incluindo as dependências ocultas que nenhum lockfile lista. O CRACI regista isso enquanto o seu job de GitHub Actions é executado, através de um proxy que reconhece pacotes no runner, e a API devolve SBOM, traços de rede e proveniência do job. Use a SBOM da imagem para o que distribui e o registo do build para saber como foi feito.

Consulte ferramentas de SBOM comparadas, SBOM durante o build e como gerar uma SBOM no GitHub Actions.

SBOM de imagens Docker: perguntas frequentes

Como gero uma SBOM para uma imagem Docker?

Há três formas comuns. Acrescente --sbom=true a docker buildx build e o BuildKit anexa uma SBOM SPDX à imagem. Execute docker scout sbom numa imagem existente. Ou execute o Syft, por exemplo syft IMAGE -o cyclonedx-json. Os três leem os pacotes que encontram na imagem.

O que é um scanner de SBOM?

Uma ferramenta que lê ficheiros, como um diretório de código-fonte, um lockfile ou uma imagem de contentor, e escreve uma SBOM dos pacotes que consegue identificar. O Syft, o Trivy, o Docker Scout e o plugin Syft do BuildKit são scanners de SBOM. Descrevem os ficheiros que têm à frente, não o build que os produziu.

Que formato de SBOM produz o Docker?

As atestações do BuildKit são documentos SPDX JSON anexados à imagem. O Docker Scout pode imprimir uma lista de pacotes ou escrever SPDX ou CycloneDX. O Syft escreve ambos, e outros. Escolha o formato que a ferramenta que consome a SBOM espera.

Como é que um scanner constrói uma SBOM a partir de uma imagem Docker?

Desempacota as camadas da imagem e lê os metadados de pacotes que encontra: a base de dados de pacotes do sistema operativo e os ficheiros de pacotes de linguagens, como os metadados de pacotes npm ou Python instalados. Cada pacote que consegue identificar torna-se uma entrada da SBOM.

Porque é que uma SBOM de imagem pode deixar de fora um componente?

Porque só pode listar o que consegue identificar nos ficheiros que lê. Um binário descarregado com curl não tem metadados de pacotes, um pacote que um passo de build descarregou e apagou não deixa nada para ler, e as fases de build anteriores ficam de fora a menos que ative a análise de fases.

Uma SBOM de imagem continua a ser útil?

Sim. É o registo certo do que está dentro da imagem que distribui, incluindo os pacotes da imagem base. Só não descreve como a imagem foi construída, pelo que deve combiná-la com um registo do build quando isso for importante.

Veja o que o build da sua imagem trouxe

Execute um build de imagem no CRACI e compare o registo das imagens base e dos pacotes obtidos com a SBOM de imagem do seu scanner.

Marcar demo