Un SBOM (Software Bill of Materials) est l'inventaire lisible par une machine de ce que contient un logiciel : paquets système, bibliothèques, dépendances transitives, versions, licences. Il sert le jour où une CVE critique tombe et que la question devient « quels artefacts livrés embarquent ce composant ? ». Cette leçon s'adresse à un DevOps qui doit produire ce document en CI, le vérifier et le distribuer avec l'image.
Tout est mesuré sur un registre local : les sorties de Syft avec la
1.54.1 le 14 octobre 2026 (mêmes chiffres qu'avec la 1.52.0 deux semaines
plus tôt), celles de Grype 0.119.0 et de Cosign v3.1.3 le 1er octobre. Trois chiffres résument la leçon :
4 composants pour un requirements.txt, 96 pour l'image
python:3.13-slim, et 0 empreinte au niveau des paquets dans les deux cas.
Un SBOM n'est pas exhaustif par nature : sa couverture dépend de ce qu'on
scanne.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Distinguer les deux formats normalisés, et savoir lequel votre outil écrit réellement, qui n'est pas toujours la dernière version publiée.
- Générer un SBOM avec Syft depuis l'artefact que vous livrez, épinglé par empreinte.
- Mesurer la couverture de votre SBOM face aux dix-sept champs exigés en 2026, plutôt que de la supposer.
- Exploiter l'inventaire pour répondre à une CVE avec
jqet Grype. - Distribuer le SBOM en attestation signée attachée à l'image, et la vérifier.
- Prouver les exigences SOCLE-PKG-GEN-1 et SOCLE-PKG-SBM-1 à -3 du référentiel Socle DevSecOps, dont la première impose un SBOM par artefact et la deuxième qu'il porte licences et empreintes.
C'est quoi un SBOM, exactement ?
Section intitulée « C'est quoi un SBOM, exactement ? »Un SBOM est un document structuré qui décrit un artefact précis, une image ou un binaire, et répond à la question « qu'y a-t-il dedans ? ». Il ne se lit pas à la main : il s'interroge, se compare et se scanne. Les informations qu'il porte tiennent en quatre familles :
- les composants : nom, version, producteur quand il est connu ;
- des identifiants stables, surtout le purl (Package URL, comme
pkg:deb/debian/openssl@3.5.6-1~deb13u2), parfois un CPE ; - les relations de dépendance, directes et transitives ;
- des métadonnées : licences, empreintes, emplacement dans l'image.
Le cycle de vie qui donne sa valeur au document tient en quatre étapes : on le génère au build, on le distribue avec l'image, on le scanne en continu, et on réagit quand une vulnérabilité touche un composant listé.
Ce que le SBOM n'est pas
Section intitulée « Ce que le SBOM n'est pas »Le SBOM est souvent confondu avec les documents qui l'entourent dans la chaîne d'approvisionnement. Il ne fait qu'inventorier : chaque autre garantie vient d'un outil ou d'un document distinct, vus dans ce module.
- Ce n'est pas un scan de vulnérabilités : Grype ou Trivy le lisent pour en produire un.
- Ce n'est pas une preuve d'intégrité : c'est le rôle de la signature et de l'attestation.
- Ce n'est pas un verdict d'exploitabilité : c'est le rôle du VEX, vu dans la leçon suivante.
- Ce n'est pas un inventaire exhaustif : sa couverture dépend de la source scannée, de l'outil et du moment de la génération, comme le montrent les mesures ci-dessous.
Que demandent les « Minimum Elements » de 2026 ?
Section intitulée « Que demandent les « Minimum Elements » de 2026 ? »Le document de référence a changé de nom, de version et d'auteurs le 29 juillet 2026. Ce qu'on citait sous « NTIA 2021 » est désormais les 2026 Minimum Elements for a Software Bill of Materials, en version 2.1, publié par la CISA avec la NSA, le FBI et quinze partenaires internationaux, dont l'ANSSI pour la France.
Son historique tient en trois lignes, et il évite de citer un brouillon pour une norme. La version 2.0 n'a jamais été finale : elle a servi de base à l'appel à commentaires de 2025.
| Version | Date | Ce que c'est |
|---|---|---|
| 1.0 | 12 juillet 2021 | les minimum elements de la NTIA |
| 2.0 | 22 août 2025 | un brouillon soumis à commentaires |
| 2.1 | 29 juillet 2026 | la version finale, celle qu'on cite |
Le document définit dix-sept champs de données, contre sept en 2021. Les nouveaux champs portent sur la licence, l'empreinte des composants, la signature de l'auteur et le contexte de génération :
| Champ | Ce qu'il porte |
|---|---|
| Component Name, Component Version | le composant et sa version |
| Component Producer | qui le produit |
| Component License | nouveau : sous quelle licence |
| Component Identifiers | purl, CPE, clés de recherche |
| Component Hash Algorithm, Component Hash Value | nouveaux : l'empreinte, et l'algorithme qui l'a produite |
| Component Dependency Relationship | qui dépend de qui |
| SBOM Author, SBOM Author Signature | qui a produit le SBOM, et sa signature |
| SBOM Data Format Name, SBOM Data Format Version | le format et sa version |
| SBOM Generation Context | nouveau : à quelle phase du cycle de vie |
| SBOM Timestamp, SBOM Version | quand, et quelle révision |
| SBOM Tool Name, SBOM Tool Version | avec quoi |
Un changement compte plus que les autres : l'élément Depth de 2021 est remplacé par Coverage. La justification de l'annexe B du document décrit exactement le piège des mesures suivantes : « The Depth element was previously defined as capturing software component information for top-level dependencies only. This definition reflected the capabilities of SBOM tooling at the time rather than the depth of information needed to make informed security decisions. »
Combien de ces dix-sept champs votre SBOM porte-t-il vraiment ?
Section intitulée « Combien de ces dix-sept champs votre SBOM porte-t-il vraiment ? »Un SBOM généré depuis un requirements.txt en couvre neuf sur dix-sept.
Mesuré avec Syft 1.54.1 sur un fichier de quatre dépendances épinglées
(flask 3.1.2, requests 2.32.5, pyyaml 6.0.3, gunicorn 23.0.0), en
CycloneDX : la licence,
l'empreinte et le producteur sont absents des quatre composants, et
aucune relation de dépendance n'est déclarée.
| Présents | Absents |
|---|---|
| Name, Version, Identifiers (purl) | Producer, License |
| Data Format Name et Version | Hash Algorithm, Hash Value |
| Timestamp, Tool Name, Tool Version, SBOM Version | Dependency Relationship, Author, Author Signature, Generation Context |
Ce n'est pas un défaut de l'outil : un fichier de déclarations ne porte ni licence, ni empreinte. Syft ne peut pas inventer ce que la source ne contient pas. Les trois champs d'auteur, de signature et de contexte ne viennent jamais d'un scanner : c'est au pipeline de les ajouter, la signature par une attestation.
La couverture dépend de ce que vous scannez, pas de la commande
Section intitulée « La couverture dépend de ce que vous scannez, pas de la commande »La démonstration tient en trois lignes : même outil, même format de sortie, trois sources différentes. Les pourcentages comptent les composants logiciels (paquets et bibliothèques), sans les entrées de type fichier que Syft ajoute pour une image.
Source scannée par syft scan | Composants | Licence | Empreinte du composant | Producteur |
|---|---|---|---|---|
file:requirements.txt | 4 | 0 % | 0 % | 0 % |
les mêmes paquets installés (pip install --target) | 15 | 93 % | 0 % | 60 % |
l'image python:3.13-slim | 96 | 92 % | 0 % | 92 % |
De 4 à 96 composants selon ce qu'on pointe. Le fichier de déclarations ne
voit que les dépendances directes ; l'environnement installé révèle les
transitives (jinja2, werkzeug, urllib3…) et leurs licences ; l'image
ajoute les paquets Debian et l'interpréteur. Un SBOM produit depuis le
dépôt décrit ce que le projet demande, un SBOM produit depuis l'image décrit
ce qu'il contient : c'est pour cela que SBOM Generation Context est
devenu un champ obligatoire.
La colonne des empreintes mérite un second regard. Dans une image, Syft
calcule bien des empreintes, mais sur les 2 651 fichiers qu'il liste comme
composants de type file, pas sur les paquets eux-mêmes. Un auditeur qui
cherche Component Hash Value sur openssl ne la trouvera pas. La conséquence
pratique reste nette : générez le SBOM depuis l'artefact que vous livrez,
et vérifiez les champs exigés au lieu de les supposer.
Pourquoi le SBOM devient incontournable ?
Section intitulée « Pourquoi le SBOM devient incontournable ? »Le SBOM change la question qu'on se pose pendant un incident. Sans lui, on cherche où un composant pourrait se trouver ; avec lui, on interroge un inventaire déjà constitué. Les grands incidents de la chaîne d'approvisionnement, Log4Shell en 2021 ou XZ Utils en 2024, ont montré le coût de la première approche.
Le problème : réagir à l'aveugle
Section intitulée « Le problème : réagir à l'aveugle »Quand une CVE critique tombe, la première question est toujours « est-ce
qu'on est touchés ? ». Sans inventaire centralisé, la réponse demande de
fouiller chaque package.json, requirements.txt ou go.mod, de rescanner
chaque image une par une et d'interroger chaque équipe. Le résultat
prend des heures ou des jours, pendant que la vulnérabilité reste exploitable,
et sans certitude d'avoir tout couvert. La leçon d'ouverture du module,
sécurité de la supply chain logicielle,
détaille ces vecteurs d'attaque.
La réponse : un inventaire interrogeable
Section intitulée « La réponse : un inventaire interrogeable »Avec un SBOM par artefact, conservé à côté de l'image, la même question
devient une requête sur des données structurées. La commande suivante,
jouée sur le SBOM de python:3.13-slim, liste en une ligne toutes les
variantes d'OpenSSL présentes, avec leur purl :
jq -r '.components[] | select(.type != "file") | select(.name | test("^(openssl|libssl)")) | "\(.name) \(.version)"' python-3.13-slim.cdx.json# libssl3t64 3.5.6-1~deb13u2# openssl 3.5.6-1~deb13u2# openssl-provider-legacy 3.5.6-1~deb13u2Le filtre select(.type != "file") écarte les entrées de fichiers qui,
sinon, noieraient le résultat. Sur un répertoire de SBOM, une boucle for
sur les fichiers *.cdx.json pose la même question à tout le parc,
sans rescanner une seule image.
Formats standardisés : SPDX ou CycloneDX ?
Section intitulée « Formats standardisés : SPDX ou CycloneDX ? »Deux formats dominent : CycloneDX et SPDX. Les deux sont des normes publiées, lisibles par tous les outils courants, et Syft écrit les deux. Leur différence pratique tient moins au contenu qu'à la version que votre outil produit par défaut, et c'est elle qu'il faut vérifier.
CycloneDX (OWASP)
Section intitulée « CycloneDX (OWASP) »CycloneDX est un standard porté par l'OWASP, conçu dès le départ pour la sécurité applicative. Il est normalisé par l'Ecma sous le nom ECMA-424 : la première édition, en juin 2024, correspond à CycloneDX 1.6, la deuxième, en décembre 2025, à CycloneDX 1.7, publiée par l'OWASP le 21 octobre 2025.
- CycloneDX 1.4 (2022) : ajout du VEX, pour qualifier l'exploitabilité d'une vulnérabilité ;
- CycloneDX 1.5 (2023) : formulation (comment l'artefact a été construit) et inventaire des modèles d'apprentissage automatique ;
- CycloneDX 1.6 (2024) : inventaire cryptographique (CBOM) et attestations ;
- CycloneDX 1.7 (2025) : version courante.
Syft 1.54.1 écrit du CycloneDX 1.7 par défaut. Le suffixe @version force
une version plus ancienne quand l'outil qui consomme le SBOM l'exige. Mesuré :
les versions 1.2 à 1.7 sont acceptées, et @2.0 est refusé avec la
liste des formats connus, ce qui est cohérent avec une 2.0 non publiée.
# Registre local servi en HTTP : SYFT_REGISTRY_INSECURE_USE_HTTP=trueIMAGE="registry:localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06"
# CycloneDX 1.7 par défautsyft scan "$IMAGE" -o cyclonedx-json > sbom.cdx.jsonjq -r .specVersion sbom.cdx.json# 1.7
# Forcer une version plus anciennesyft scan "$IMAGE" -o cyclonedx-json@1.5 > sbom-1.5.cdx.jsonL'ancienne commande syft packages fonctionne encore, mais Syft 1.54.1
affiche l'avertissement de dépréciation ci-dessous : les exemples qui
circulent avec syft packages sont à mettre à jour.
Command "packages" is deprecated, use `syft scan` insteadSPDX (Linux Foundation / ISO)
Section intitulée « SPDX (Linux Foundation / ISO) »SPDX (Software Package Data Exchange) est un standard de la Linux
Foundation, normalisé sous ISO/IEC 5962:2021 (qui correspond à SPDX
2.2.1). Il est historiquement fort sur la conformité des licences : sa
liste d'identifiants (MIT, Apache-2.0, GPL-3.0-only) est reprise par
CycloneDX lui-même.
- SPDX 2.3 (2022) : la version qu'écrit Syft par défaut ;
- SPDX 3.0 (2024) : refonte en profils (Core, Software, Security, Licensing, Build, AI, Dataset), avec des relations VEX dans le profil Security.
La version courante de la spécification n'est pas celle que l'outil
produit. Mesuré avec Syft 1.54.1 : spdx-json sans suffixe écrit du
SPDX-2.3, et il faut demander spdx-json@3.0 pour obtenir un document
SPDX 3, dont le contexte JSON-LD pointe vers la 3.0.1. C'est l'inverse de
CycloneDX, où le défaut suit la dernière version.
syft scan "$IMAGE" -o spdx-json > sbom.spdx.jsonjq -r .spdxVersion sbom.spdx.json# SPDX-2.3
syft scan "$IMAGE" -o spdx-json@3.0 > sbom.spdx3.jsonjq -r '."@context"' sbom.spdx3.json# https://spdx.org/rdf/3.0.1/spdx-context.jsonldTableau comparatif
Section intitulée « Tableau comparatif »Le tableau résume les points qui décident d'un choix. Les deux lignes de version sont celles qu'on oublie : la version de la spécification et la version que votre outil écrit sont deux choses différentes, et l'écart est réel côté SPDX.
| Critère | CycloneDX | SPDX |
|---|---|---|
| Organisme | OWASP, normalisé par l'Ecma | Linux Foundation, normalisé par l'ISO |
| Version actuelle de la spécification | 1.7 (octobre 2025) | 3.0.1 |
| Version écrite par défaut par Syft 1.54.1 | 1.7 | 2.3 |
| Norme publiée | ECMA-424 (1re édition juin 2024, 2e décembre 2025) | ISO/IEC 5962:2021 |
| Focus d'origine | Sécurité, supply chain | Licences, conformité |
| VEX | Intégré depuis 1.4 | Relations VEX en 3.0 |
Ma recommandation : produisez au moins le format qu'attendent vos
consommateurs, et vérifiez sa version avec jq avant de le publier. Les
deux se génèrent depuis le même artefact en deux commandes, ce qui évite
de choisir quand un client exige SPDX et que vos outils lisent CycloneDX.
Outils de génération et d'analyse
Section intitulée « Outils de génération et d'analyse »Syft, d'Anchore, est l'outil de référence de cette leçon, mais il n'est pas le seul. Le choix dépend de ce que vous scannez : une image ou un binaire se prêtent bien à Syft et Trivy, un projet source multi-langages à cdxgen. Le guide dédié à Syft détaille ses sources et ses options.
| Outil | Éditeur | Points forts | Formats |
|---|---|---|---|
| Syft | Anchore | Images, archives, systèmes de fichiers | CycloneDX, SPDX |
| Trivy | Aqua Security | Scanner de vulnérabilités avec génération de SBOM | CycloneDX, SPDX |
| cdxgen | OWASP CycloneDX | Projets source multi-langages | CycloneDX |
L'ancien spdx-sbom-generator du projet SPDX est archivé sur GitHub : ne le prenez plus comme point de départ. Côté analyse, trois outils lisent un SBOM existant :
| Outil | Fonction | Guide |
|---|---|---|
| Grype | Scan de vulnérabilités d'un SBOM | Guide Grype |
| Trivy | Scan multi-cibles, SBOM compris | Guide Trivy |
| Dependency-Track | Suivi continu d'un parc de SBOM | Guide Dependency-Track |
Scanner un SBOM avec Grype
Section intitulée « Scanner un SBOM avec Grype »Grype lit un SBOM avec le préfixe sbom: et le confronte à sa base de
vulnérabilités, sans rescanner l'image. Mesuré avec Grype 0.119.0 sur le
SBOM de python:3.13-slim : 335 correspondances, dont 176 avec un
correctif publié. L'option --fail-on high fait sortir la commande en
code 2, ce qui suffit à bloquer un job CI.
grype sbom:./sbom.cdx.json# 335 lignes, dont openssl 3.5.6-1~deb13u2, corrigé en 3.5.7-1~deb13u2
grype sbom:./sbom.cdx.json --only-fixed --fail-on highecho $?# 2L'option --only-fixed retire les vulnérabilités sans correctif publié, sur
lesquelles l'équipe ne peut pas agir tout de suite. Le même SBOM rescanné un
mois après donne un autre résultat : la base évolue, l'inventaire reste fixe, et
c'est précisément ce qui permet de rescanner un parc entier sans reconstruire
une image.
Centraliser avec Dependency-Track
Section intitulée « Centraliser avec Dependency-Track »Dependency-Track est une plateforme qui ingère les SBOM, les
corrèle en continu avec les bases de vulnérabilités et alerte quand une
nouvelle CVE touche un composant déjà livré. Son API attend le SBOM en
multipart, pas en JSON brut : un curl -d @sbom.cdx.json avec un en-tête
JSON, encore courant dans les exemples, ne correspond pas à l'API documentée.
# Envoi d'un SBOM, projet créé à la volée s'il n'existe pascurl -X POST "https://dtrack.interne.exemple/api/v1/bom" \ -H "X-Api-Key: $DTRACK_API_KEY" \ -F "autoCreate=true" \ -F "projectName=order-service" \ -F "projectVersion=2.1.0" \ -F "bom=@sbom.cdx.json"La forme PUT existe aussi, avec le SBOM encodé en base64 dans un corps
JSON. Les deux formes sont décrites dans la documentation CI/CD de
Dependency-Track. La clé d'API vient d'un secret du pipeline, jamais du
code.
Distribuer un SBOM
Section intitulée « Distribuer un SBOM »Un SBOM qui reste sur le poste du développeur, ou dans un artefact CI expiré, ne sert à rien le jour de l'incident. Pour être utile, il doit être accessible aux équipes et aux clients, associé à l'artefact exact qu'il décrit, et vérifiable : on doit pouvoir prouver qu'il n'a pas été modifié après sa génération.
Trois stratégies de distribution
Section intitulée « Trois stratégies de distribution »Trois stratégies se rencontrent, de la plus simple à la plus robuste. Le schéma montre ce qui les sépare : seules les deux dernières placent le SBOM dans le registre, à côté de l'image désignée par son digest, et seule la troisième le signe.
| Stratégie | Avantages | Inconvénients |
|---|---|---|
| Fichier à côté (CI, release) | Simple à mettre en place | Dissocié de l'image, risque de désynchronisation |
Référent OCI (oras attach) | Dans le registre, lié au digest | Non signé : rien ne prouve qui l'a produit |
Attestation signée (cosign attest) | Intégrité et origine vérifiables | Demande une clé ou une identité OIDC |
La commande cosign attach sbom, longtemps citée pour la deuxième stratégie,
est dépréciée : Cosign v3.1.3 l'accepte encore mais affiche « SBOM
attachments are deprecated and support will be removed », et renvoie vers
les attestations. Pour un SBOM non signé dans le registre, oras fait le
même travail avec le mécanisme standard des référents OCI :
oras attach --plain-http --artifact-type application/vnd.cyclonedx+json \ localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06 \ sbom.cdx.json:application/vnd.cyclonedx+jsonoras discover --plain-http localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06Mesuré avec oras 1.3.4 sur un registre local registry:3 servi en
HTTP, d'où l'option --plain-http : oras discover affiche le SBOM sous
l'image, à côté des signatures que Cosign v3 range au même endroit.
SBOM en attestation signée
Section intitulée « SBOM en attestation signée »L'attestation va plus loin : Cosign enveloppe le SBOM dans une déclaration in-toto dont le sujet est le digest de l'image, puis la signe. Modifier le SBOM casse la signature, et un SBOM attesté pour une autre image ne passe pas la vérification. La signature keyless exige une identité OIDC ; l'exemple ci-dessous utilise une paire de clés, et une configuration de signature sans journal de transparence, pour rester sur un registre local sans rien publier sur l'instance publique de Sigstore.
# Configuration de signature vide : aucun service public sollicitécosign signing-config create --out signing-config.json
# Attester le SBOM CycloneDX sur l'image désignée par digestcosign attest --key cosign.key --signing-config signing-config.json \ --type cyclonedx --predicate sbom.cdx.json --allow-insecure-registry \ localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06
# Vérifier : la clé publique ET le type de prédicatcosign verify-attestation --key cosign.pub --type cyclonedx \ --insecure-ignore-tlog=true --allow-insecure-registry \ localhost:5000/python:3.13-slim@sha256:afe189875f1d2f9b45e287834fb9f2c273a5d59d354ae4050ab9affbf0a6ba06Trois résultats mesurés méritent d'être retenus. La vérification réussie
renvoie la déclaration signée, dont le predicateType vaut
https://cyclonedx.org/bom et le sujet le digest exact de l'image. Sans
--key ni identité, cosign verify-attestation échoue avec «
--certificate-identity or --certificate-identity-regexp is required » : il
n'existe pas de vérification « par défaut ». Et un --type spdxjson sur une
image qui ne porte qu'un SBOM CycloneDX échoue avec « none of the attestations
matched the predicate type ».
L'option --insecure-ignore-tlog=true n'est justifiée ici que parce qu'aucun
journal de transparence n'a été utilisé, et --allow-insecure-registry que
parce que le registre de test répond en HTTP. En production, la signature
passe par Rekor et la vérification le consulte, comme le détaille la leçon sur
Cosign.
Pourquoi attester plutôt que déposer un fichier ?
Section intitulée « Pourquoi attester plutôt que déposer un fichier ? »Parce qu'on construit un graphe d'artefacts vérifiable autour de l'image : SBOM, signature et provenance SLSA sont rangés au même endroit, liés au même digest, et signés par la même chaîne de build. Le jour où un client demande « prouvez-moi ce que contient cette image », la réponse est une commande de vérification, pas une recherche dans les artefacts CI. C'est aussi ce qu'exige SOCLE-PKG-SBM-2 : un SBOM attaché à l'artefact et récupérable par ses consommateurs.
Réagir vite à une CVE avec les SBOM
Section intitulée « Réagir vite à une CVE avec les SBOM »Une CVE critique qui tombe un vendredi soir est le cas d'usage qui justifie
tout le reste. Avec des SBOM centralisés, la réponse suit quatre étapes
qui s'outillent chacune, du simple jq à la plateforme de suivi. L'exemple
historique reste Log4Shell (CVE-2021-44228, score CVSS 10.0), qui
touchait log4j-core de la version 2.0-beta9 à la 2.14.1.
Étape 1 : identifier les artefacts concernés
Section intitulée « Étape 1 : identifier les artefacts concernés »La première question est quels artefacts embarquent le composant. Une
boucle sur les SBOM conservés y répond, avec la version et le purl, qui
désigne sans ambiguïté le paquet dans son écosystème. Pour la mesure, un
dossier sboms/ contient deux SBOM : celui de python:3.13-slim et celui d'un
service Java qui embarque le JAR officiel log4j-core-2.14.1.jar de Maven
Central.
for sbom in sboms/*.cdx.json; do jq -r --arg f "$sbom" '.components[] | select(.name == "log4j-core") | "\($f) \(.version) \(.purl)"' "$sbom"done# sboms/billing-api.cdx.json 2.14.1 pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1Seul le service Java ressort : Syft a reconnu le JAR et lui a attribué
le purl Maven exact, sans avoir besoin du pom.xml du projet.
Le purl est particulièrement utile : c'est la clé que les bases OSV et GitHub Advisory emploient pour désigner un paquet, ce qui permet une corrélation directe sans deviner le nom.
Étape 2 : vérifier si la version est vulnérable
Section intitulée « Étape 2 : vérifier si la version est vulnérable »Une version trouvée n'est pas forcément une version vulnérable. Plutôt que de comparer des numéros à la main, on laisse Grype confronter le SBOM à sa base : il connaît les plages affectées et les versions corrigées, y compris les correctifs rétroportés par les distributions, qu'une comparaison alphabétique ne voit pas.
$ grype sbom:sboms/billing-api.cdx.json --only-fixed -qNAME INSTALLED FIXED IN TYPE VULNERABILITY SEVERITY EPSS RISKlog4j-core 2.14.1 2.15.0 java-archive GHSA-jfh8-c2jp-5v3q Critical 100.0% (100th) 100.0 (kev)log4j-core 2.14.1 2.16.0 java-archive GHSA-7rjr-3q55-vv33 Critical 100.0% (99th) 99.0 (kev)log4j-core 2.14.1 2.17.0 java-archive GHSA-p6xc-xr62-6r2g High 100.0% (99th) 80.5log4j-core 2.14.1 2.17.1 java-archive GHSA-8489-44mv-ggj8 Medium 97.9% (99th) 56.8...Mesuré avec Grype 0.119.0 : 7 avis sur ce seul JAR. Le premier,
GHSA-jfh8-c2jp-5v3q, est l'avis GitHub de Log4Shell, corrigé en
2.15.0 et marqué (kev) : il figure au catalogue des vulnérabilités
activement exploitées de la CISA. La colonne FIXED IN donne
directement la version cible de la montée.
Étape 3 : prioriser la remédiation
Section intitulée « Étape 3 : prioriser la remédiation »Tous les artefacts concernés ne se valent pas. On priorise selon
l'exposition, la criticité métier et l'exploitabilité, avec les
critères du guide CVE, CVSS et EPSS. Les
colonnes EPSS et RISK de Grype 0.119.0, et le marqueur (kev), donnent
déjà une première probabilité d'exploitation à croiser avec le contexte.
| Critère | Priorité haute | Priorité basse |
|---|---|---|
| Exposition | Production exposée à Internet | Environnement de développement interne |
| Criticité métier | Service critique 24/7 | Traitement mensuel |
| Exploitabilité | Exploit public, EPSS élevé | Vulnérabilité théorique |
| Effort de correction | Montée de version simple | Refonte importante |
Étape 4 : automatiser avec Dependency-Track
Section intitulée « Étape 4 : automatiser avec Dependency-Track »À l'échelle d'un parc, la boucle jq ne suffit plus. Dependency-Track
garde chaque SBOM envoyé par la CI, réévalue le parc à chaque mise à jour
de ses sources de vulnérabilités, et alerte quand une nouvelle CVE touche
un composant déjà livré. Le temps de réponse passe alors de plusieurs jours
de recherche à une requête sur la plateforme.
Réduire le bruit : SBOM et VEX
Section intitulée « Réduire le bruit : SBOM et VEX »Un scan sur un SBOM complet remonte des centaines de correspondances :
335 sur la seule image python:3.13-slim. Beaucoup ne sont pas exploitables
dans votre contexte : code vulnérable jamais appelé, fonction désactivée,
condition d'exploitation absente. Sans moyen de le documenter, les équipes
trient le même bruit à chaque scan, jusqu'à ignorer les vraies alertes :
c'est l'alert fatigue.
Le VEX (Vulnerability Exploitability eXchange) répond à ce problème : un
document qui associe une vulnérabilité à un produit et à un statut
(not_affected, affected, fixed, under_investigation), avec une
justification. Grype et Trivy savent l'appliquer pour filtrer leur rapport. Il
existe en trois formats, OpenVEX, CycloneDX VEX et CSAF VEX, et
fait l'objet de la leçon suivante,
mesures comprises.
Mettre en pratique
Section intitulée « Mettre en pratique »Ce lab vient du fil rouge de la formation Python : l'outil
security_check.py, construit lab après lab, apprend à lire un SBOM
CycloneDX réel, produit par syft. Comme un SBOM liste des composants et non
des failles, l'outil croise chaque composant PyPI, lu dans son purl, avec la
base OSV, et fait de chaque vulnérabilité connue un finding, avec la
sévérité de son avis GitHub. La validation vérifie les requêtes envoyées à une
API OSV factice, le résumé par sévérité, et le seuil qui arrête un pipeline.
À retenir
Section intitulée « À retenir »- Un SBOM n'est pas un inventaire exhaustif : sa couverture dépend de la source scannée, de l'outil et du moment. Le document de 2026 a remplacé l'élément Depth par Coverage pour cette raison précise.
- De 4 à 96 composants selon ce qu'on pointe, avec Syft 1.54.1 : générez le SBOM depuis l'artefact livré, désigné par son digest, pas depuis le dépôt de code.
- Le document de référence est les 2026 Minimum Elements, version 2.1 du 29 juillet 2026, co-signé par l'ANSSI, avec dix-sept champs au lieu de sept.
- La version de la spécification n'est pas celle que l'outil écrit. Syft
1.54.1 produit du CycloneDX 1.7 mais du SPDX 2.3. Vérifiez la sortie
avec
jq, ne la supposez pas. - CycloneDX est une norme publiée depuis juin 2024 (ECMA-424), dont la deuxième édition de décembre 2025 couvre la 1.7.
syft packagesetcosign attach sbomsont dépréciés : on écritsyft scan, et on distribue en attestation aveccosign attest.- La preuve attendue par SOCLE-PKG-SBM-1 et SBM-2 est un SBOM complet par artefact (composants, licences, empreintes), au format normalisé, attaché à l'artefact et conservé, récupérable par les consommateurs.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de cette leçon est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : xBOM : comprendre l'écosystème des inventaires CycloneDX
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications