Distroless / Wolfi / Chainguard : images minimales sécurisées — tutoriel 2026
Cet article fait partie du cluster DevOps Avancé — Containers. Pour la vue d’ensemble complète des alternatives à Docker classique, lire d’abord le guide général avant de plonger dans ce tutoriel.
Introduction
En 2024, la faille CVE-2024-21626 dans runc a mis en lumière une réalité inconfortable : la majorité des images Docker en production embarquent des centaines de paquets inutiles, chacun une surface d’attaque potentielle. Un container Node.js basé sur node:20 (Debian slim) pèse environ 180 Mo et affiche régulièrement 80 à 120 vulnérabilités dans un scan Trivy. C’est le problème que les images minimales résolvent de fond en comble.
Distroless, le projet lancé par Google en 2017, part d’une idée radicale : une image de production n’a besoin que du runtime de l’application — rien d’autre. Pas de shell bash, pas de apt, pas de curl, pas de /etc/passwd superflu. Le résultat est une image qui tient en 5 à 30 Mo selon le langage, et qui rend de nombreuses attaques post-exploitation impossible par défaut : sans shell, un attaquant qui parvient à exécuter du code ne peut pas lancer de commandes interactives.
Wolfi est une distribution Linux minimaliste, entièrement conçue pour les containers, créée par Chainguard en 2022. Là où Distroless fournit des images figées, Wolfi offre un écosystème de paquets géré avec apk (le gestionnaire d’Alpine), des mises à jour quotidiennes, et la garantie contractuelle de zéro CVE connu sur les images taguées :latest. Chainguard publie chaque image avec une signature cryptographique Sigstore/cosign et un Software Bill of Materials (SBOM) intégré, transformant ainsi la chaîne d’approvisionnement logicielle d’une boîte noire en registre auditable.
Ce tutoriel vous guide pas-à-pas, de la compréhension des différences entre Distroless, Wolfi et Alpine, jusqu’à la production d’une image signée avec SBOM vérifiable, en passant par un scan Trivy à zéro CVE. Durée estimée : 30 minutes avec une connexion correcte.
Prérequis
- Docker 24+ ou Podman 4.8+ — les deux fonctionnent ; les commandes sont compatibles (remplacer
dockerparpodmanpartout) - Trivy 0.50+ — scanner de vulnérabilités open source d’Aqua Security (aquasecurity.github.io/trivy)
- cosign 2.0+ — outil Sigstore pour la signature et la vérification (docs.sigstore.dev/cosign)
- Accès Internet pour les pulls depuis
gcr.ioetcgr.dev - Niveau : intermédiaire — vous savez écrire un Dockerfile et comprendre un multi-stage build
- Temps estimé : 30 minutes
Étape 1 — Distroless vs Wolfi vs Alpine : positionnement
Avant d’écrire la première ligne de Dockerfile, il faut comprendre pourquoi ces trois approches existent et quand choisir l’une plutôt que l’autre. Elles ne sont pas des concurrentes directes — elles répondent à des besoins différents sur le spectre sécurité vs flexibilité vs compatibilité.
Alpine Linux est la base minimaliste historique. Elle utilise musl libc au lieu de glibc et pèse environ 7 Mo. Elle dispose d’un shell, d’un gestionnaire de paquets apk, et d’un écosystème de 10 000+ paquets. C’est le choix pragmatique pour les équipes qui veulent une image petite sans changer leur façon de travailler. Son inconvénient : le scan Trivy révèle régulièrement 10 à 30 CVE de sévérité moyenne sur une image alpine:3.19 fraîchement pullée, selon les paquets installés.
Distroless (Google) est une collection d’images de runtime — Java, Python, Node.js, Go (via static), etc. — qui ne contiennent que les bibliothèques strictement nécessaires à l’exécution d’un binaire. Il n’y a pas de gestionnaire de paquets, pas de shell par défaut (une variante :debug ajoute busybox pour le débogage). Les images sont construites à partir de Debian stable et mises à jour automatiquement. Elles sont parfaites en destination de multi-stage build : on compile dans une image lourde, on copie uniquement le binaire final dans Distroless.
Wolfi / Chainguard combine le meilleur des deux mondes : la flexibilité d’un gestionnaire de paquets (apk-compatible) avec la discipline de sécurité maximale. Wolfi est compilé avec glibc, ce qui le rend compatible avec la grande majorité des applications sans recompilation. Chainguard publie des images pré-construites pour les runtimes populaires (Python, Node.js, Go, Java, nginx…) et garantit 0 CVE connu au moment du push. Le projet est entièrement open source et documenté sur github.com/wolfi-dev.
| Critère | Alpine | Distroless | Wolfi / Chainguard |
|---|---|---|---|
| Taille de base | ~7 Mo | ~2–20 Mo | ~3–15 Mo |
| Shell disponible | Oui (ash) | Non (debug oui) | Non (variante :debug oui) |
| Gestionnaire paquets | apk | Aucun | apk (wolfi-style) |
| CVE garantis à 0 | Non | Approche (pas garanti) | Oui (:latest) |
| Signature Sigstore | Non | Non | Oui (cosign) |
| SBOM intégré | Non | Non | Oui (CycloneDX/SPDX) |
| Compatibilité glibc | Non (musl) | Oui (Debian) | Oui (glibc) |
La règle de décision est simple : si vous compilez un binaire Go statique, Distroless static est le choix optimal. Si vous avez besoin d’un runtime dynamique (Python, Node, Java) avec la garantie 0 CVE et une chaîne de signature, Wolfi/Chainguard s’impose. Alpine reste pertinente pour le développement local ou les cas où la compatibilité avec des scripts shell existants est non négociable.
Étape 2 — Multi-stage build avec gcr.io/distroless/static
Le multi-stage build est la technique fondamentale qui rend Distroless utilisable en pratique. L’idée est de séparer l’environnement de compilation (lourd, avec tous les outils de build) de l’environnement d’exécution (minimal, Distroless). Seul le binaire final traverse la frontière entre les deux stages. C’est une approche particulièrement adaptée aux applications Go, dont les binaires compilés avec CGO_ENABLED=0 sont entièrement statiques et n’ont besoin d’aucune bibliothèque système.
# Stage 1 : compilation dans l'image Go officielle
FROM golang:1.22-alpine AS builder
WORKDIR /app
# Copier les fichiers de dépendances en premier pour profiter du cache Docker
COPY go.mod go.sum ./
RUN go mod download
# Copier le reste du code source
COPY . .
# Compiler en binaire statique : CGO_ENABLED=0 désactive les liaisons C,
# GOOS=linux force la cible Linux même si on build sur macOS,
# -ldflags "-w -s" supprime les infos de debug pour réduire la taille
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-w -s" -o /api ./cmd/api
# Stage 2 : image de production Distroless
# gcr.io/distroless/static-debian12 ne contient que les certificats CA
# et les timezone data — rien d'autre
FROM gcr.io/distroless/static-debian12:nonroot
# Copier uniquement le binaire compilé depuis le stage builder
COPY --from=builder /api /api
# L'utilisateur "nonroot" (UID 65532) est défini dans l'image Distroless
# pour ne pas tourner en root
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/api"]
Construisez cette image avec docker build -t mon-api:distroless .. L’image résultante pèse typiquement entre 8 et 15 Mo selon la taille de votre binaire, contre 300+ Mo pour une image golang:1.22 directe. L’option :nonroot du tag signifie que le processus tourne sous un utilisateur sans privilèges — une mesure de sécurité supplémentaire que vous n’obtenez pas gratuitement avec les images classiques. Vérifiez avec docker run --rm mon-api:distroless whoami : la commande échouera car il n’y a pas de shell, mais docker inspect mon-api:distroless | grep User doit afficher nonroot.
Étape 3 — Wolfi base image cgr.dev/chainguard/wolfi-base
Contrairement à Distroless qui est une destination finale figée, wolfi-base est une image de construction active. Elle fournit un environnement apk-compatible avec le dépôt de paquets Wolfi, permettant d’installer exactement ce dont votre application a besoin — ni plus, ni moins. C’est l’approche privilégiée quand votre application nécessite des dépendances dynamiques (bibliothèques C, extensions Python, modules Node natifs) mais que vous refusez de partir d’une Debian ou Ubuntu gonflée.
# Utiliser wolfi-base comme image de construction
FROM cgr.dev/chainguard/wolfi-base:latest AS base
# Mettre à jour l'index des paquets et installer Python + pip
# Les paquets Wolfi sont compilés quotidiennement et patchés immédiatement
# dès qu'un CVE est publié — c'est la garantie 0 CVE de Chainguard
RUN apk update && apk add --no-cache python3 py3-pip
# Copier et installer les dépendances applicatives
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copier le code applicatif
COPY . .
# L'image wolfi-base définit déjà un utilisateur non-root
USER nonroot
EXPOSE 8000
CMD ["python3", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Après docker build -t mon-api:wolfi ., vérifiez la taille avec docker image inspect mon-api:wolfi --format '{{.Size}}' — divisez par 1 048 576 pour obtenir les mégaoctets. Une application FastAPI minimale avec wolfi-base se situe généralement autour de 80-120 Mo, bien en dessous des 400+ Mo d’une image python:3.12-slim avec les mêmes dépendances. Pour aller plus loin dans la réduction, Chainguard propose également des images pré-construites spécifiques comme cgr.dev/chainguard/python:latest qui partent directement d’un Python 3.12 sur Wolfi.
Étape 4 — apk-tools style Wolfi packages
Le gestionnaire de paquets Wolfi utilise la syntaxe apk d’Alpine, mais son dépôt est distinct et maintenu par Chainguard. Chaque paquet du dépôt Wolfi est compilé à partir des sources, signé avec une clé Chainguard, et reconstruit automatiquement dès qu’une vulnérabilité affectant ses dépendances est publiée. Cette chaîne est ce qui permet la garantie 0 CVE. Il est important de comprendre la différence entre les dépôts Alpine et Wolfi pour ne pas mélanger les deux — les paquets Alpine peuvent ne pas être compatibles avec l’environnement Wolfi (versions de musl vs glibc, notamment).
# Chercher un paquet dans le dépôt Wolfi depuis l'intérieur d'un container
docker run --rm cgr.dev/chainguard/wolfi-base apk search nginx
# Lister les paquets disponibles pour un runtime spécifique
docker run --rm cgr.dev/chainguard/wolfi-base apk search python3
# Voir les informations d'un paquet (version, dépendances, taille)
docker run --rm cgr.dev/chainguard/wolfi-base apk info -v python3
# Vérifier qu'aucun CVE ne touche un paquet installé
# (via trivy — voir étape 5)
trivy image cgr.dev/chainguard/wolfi-base:latest --pkg-types os
Ces commandes vous donnent une vision claire de ce que contient votre image avant même de construire votre Dockerfile final. La commande apk info -v est particulièrement utile pour vérifier les versions exactes et s’assurer que vous documentez correctement votre SBOM. Notez que dans une image de production finale (sans stage de build), il ne doit plus y avoir d’apk ni de cache de paquets — la commande apk del apk-tools && rm -rf /var/cache/apk est une bonne pratique pour supprimer le gestionnaire lui-même de l’image finale si vous n’en avez plus besoin au runtime.
Étape 5 — Scanner Trivy : 0 CVE attendu
Trivy est le scanner de vulnérabilités open source développé par Aqua Security, devenu en 2023-2024 le standard de facto pour l’analyse d’images containers dans les pipelines CI/CD. Il interroge plusieurs bases de données (NVD, GitHub Advisory, Alpine SecDB, Wolfi SecDB) pour croiser les paquets installés dans votre image avec les CVE connus. L’objectif ici est de valider que votre image Wolfi/Chainguard affiche bien 0 vulnérabilité, et de générer un rapport exploitable pour vos audits de conformité.
# Installer Trivy sur Ubuntu/Debian
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main \
| sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy
# Scanner l'image Wolfi de base — résultat attendu : 0 CVE
trivy image cgr.dev/chainguard/wolfi-base:latest
# Scanner votre image custom construite à l'étape 3
trivy image mon-api:wolfi
# Générer un rapport JSON pour audit (format exploitable par un SIEM ou un outil de conformité)
trivy image --format json --output rapport-cve-$(date +%Y%m%d).json mon-api:wolfi
# Scanner uniquement les vulnérabilités HIGH et CRITICAL (seuil CI/CD)
trivy image --severity HIGH,CRITICAL mon-api:wolfi
Si le scan de cgr.dev/chainguard/wolfi-base:latest retourne des CVE, c’est probablement que vous utilisez un tag versionné plus ancien plutôt que :latest, ou que Chainguard n’a pas encore publié le patch (généralement sous 24 heures). La commande docker pull cgr.dev/chainguard/wolfi-base:latest avant le scan garantit que vous testez bien la dernière version. Pour votre image applicative custom, si Trivy signale des CVE, le coupable est presque toujours une dépendance Python/Node installée via pip ou npm — dans ce cas, mettez à jour vos requirements.txt ou package.json plutôt que de chercher à patcher les paquets OS.
Étape 6 — Sigstore signature obligatoire Chainguard
La signature d’image avec Sigstore/cosign est ce qui distingue une supply chain sécurisée d’un simple registre de fichiers. En signant cryptographiquement votre image et en vérifiant la signature des images Chainguard, vous établissez une chaîne de confiance mathématiquement vérifiable : personne ne peut substituer une image malveillante sans que la vérification de signature échoue. Chainguard signe toutes ses images avec sa clé publique, disponible sur chainguard.dev.
# Installer cosign
# Sur Linux x86_64 :
curl -O -L https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign
# Vérifier la signature Chainguard d'une image officielle
# La clé publique de Chainguard est disponible à cette URL
cosign verify \
--certificate-identity-regexp="https://github.com/chainguard-images/" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
cgr.dev/chainguard/wolfi-base:latest
# Générer une paire de clés pour signer vos propres images
cosign generate-key-pair
# Génère cosign.key (clé privée, à garder secrète) et cosign.pub (clé publique)
# Signer votre image après l'avoir pushée dans un registry
docker tag mon-api:wolfi registry.monentreprise.com/mon-api:v1.0.0
docker push registry.monentreprise.com/mon-api:v1.0.0
cosign sign --key cosign.key registry.monentreprise.com/mon-api:v1.0.0
# Vérifier la signature depuis n'importe quelle machine ayant cosign.pub
cosign verify --key cosign.pub registry.monentreprise.com/mon-api:v1.0.0
La commande cosign verify sur une image Chainguard officielle retournera un bloc JSON contenant le sujet du certificat, l’émetteur OIDC (GitHub Actions dans ce cas), et le hash de l’image. Si la vérification réussit, la sortie affiche Verification for cgr.dev/chainguard/wolfi-base:latest -- The following checks were performed.... En intégrant cette vérification dans votre pipeline CI/CD (avant tout déploiement), vous vous protégez contre les attaques de type image poisoning — une menace réelle dans les registries publics qui a conduit à plusieurs incidents de sécurité majeurs en 2023-2024.
Étape 7 — SBOM auto-généré
Le SBOM (Software Bill of Materials) est l’inventaire exhaustif de tous les composants d’une image : paquets OS, bibliothèques applicatives, versions, licences, hashes. Il est devenu une exigence réglementaire dans de nombreux contextes (executive order US de 2021, cadre NIS2 en Europe) et un outil pratique pour répondre rapidement à la question « est-ce que mon infrastructure est vulnérable à la CVE-XXXX-YYYY ? ». Trivy et Syft peuvent générer des SBOM au format CycloneDX (JSON/XML) ou SPDX.
# Générer un SBOM CycloneDX pour votre image avec Trivy
trivy image --format cyclonedx --output sbom-mon-api-v1.0.0.json mon-api:wolfi
# Générer un SBOM SPDX (format alternatif, compatible plus d'outils)
trivy image --format spdx-json --output sbom-mon-api-v1.0.0.spdx.json mon-api:wolfi
# Récupérer le SBOM intégré d'une image Chainguard officielle
# Chainguard attache le SBOM comme attestation dans le registry
cosign download attestation cgr.dev/chainguard/wolfi-base:latest \
| jq '.payload | @base64d | fromjson | .predicate' \
| head -50
# Scanner un SBOM existant pour trouver des CVE (workflow asynchrone)
trivy sbom sbom-mon-api-v1.0.0.json
Le flux de travail recommandé pour une PME est le suivant : générer le SBOM à chaque build dans la CI, le stocker en artefact de pipeline avec le numéro de version, et le scanner quotidiennement avec Trivy pour détecter les nouvelles CVE qui auraient été publiées depuis le dernier build. Ce workflow découple la génération du SBOM (qui se produit une fois, au build) de la surveillance (qui est continue). La commande cosign download attestation sur les images Chainguard montre que cette pratique est déjà implémentée côté Chainguard : le SBOM est attaché cryptographiquement à chaque image et vérifiable à tout moment.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
exec /bin/sh: no such file or directory |
Tentative de docker exec -it container sh dans une image Distroless sans shell |
Utiliser le tag :debug (ex : gcr.io/distroless/static-debian12:debug) uniquement pour le debug, jamais en prod. Pour Wolfi : cgr.dev/chainguard/wolfi-base:latest-dev |
/api: exec format error |
Binaire compilé pour mauvaise architecture (ex : arm64 sur amd64) | Préciser GOARCH=amd64 dans le stage builder, ou utiliser docker buildx build --platform linux/amd64 |
| CVE non nuls sur image Wolfi custom | Dépendances pip/npm pas à jour, ou tag versionné figé | Mettre à jour requirements.txt, reconstruire avec --no-cache, utiliser :latest en dev |
cosign verify échoue sur image custom |
Image non signée ou mauvaise clé publique | Signer avec cosign sign --key cosign.key après chaque push ; stocker cosign.pub dans le repo Git |
| Image wolfi-base incompatible avec paquets Alpine | Tentative d’ajouter un dépôt Alpine (dl-cdn.alpinelinux.org) dans un Dockerfile Wolfi |
Utiliser uniquement les dépôts Wolfi (packages.wolfi.dev) ou construire le paquet manquant via wolfi-dev/os |
| SBOM vide ou incomplet | Trivy scanné avant le push (image locale sans manifest complet) | Pousser l’image dans un registry d’abord, scanner depuis le registry : trivy image registry.io/mon-api:v1 |
Adaptation au contexte ouest-africain
Dans les pays comme le Sénégal, la Côte d’Ivoire ou le Mali, les deux contraintes techniques dominantes sont la bande passante limitée et le coût des VPS. Les images Distroless et Wolfi apportent des bénéfices concrets sur ces deux fronts.
Une image Node.js classique basée sur node:20 pèse environ 350 Mo compressée. Avec une connexion 4G partagée sur un datacenter Hetzner Francfort (le choix le plus économique pour les PME de la sous-région avec 4 €/mois pour un CX22), chaque pull d’une nouvelle version prend 3 à 5 minutes. Multipliez par 10 services dans un cluster Kubernetes ou Docker Compose, et chaque déploiement devient un événement douloureux. Une image équivalente basée sur cgr.dev/chainguard/node:latest pèse environ 80 Mo — soit 4 à 5 fois moins. Les premiers pulls bénéficient des couches partagées entre images Chainguard (la base Wolfi commune est pullée une seule fois), ramenant les déploiements suivants à quelques mégaoctets de delta.
Sur la question de la conformité réglementaire, l’ARTCI (Autorité de Régulation des Télécommunications de Côte d’Ivoire) et les organismes équivalents au Sénégal (ARTP) travaillent sur des cadres de cybersécurité inspirés du RGPD et du NIST. Les entreprises soumises à des audits de sécurité (fintech, santé numérique, e-gouvernement) sont de plus en plus interrogées sur la sécurité de leur chaîne logicielle. Un rapport Trivy à 0 CVE sur les images de production, associé à des signatures cosign et des SBOM versionnés, constitue une preuve documentaire solide et exploitable lors d’un audit. C’est infiniment plus crédible que « nos images sont à jour » dit oralement.
Pour les équipes travaillant sur des réseaux instables (coupures fréquentes, bascule 4G/WiFi), le multi-stage build avec Distroless présente un autre avantage : le stage de build peut être exécuté dans un registry CI hébergé en Europe (GitHub Actions, GitLab CI sur serveur Hetzner), et seule la toute petite image finale est pullée par les serveurs de production. Cela réduit drastiquement l’impact d’une connexion dégradée sur les déploiements.
Tutoriels frères
- Podman rootless en production — tutoriel complet 2026 — lancer des containers sans daemon root, une approche complémentaire à Distroless pour réduire la surface d’attaque
- Buildah : construire des images OCI sans daemon Docker — alternative à
docker buildqui s’intègre parfaitement avec les Dockerfiles Distroless/Wolfi vus ici - Trivy intégré dans une pipeline CI/CD GitHub Actions — automatiser les scans présentés à l’étape 5 à chaque commit
Pour aller plus loin
- Retour au guide général : Containers sans Docker : Podman, Buildah, distroless (2026)
- github.com/GoogleContainerTools/distroless — dépôt officiel avec la liste complète des images (static, base, java, python, nodejs…)
- wolfi.dev — documentation officielle de la distribution Wolfi, guide de création de paquets custom
- chainguard.dev/chainguard-images — catalogue des images Chainguard pré-construites avec statut CVE en temps réel
- edu.chainguard.dev — academy Chainguard avec tutoriels approfondis sur Wolfi, cosign, SBOM
- aquasecurity.github.io/trivy — documentation Trivy complète (formats de sortie, intégrations CI/CD, politiques OPA)
- docs.sigstore.dev — référence Sigstore/cosign pour aller plus loin sur la signature et la vérification d’artefacts
FAQ
Q : Peut-on utiliser Distroless avec des applications qui ont besoin d’accéder à des fichiers de configuration au runtime ?
Oui, sans problème. L’absence de shell dans Distroless ne signifie pas l’absence de système de fichiers. Vous pouvez monter des volumes Docker, utiliser des ConfigMaps Kubernetes, ou copier des fichiers de configuration dans l’image au moment du build avec COPY --from=builder /app/config.yaml /config.yaml. Ce que vous ne pouvez pas faire, c’est exécuter des scripts shell (.sh) au démarrage — votre ENTRYPOINT doit pointer directement vers le binaire de l’application.
Q : Les images Chainguard gratuites sont-elles utilisables en production commerciale ?
Oui. Les images disponibles sur cgr.dev/chainguard avec le tag :latest sont gratuites et utilisables en production sans restriction de licence. Chainguard propose également une offre payante (Chainguard Images for Business) qui donne accès à des tags versionnés stables (ex : :3.12.3), un SLA sur les patchs CVE, et un support. Pour la plupart des PME de la sous-région, les images gratuites :latest sont largement suffisantes.
Q : Comment déboguer un container Distroless qui ne démarre pas correctement ?
La technique recommandée est de créer temporairement une variante de debug de votre image. Remplacez FROM gcr.io/distroless/static-debian12:nonroot par FROM gcr.io/distroless/static-debian12:debug-nonroot dans votre Dockerfile, reconstruisez, et vous aurez accès à un shell busybox minimal via docker run --rm -it --entrypoint /busybox/sh mon-api:debug. Une autre approche sans modifier le Dockerfile est d’utiliser docker cp pour extraire les logs de l’application ou docker logs si l’application écrit sur stdout. Ne jamais déployer la variante :debug en production.
Q : Est-ce que Wolfi est compatible avec mes images ARM (Raspberry Pi, serveurs Ampere) ?
Oui. Chainguard publie ses images en multi-architecture pour linux/amd64 et linux/arm64. Docker et Podman sélectionnent automatiquement la bonne variante lors du pull selon l’architecture de l’hôte. Pour construire explicitement pour une architecture cible (par exemple, construire une image arm64 depuis un poste amd64), utilisez docker buildx build --platform linux/arm64 -t mon-api:wolfi-arm64 ..
Q : Quelle est la différence entre un SBOM CycloneDX et SPDX ? Lequel choisir ?
CycloneDX et SPDX sont deux formats ouverts standardisés pour les SBOM. CycloneDX, maintenu par OWASP, est plus orienté sécurité et vulnérabilités, avec un support natif dans Trivy et les outils Chainguard. SPDX, maintenu par la Linux Foundation, est plus orienté conformité de licences et est notamment requis par certains appels d’offres gouvernementaux américains et européens. Pour une PME africaine, CycloneDX est le choix pragmatique : meilleur outillage, plus lisible, directement exploitable avec Trivy et Dependency-Track (plateforme open source de gestion de SBOM). Générez les deux si vous soumettez des dossiers d’appels d’offres publics.
Q : Peut-on intégrer cette chaîne complète (Wolfi + Trivy + cosign + SBOM) dans un pipeline GitHub Actions ?
Absolument, et c’est même la configuration recommandée. GitHub Actions dispose d’actions officielles pour chacun de ces outils : aquasecurity/trivy-action pour les scans CVE, sigstore/cosign-installer pour la signature, et anchore/sbom-action (utilisant Syft) pour la génération de SBOM. Le workflow complet — build, scan Trivy (bloquant si HIGH/CRITICAL), push, sign cosign, attach SBOM — peut tenir en moins de 80 lignes YAML. Ce tutoriel sera couvert en détail dans l’article connexe dédié aux pipelines CI/CD avec GitHub Actions du cluster DevOps Avancé.