← Voltar ao blog

Corrigir "Supplier is a minimum element and must not be empty" em SBOMs CycloneDX

· Verimu
CycloneDXNTIASBOMConformidade CRASupplier

Se alguma vez verificou um SBOM CycloneDX com o FOSSA NTIA SBOM Validator ou uma ferramenta semelhante, pode ter visto erros como estes:

Supplier is a minimum element and must not be empty. Path: metadata.supplier Rule: Metadata.supplier

Supplier is a minimum element and must not be empty. Path: components.pkg:npm/express@4.18.2.supplier Rule: Component.supplier

Estes erros significam que o seu SBOM é tecnicamente um CycloneDX válido — passa na validação de esquema — mas não cumpre os elementos mínimos NTIA para um Software Bill of Materials. Se vende software na UE ao abrigo do Cyber Resilience Act (CRA), ou entrega a uma agência federal dos EUA, a conformidade NTIA geralmente não é opcional.

Vamos analisar o que está a acontecer e como corrigir.

O que os elementos mínimos NTIA exigem

A NTIA publicou os seus "Minimum Elements for a Software Bill of Materials" em 2021. Entre os campos de dados obrigatórios para cada SBOM estão:

Campo Descrição
Nome do Supplier O nome da entidade que cria, define e identifica componentes
Nome do Componente O nome atribuído à unidade de software
Versão A versão do componente
Identificador Único Um identificador único (como PURL ou CPE)
Relação de Dependência Quais componentes são dependências de quais
Autor dos Dados SBOM Quem criou o SBOM
Marca Temporal Quando o SBOM foi gerado

O Nome do Supplier é obrigatório em três locais distintos num SBOM CycloneDX:

  1. metadata.supplier — a organização que fornece o software descrito
  2. metadata.component.supplier — o fornecedor do componente de nível superior
  3. components[].supplier — o fornecedor de cada dependência listada

A maioria dos geradores de SBOM, incluindo ferramentas populares como Syft e Trivy, historicamente omitiam estes campos. A validação de esquema CycloneDX não os exige — são opcionais na especificação. Mas a validação NTIA exige, e é isso que importa para conformidade.

A causa raiz

Quando executa npm install ou pip install, o lockfile resultante (package-lock.json, requirements.txt, etc.) regista nomes de pacotes, versões e relações de dependência. O que não regista é quem publicou cada pacote. Esses metadados residem no registo de pacotes (npmjs.org, PyPI, etc.), não no seu lockfile.

A maioria dos geradores de SBOM analisa apenas o lockfile. Resultado: cada componente obtém um nome e uma versão, mas nenhum fornecedor. O SBOM é válido quanto ao esquema mas não conforme com NTIA.

A solução: preencher campos supplier em cada nível

1. Supplier nos metadata

A secção metadata do seu SBOM precisa de um objeto supplier com pelo menos um name:

{
  "metadata": {
    "supplier": {
      "name": "nome-do-seu-projeto"
    },
    "component": {
      "type": "application",
      "name": "nome-do-seu-projeto",
      "version": "1.0.0",
      "supplier": {
        "name": "nome-do-seu-projeto"
      }
    }
  }
}

O metadata.supplier representa a organização que fornece o software descrito por este SBOM. Para a maioria das equipas, é o nome do projeto ou da empresa.

2. Supplier da ferramenta

Se o seu SBOM lista a ferramenta geradora em metadata.tools, cada ferramenta deve também ter um supplier:

{
  "tools": [
    {
      "name": "a-sua-ferramenta-sbom",
      "version": "1.0.0",
      "supplier": {
        "name": "O Seu Fornecedor de Ferramentas"
      }
    }
  ]
}

3. Suppliers dos componentes — a parte complicada

Cada entrada no array components precisa de um supplier.name. Mas de onde vêm esses dados se o lockfile não os tem?

Há duas abordagens:

Opção A: Enriquecimento a partir do registo (ideal, mais lento)

Chamar a API do registo npm (https://registry.npmjs.org/{package}) para cada dependência, extrair o autor ou publicador e preencher o supplier. Isto fornece os dados mais precisos mas adiciona chamadas de rede e latência ao seu pipeline de geração de SBOM.

Opção B: Heurística a partir do scope do pacote (prática, rápida)

Para pacotes npm, o scope (o prefixo @org/) é um proxy razoável para o fornecedor. Por exemplo:

  • @angular/core → supplier: @angular
  • @types/node → supplier: @types
  • express → supplier: express

Esta é a abordagem utilizada por ferramentas como Syft e Trivy. Não é perfeita — um pacote sem scope como express é atribuído a si próprio — mas satisfaz o requisito NTIA e é uma escolha defensável para ferramentas automatizadas. O scope representa genuinamente a entidade organizacional que publicou o pacote.

Atualização para CycloneDX 1.7

Enquanto corrige os campos supplier, vale a pena atualizar a versão da especificação. CycloneDX 1.7 (lançado em outubro de 2025) é a versão mais recente e é totalmente retrocompatível. As alterações são mínimas:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.7",
  "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json"
}

Após a correção

Com campos supplier preenchidos em cada nível, o seu SBOM deve passar todas as verificações de elementos mínimos NTIA:

✓ 12/12 verificações de elementos mínimos NTIA aprovadas

Como o Verimu lida com isto

Cada SBOM gerado pelo Verimu já inclui campos supplier nos três níveis — metadata.supplier, metadata.component.supplier e supplier por componente — utilizando heurísticas baseadas em scope para pacotes npm (com enriquecimento a partir do registo planeado para uma versão futura).

Os nossos SBOMs são gerados segundo a especificação CycloneDX 1.7 e validados contra os elementos mínimos NTIA antes da entrega. Se está a trabalhar na conformidade CRA para acesso ao mercado europeu até setembro de 2026, é um problema a menos com que se preocupar.

Comece grátis → ou marque uma demo para ver como o Verimu lida com a geração de SBOM para o seu stack.