Corriger "Supplier is a minimum element and must not be empty" dans les SBOM CycloneDX
Si vous avez déjà fait passer un SBOM CycloneDX dans le FOSSA NTIA SBOM Validator ou un outil similaire, vous avez peut-être vu des erreurs comme celles-ci :
Supplier is a minimum element and must not be empty. Path: components.pkg:npm/express@4.18.2.supplier Rule: Component.supplier
Ces erreurs signifient que votre SBOM est techniquement un CycloneDX valide — il passe la validation de schéma — mais ne satisfait pas les éléments minimum NTIA pour une Software Bill of Materials. Si vous vendez des logiciels dans l'UE sous le Cyber Resilience Act (CRA), ou si vous livrez à une agence fédérale américaine, la conformité NTIA n'est généralement pas optionnelle.
Voyons ce qui se passe et comment le corriger.
Ce que les éléments minimum NTIA exigent
La NTIA a publié ses « Minimum Elements for a Software Bill of Materials » en 2021. Parmi les champs de données requis pour chaque SBOM :
| Champ | Description |
|---|---|
| Supplier Name | Le nom de l'entité qui crée, définit et identifie les composants |
| Component Name | Le nom attribué à une unité logicielle |
| Version | La version du composant |
| Unique Identifier | Un identifiant unique (comme PURL ou CPE) |
| Dependency Relationship | Quels composants sont des dépendances desquels |
| Author of SBOM Data | Qui a créé le SBOM |
| Timestamp | Quand le SBOM a été généré |
Le Supplier Name est requis à trois endroits distincts dans un SBOM CycloneDX :
metadata.supplier— l'organisation fournissant le logiciel décritmetadata.component.supplier— le fournisseur du composant de niveau supérieurcomponents[].supplier— le fournisseur de chaque dépendance listée
La plupart des générateurs SBOM, y compris des outils populaires comme Syft et Trivy, ont historiquement omis ces champs. La validation de schéma CycloneDX ne les exige pas — ils sont optionnels dans la spécification. Mais la validation NTIA les exige, et c'est ce qui compte pour la conformité.
La cause profonde
Quand vous exécutez npm install ou pip install, le fichier de verrouillage résultant (package-lock.json, requirements.txt, etc.) enregistre les noms de packages, versions et relations de dépendance. Ce qu'il n'enregistre pas, c'est qui a publié chaque package. Ces métadonnées se trouvent dans le registre de packages (npmjs.org, PyPI, etc.), pas dans votre fichier de verrouillage.
La plupart des générateurs SBOM analysent le fichier de verrouillage et rien d'autre. Résultat : chaque composant obtient un nom et une version, mais pas de supplier. Le SBOM est valide selon le schéma mais non conforme NTIA.
La solution : remplir les champs supplier à chaque niveau
1. Metadata supplier
La section metadata de votre SBOM a besoin d'un objet supplier avec au moins un name :
{
"metadata": {
"supplier": {
"name": "your-project-name"
},
"component": {
"type": "application",
"name": "your-project-name",
"version": "1.0.0",
"supplier": {
"name": "your-project-name"
}
}
}
}
Le metadata.supplier représente l'organisation fournissant le logiciel décrit par ce SBOM. Pour la plupart des équipes, c'est votre nom de projet ou d'entreprise.
2. Tool supplier
Si votre SBOM liste l'outil de génération sous metadata.tools, chaque outil devrait aussi porter un supplier :
{
"tools": [
{
"name": "your-sbom-tool",
"version": "1.0.0",
"supplier": {
"name": "Your Tool Vendor"
}
}
]
}
3. Component suppliers — la partie délicate
Chaque entrée du tableau components a besoin d'un supplier.name. Mais d'où viennent ces données si le fichier de verrouillage ne les contient pas ?
Il y a deux approches :
Option A : Enrichissement via le registre (idéal, plus lent)
Appelez l'API du registre npm (https://registry.npmjs.org/{package}) pour chaque dépendance, extrayez l'auteur ou le publisher, et remplissez le supplier. Cela donne les données les plus précises mais ajoute des appels réseau et de la latence à votre pipeline de génération SBOM.
Option B : Heuristique basée sur le scope du package (pratique, rapide)
Pour les packages npm, le scope (le préfixe @org/) est un proxy raisonnable pour le supplier. Par exemple :
@angular/core→ supplier :@angular@types/node→ supplier :@typesexpress→ supplier :express
C'est l'approche utilisée par des outils comme Syft et Trivy. Elle n'est pas parfaite — un package non scopé comme express est attribué à lui-même — mais elle satisfait l'exigence NTIA et constitue un choix défendable pour des outils automatisés. Le scope représente véritablement l'entité organisationnelle qui a publié le package.
Passage à CycloneDX 1.7
Pendant que vous corrigez les champs supplier, il vaut la peine de passer à la dernière version de la spécification. CycloneDX 1.7 (publié en octobre 2025) est la dernière version et est entièrement rétrocompatible. Les changements sont minimes :
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json"
}
Après la correction
Avec les champs supplier remplis à chaque niveau, votre SBOM devrait passer toutes les vérifications des éléments minimum NTIA :
Comment Verimu gère cela
Chaque SBOM généré par Verimu inclut déjà les champs supplier aux trois niveaux — metadata.supplier, metadata.component.supplier et supplier par composant — en utilisant des heuristiques basées sur le scope pour les packages npm (avec enrichissement par registre prévu dans une prochaine version).
Nos SBOM sont générés selon la spécification CycloneDX 1.7 et validés contre les éléments minimum NTIA avant livraison. Si vous travaillez vers la conformité CRA pour l'accès au marché européen d'ici septembre 2026, c'est un souci de moins.
Commencer gratuitement → ou réserver une démo pour voir comment Verimu gère la génération SBOM pour votre stack.