Corrigir "Supplier is a minimum element and must not be empty" em SBOMs CycloneDX
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: 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:
metadata.supplier— a organização que fornece o software descritometadata.component.supplier— o fornecedor do componente de nível superiorcomponents[].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:@typesexpress→ 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:
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.