En décembre 2020, l’attaque SolarWinds révélait au monde entier une réalité que peu d’équipes DevOps avaient anticipée : la supply chain logicielle est devenue le vecteur d’attaque le plus dangereux de l’industrie. Un build compromis, une dépendance piégée, un registre infiltré — et ce sont 18 000 organisations qui se retrouvent avec une backdoor en production. Depuis, les incidents se sont multipliés (Codecov, Log4Shell, xz-utils) et la question n’est plus “si” mais “quand” ta supply chain sera ciblée. Ce cours t’arme avec les frameworks et outils qui font aujourd’hui référence : SLSA pour la provenance, Sigstore/cosign pour la signature, et SBOM pour l’inventaire de tes composants.
Anatomie d’une supply chain logicielle
La supply chain, c’est tout ce qui se passe entre ton git push et le conteneur qui tourne en prod : les dépendances que tu importes, le pipeline CI/CD qui build, le registre qui stocke, et le runtime qui déploie. Chaque maillon est un point d’attaque potentiel.
Les vecteurs les plus exploités en entreprise sont :
- Dependency confusion / typosquatting : un package malveillant avec un nom quasi identique à une lib populaire (ex :
lodashvsl0dash) - Compromission du build : injection de code dans le pipeline CI (SolarWinds) ou dans un script d’upload (Codecov)
- Maintainer takeover : un contributeur patient gagne la confiance d’un projet open-source puis y insère une backdoor (xz-utils, 2024)
- Vulnérabilités transitives : ton app utilise 3 dépendances directes, mais elles en tirent 150+ transitives — et Log4j se cache dans le lot
🧠 À retenir : L’attaque SolarWinds n’a pas exploité une faille dans le code source. Le repo était propre. C’est le processus de build lui-même qui avait été compromis — le binaire livré contenait du code qui n’existait nulle part dans Git. C’est exactement le problème que SLSA résout.
Le framework SLSA : des niveaux de maturité concrets
SLSA (prononcé “salsa”) est un framework créé par Google qui définit des niveaux de confiance pour ton processus de build. L’idée centrale : chaque artefact doit être accompagné d’une attestation de provenance — un document qui prouve qui a buildé quoi, comment, et à partir de quelles sources.
Les quatre niveaux SLSA Build :
- Level 0 — Aucune garantie. Le dev build sur son laptop et pousse le binaire. C’est malheureusement encore la norme dans beaucoup d’organisations.
- Level 1 — Le build génère une attestation de provenance. On sait désormais d’où vient l’artefact.
- Level 2 — Le build tourne sur une plateforme hébergée (CI/CD) et la provenance est signée par le service de build.
- Level 3 — Le build est isolé (pas de contamination entre jobs) et la provenance est non-falsifiable. C’est le gold standard.
💡 Tip DevOps : GitHub Actions supporte nativement SLSA Level 3 via les slsa-github-generator workflows. Si tu es déjà sur GitHub, atteindre le Level 3 ne demande que quelques lignes de config — pas une refonte complète de ton pipeline.
Voici comment une provenance SLSA est structurée concrètement. Ce document JSON accompagne ton artefact et répond aux questions essentielles — qui, quoi, quand, comment :
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "myapp",
"digest": { "sha256": "abc123def456..." }
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v1",
"externalParameters": {
"source": {
"uri": "git+https://github.com/org/repo@refs/heads/main",
"digest": { "sha1": "abc123..." }
}
}
},
"runDetails": {
"builder": {
"id": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v1.9.0"
}
}
}
}
Et voici le workflow GitHub Actions qui génère automatiquement cette provenance SLSA Level 3 pour une image Docker :
# .github/workflows/release.yml
name: Release with SLSA Provenance
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/org/myapp:${{ github.ref_name }}
provenance:
needs: build
permissions:
actions: read
id-token: write
packages: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
with:
image: ghcr.io/org/myapp
digest: ${{ needs.build.outputs.digest }}
registry-username: ${{ github.actor }}
secrets:
registry-password: ${{ secrets.GITHUB_TOKEN }}
Sigstore et cosign : la signature sans la douleur
Sigstore est au signing ce que Let’s Encrypt est au TLS : une infrastructure gratuite, transparente et automatisée. Fini les clés PGP à gérer manuellement. L’écosystème repose sur trois composants : cosign (signe et vérifie les conteneurs), Fulcio (autorité de certificats éphémères basée sur ton identité OIDC), et Rekor (transparency log immutable qui enregistre chaque signature).
Le mode keyless est la vraie révolution : tu signes avec ton identité GitHub ou Google, pas avec une clé privée stockée quelque part. Plus de rotation de clés, plus de secrets qui fuient.
# Installer cosign
brew install cosign
# Keyless signing (recommandé) — utilise ton identité OIDC
cosign sign ghcr.io/org/myapp@sha256:abc123...
# → Authentification via navigateur, signature dans Rekor
# Vérifier la signature
cosign verify ghcr.io/org/myapp@sha256:abc123... \
--certificate-identity=user@company.com \
--certificate-oidc-issuer=https://accounts.google.com
# Key-pair classique (pour le CI/CD sans OIDC)
cosign generate-key-pair
cosign sign --key cosign.key ghcr.io/org/myapp@sha256:abc123...
cosign verify --key cosign.pub ghcr.io/org/myapp@sha256:abc123...
⚠️ Attention : En CI/CD, le keyless signing fonctionne nativement sur GitHub Actions grâce au token OIDC (id-token: write). Sur GitLab CI ou Jenkins, il faut configurer un OIDC provider — sinon, utilise la méthode key-pair avec le secret stocké dans ton vault.
🔥 Cas réel : Chez un grand retailer européen, l’adoption de cosign keyless a permis de supprimer 47 secrets de signing dispersés dans différents pipelines CI. Le temps de rotation des clés est passé de “jamais fait” à “automatique à chaque signature”.
SBOM : l’inventaire qui sauve en cas de crise
Un SBOM (Software Bill of Materials) est la liste exhaustive de tous les composants qui composent ton logiciel — dépendances directes, transitives, librairies système, tout. Pense à la liste d’ingrédients sur un produit alimentaire, mais pour du code.
Pourquoi c’est devenu indispensable ? Quand Log4Shell a frappé en décembre 2021, les équipes qui avaient un SBOM ont pu répondre en minutes à la question “est-ce qu’on est impactés ?”. Les autres ont passé des semaines à auditer manuellement chaque service.
Deux formats dominent : SPDX (Linux Foundation, ISO standardisé) et CycloneDX (OWASP, orienté sécurité). Les deux sont solides — CycloneDX est plus populaire dans l’écosystème DevSecOps, SPDX dans le monde de la conformité.
Syft (par Anchore) est l’outil de référence pour la génération. Il scanne des images Docker, des répertoires source, ou des binaires :
# Installer Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# SBOM d'une image Docker (format CycloneDX)
syft ghcr.io/org/myapp:latest -o cyclonedx-json > sbom.cdx.json
# SBOM d'un répertoire source (format SPDX)
syft dir:. -o spdx-json > sbom.spdx.json
# Vue lisible en tableau
syft ghcr.io/org/myapp:latest -o table
# NAME VERSION TYPE
# express 4.18.2 npm
# pg 8.11.0 npm
# body-parser 1.20.1 npm
# ...150+ transitives
💡 Tip DevOps : Génère le SBOM à chaque build, pas juste au release. Stocke-le comme artefact CI et attache-le à l’image avec cosign attach sbom. En cas de CVE zero-day, tu pourras scanner tous tes SBOMs historiques en quelques secondes avec grype sbom:sbom.json.
Pipeline complet : build, sign, attest
Voici le pipeline qui intègre tous les concepts — build, SBOM, scan de vulnérabilités, signature et attestation. C’est le modèle à viser pour une supply chain mature :
# .github/workflows/secure-pipeline.yml
name: Secure Build Pipeline
on:
push:
branches: [main]
jobs:
build-sign:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: sigstore/cosign-installer@v3
- name: Build and push
id: build
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/org/myapp:${{ github.sha }}
- name: Generate SBOM
run: |
syft ghcr.io/org/myapp@${{ steps.build.outputs.digest }} \
-o spdx-json > sbom.spdx.json
- name: Scan vulnerabilities
run: |
grype sbom:sbom.spdx.json --fail-on critical
- name: Sign image (keyless)
run: |
cosign sign --yes \
ghcr.io/org/myapp@${{ steps.build.outputs.digest }}
- name: Attach and sign SBOM
run: |
cosign attach sbom --sbom sbom.spdx.json \
ghcr.io/org/myapp@${{ steps.build.outputs.digest }}
cosign sign --yes --attachment sbom \
ghcr.io/org/myapp@${{ steps.build.outputs.digest }}
Pour boucler la boucle côté Kubernetes, une policy Kyverno peut bloquer tout déploiement d’image non signée :
# kyverno-policy.yml - Admission control
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: verify-cosign-signature
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences: ["ghcr.io/org/*"]
attestors:
- entries:
- keyless:
subject: "*@company.com"
issuer: "https://accounts.google.com"
rekor:
url: https://rekor.sigstore.dev
🧠 À retenir : La chaîne complète est : build isolé → SBOM → scan vulnérabilités → signature → attestation de provenance → vérification à l’admission. Chaque maillon renforce le suivant. Un SBOM sans signature peut être falsifié. Une signature sans provenance ne prouve pas grand-chose. C’est l’ensemble qui crée la confiance.
Bonnes pratiques et pièges à éviter
Ce qui marche en entreprise :
- Commence par SLSA Level 1 (provenance) — c’est déjà un énorme gain de visibilité
- Génère un SBOM à chaque build, pas seulement au release
- Utilise le keyless signing dès que possible — moins de secrets = moins de surface d’attaque
- Stocke tes SBOMs dans un registre centralisé (Dependency-Track, GUAC) pour pouvoir les requêter
- Bloque les images non signées en admission Kubernetes avec Kyverno ou Connaisseur
Les pièges classiques :
- ⚠️ Ne pas scanner les dépendances transitives — c’est là que se cachent 90% des vulnérabilités
- ⚠️ Stocker les clés cosign dans le même repo que le code — autant ne pas signer du tout
- ⚠️ Générer un SBOM une fois et l’oublier — un SBOM périmé donne un faux sentiment de sécurité
- ⚠️ Ignorer les vulnérabilités “medium” — elles deviennent critiques quand elles sont chaînées
🔥 Cas réel : Après Log4Shell, une grande banque européenne a mis 3 semaines à identifier tous les services impactés — ils n’avaient pas de SBOM. Leur concurrent, qui avait adopté Syft + Dependency-Track 6 mois avant, a répondu en 4 heures. La supply chain security, c’est de la préparation qui paie le jour de la crise.
Résumé
La sécurité de la supply chain logicielle repose sur trois piliers complémentaires. SLSA fournit un framework de maturité par niveaux pour sécuriser ton processus de build et garantir la provenance de tes artefacts. Sigstore/cosign offre une infrastructure de signature moderne, avec le keyless signing qui élimine la gestion de clés. SBOM donne une visibilité totale sur les composants de ton logiciel, indispensable pour réagir vite aux CVE zero-day. Intégrés dans un pipeline CI/CD avec vérification à l’admission Kubernetes, ces outils transforment ta supply chain d’un angle mort en un périmètre maîtrisé.
🖥️ Pratique sur ton propre serveur
Pour suivre Sécurité Cloud en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Sécurité Cloud
5 / 6Sur cette page
Articles liés
Scanning et pipeline sécurisé
Scanning de vulnérabilités avec Trivy et Grype, GitHub Advanced Security, pipeline sécurisé bout en bout et protection contre la dependency confusion.
Zero Trust : ne fais confiance à personne
Comprends les principes du Zero Trust, pourquoi le modèle périmétrique est mort, l'architecture ZTA en détail et le modèle BeyondCorp de Google.
mTLS et Service Mesh en pratique
Implémente mTLS, déploie un Service Mesh (Istio/Linkerd), utilise Tailscale, et mets en place le Zero Trust progressivement sur Kubernetes.