En décembre 2021, la vulnérabilité Log4Shell a exposé une réalité inconfortable : la plupart des organisations ne savaient pas si elles utilisaient Log4j. La bibliothèque était présente dans des milliers d'applications, souvent comme dépendance transitive invisible. Les équipes ont passé des semaines à auditer manuellement leurs systèmes pendant que les attaquants exploitaient la faille.
Cette crise a révélé un problème structurel : nous ne savons pas ce qui compose nos logiciels. La supply chain logicielle, l'ensemble des composants, processus et personnes impliqués dans la création d'un logiciel, est devenue le maillon faible de la sécurité. Cette page s'adresse aux développeurs, ingénieurs DevOps et responsables sécurité qui doivent comprendre ces risques et mettre en place des garde-fous concrets : SBOM pour l'inventaire, SLSA pour la maturité du build, Sigstore pour la signature, et des pratiques de gestion des dépendances directement applicables en CI/CD.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre les risques de la supply chain logicielle à travers des attaques réelles (SolarWinds, xz utils, Shai-Hulud)
- Générer et exploiter un SBOM (CycloneDX, SPDX) pour répondre en quelques minutes à une CVE critique
- Situer votre chaîne de build sur les niveaux SLSA (0 à 3) et automatiser la génération de provenance
- Signer vos artefacts sans gérer de clé privée grâce à Sigstore (Cosign, Fulcio, Rekor)
- Sécuriser vos dépendances : épingler, verrouiller, scanner, vérifier les checksums
- Construire une roadmap progressive de maturité supply chain, de la visibilité à la provenance
Qu'est-ce que la supply chain logicielle ?
Section intitulée « Qu'est-ce que la supply chain logicielle ? »Analogie : Imaginez la construction d'une voiture. Vous ne fabriquez pas chaque vis, chaque boulon, chaque composant électronique. Vous les achetez à des fournisseurs. Si l'un d'eux vous livre des freins défectueux, votre voiture sera dangereuse, même si votre assemblage est parfait.
En développement logiciel, c'est identique. La supply chain logicielle est l'ensemble des fournisseurs, outils et processus qui interviennent entre votre première ligne de code et l'application déployée en production. Chaque maillon peut être compromis, et une seule faille suffit à contaminer l'ensemble.
Les maillons de la chaîne
Section intitulée « Les maillons de la chaîne »Voici les composants typiques d'une supply chain logicielle, avec les risques spécifiques à chaque étape :
| Composant | Exemples | Risques associés |
|---|---|---|
| Code source | Votre code, contributions externes | Injection de code malveillant |
| Dépendances | npm, PyPI, Maven, Go modules | CVE, typosquatting, compte compromis |
| Outils de build | Compilateurs, bundlers, CI/CD | Compromission du processus de build |
| Artefacts | Images Docker, binaires, packages | Tampering, substitution |
| Infrastructure | Registries, CDN, serveurs de déploiement | Man-in-the-middle, compromission |
Chaque ligne de ce tableau représente un point d'entrée potentiel pour un attaquant. Une dépendance compromise peut exfiltrer vos secrets. Un outil de build modifié peut injecter un backdoor. Une infrastructure piratée peut distribuer une version corrompue de votre application.
L'ampleur du problème
Section intitulée « L'ampleur du problème »Les chiffres donnent le vertige :
- Plus de 80% du code d'une application moderne provient de dépendances tierces, un ratio stable depuis plusieurs années dans les rapports sectoriels (Sonatype, Synopsys OSSRA)
- En 2025, Sonatype a recensé plus de 454 000 nouveaux paquets malveillants publiés sur les registries publics (npm, PyPI, Maven Central, NuGet, Hugging Face), portant le total cumulé détecté à plus de 1,2 million de paquets, avec plus de 99% concentrés sur npm
- Une application Node.js moderne peut compter plusieurs centaines, voire plus d'un millier, de dépendances une fois l'arbre transitif complet déplié
- Le délai de détection d'un paquet compromis varie énormément : de quelques jours pour les cas les plus visibles à plus d'un an pour les attaques les plus discrètes
Ce que ces chiffres signifient concrètement : Quand vous écrivez une application de 10 000 lignes de code, vous faites en réalité confiance à 40 000 lignes de code écrites par des inconnus. Si l'un de ces auteurs voit son compte npm compromis, votre application peut devenir un vecteur d'attaque, souvent sans que personne ne s'en rende compte pendant des mois.
Cette gravité n'a pas échappé à l'OWASP (Open Web Application Security Project) : dans son Top 10:2025, publié début 2026, la catégorie A03, Software Supply Chain Failures entre directement à la troisième place du classement, avec le taux d'incidence moyen le plus élevé de toutes les catégories. Ce basculement confirme que la supply chain n'est plus un sujet périphérique du Top 10 OWASP appliqué au DevSecOps, mais un pilier central de toute stratégie de sécurité applicative.
Les trois piliers de la sécurité supply chain
Section intitulée « Les trois piliers de la sécurité supply chain »Face à la complexité de la supply chain, trois questions fondamentales émergent. Si vous ne pouvez pas y répondre avec certitude, vous êtes vulnérable.
Premier réflexe : Face à une nouvelle CVE critique (comme Log4Shell), pouvez-vous identifier en moins de 10 minutes tous les systèmes affectés ? Si la réponse est "non", c'est un problème de transparence.
Deuxième réflexe : Quand vous déployez une image Docker en production, êtes-vous sûr qu'elle n'a pas été modifiée entre le build et le déploiement ? Si vous ne pouvez pas le prouver, c'est un problème d'intégrité.
Troisième réflexe : Pouvez-vous affirmer que votre artefact provient exactement du commit Git que vous pensez, construit par votre CI/CD officiel ? Si vous devez fouiller dans les logs pour vérifier, c'est un problème de provenance.
Voici comment ces trois piliers se matérialisent techniquement :
| Pilier | Question | Solution |
|---|---|---|
| Transparence | Qu'est-ce qui compose mon logiciel ? | SBOM |
| Intégrité | Mon logiciel a-t-il été modifié ? | Signatures, SLSA |
| Provenance | D'où vient mon logiciel ? | Attestations, logs de transparence |
Pourquoi ces trois piliers sont indissociables : Un SBOM (transparence) sans signature (intégrité) peut être falsifié par un attaquant. Une signature sans SBOM ne vous dit pas si la dépendance vulnérable est présente. Une attestation de provenance sans les deux ne prouve rien sur le contenu réel de l'artefact. C'est l'intersection des trois qui crée la sécurité.
SBOM : l'inventaire des composants
Section intitulée « SBOM : l'inventaire des composants »Analogie : Quand vous achetez un produit alimentaire, vous lisez la liste des ingrédients. Farine, eau, sel, conservateurs. Si demain un conservateur est déclaré cancérigène, le fabricant peut rappeler tous les produits qui en contiennent. Sans cette liste, impossible de savoir quels produits sont concernés.
Un SBOM (Software Bill of Materials) est exactement cette liste d'ingrédients, mais pour le logiciel. C'est l'inventaire exhaustif de tous les composants qui composent votre application :
- Dépendances directes : les bibliothèques que vous avez explicitement ajoutées (
npm install express) - Dépendances transitives : les bibliothèques utilisées par vos dépendances (express dépend de 50+ packages)
- Versions exactes : pas "lodash 4.x", mais "lodash 4.17.21"
- Licences : MIT, Apache 2.0, GPL, crucial pour la conformité juridique
- Hashes : empreintes cryptographiques pour vérifier l'intégrité
Pourquoi un SBOM est essentiel
Section intitulée « Pourquoi un SBOM est essentiel »Sans SBOM, vous êtes aveugle. Quand une vulnérabilité comme Log4Shell est annoncée, vous devez pouvoir répondre en minutes, pas en semaines :
| Question | Sans SBOM | Avec SBOM |
|---|---|---|
| Suis-je affecté par CVE-2024-XXXX ? | "Je ne sais pas, il faut vérifier" | Requête automatique : oui/non |
| Quelles applications utilisent OpenSSL < 3.0 ? | Audit manuel de tous les projets | Export filtré instantané |
| Quelles licences sont présentes ? | Analyse juridique coûteuse | Liste générée automatiquement |
Formats de SBOM
Section intitulée « Formats de SBOM »Un SBOM, c'est comme un format de facture : tout le monde pourrait inventer le sien, mais pour que les systèmes se parlent, il faut des standards. Deux formats se sont imposés, chacun avec son histoire et ses forces.
CycloneDX vient du monde de la sécurité applicative (OWASP, les gens qui maintiennent le Top 10 des vulnérabilités web). Il est optimisé pour répondre rapidement à une CVE : métadonnées de sécurité riches, support natif des VEX (Vulnerability Exploitability eXchange, pour dire "oui la CVE existe, mais elle n'est pas exploitable dans mon contexte"). La spécification a atteint la version 1.7 fin 2025, désormais reconnue comme standard ECMA-424.
SPDX vient du monde de l'open source Linux Foundation. Il est standardisé ISO et se concentre sur la conformité juridique : qui a écrit quoi, sous quelle licence, avec quelles obligations. La version 3.0, sortie en 2024, introduit une architecture par profils (sécurité, licences, build, IA) qui étend le socle commun selon le cas d'usage. Si votre entreprise doit prouver qu'elle respecte les licences GPL, SPDX est votre allié.
| Format | Origine | Forces | Cas d'usage |
|---|---|---|---|
| CycloneDX | OWASP | Riche en métadonnées de sécurité, VEX intégré | Sécurité, vulnérabilités |
| SPDX | Linux Foundation | Standard ISO, focus licences | Conformité, juridique |
En pratique : Si votre priorité est la sécurité (réagir vite aux CVE), choisissez CycloneDX. Si votre priorité est la conformité légale, choisissez SPDX. Les deux formats coexistent, et les outils modernes supportent généralement les deux.
{ "bomFormat": "CycloneDX", "specVersion": "1.6", "components": [ { "type": "library", "name": "lodash", "version": "4.17.21", "purl": "pkg:npm/lodash@4.17.21", "licenses": [{ "license": { "id": "MIT" }}] } ]}{ "spdxVersion": "SPDX-2.3", "SPDXID": "SPDXRef-DOCUMENT", "packages": [ { "SPDXID": "SPDXRef-Package-lodash", "name": "lodash", "versionInfo": "4.17.21", "licenseConcluded": "MIT" } ]}Génération de SBOM
Section intitulée « Génération de SBOM »Plusieurs outils open source génèrent un SBOM directement depuis votre code ou votre image Docker, sans configuration lourde. Syft (Anchore) est le plus polyvalent : il détecte les paquets de dizaines d'écosystèmes (npm, pip, Go, Maven, RPM, APK) et exporte aussi bien en CycloneDX qu'en SPDX. Trivy a l'avantage de combiner génération de SBOM et scan de vulnérabilités dans un seul outil, ce qui simplifie l'intégration en CI/CD. Le choix dépend surtout de l'existant : si un scanner tourne déjà dans votre pipeline, réutiliser sa fonction SBOM évite d'ajouter un outil de plus.
# Avec Syft (Anchore) - recommandésyft packages dir:. -o cyclonedx-json > sbom.json
# Avec Trivytrivy fs --format cyclonedx -o sbom.json .
# Pour une image Dockersyft packages registry.example.com/myapp:v1.0.0 -o spdx-json > sbom.jsonPour un tour d'horizon plus complet des formats, des outils et des cas d'usage juridiques du SBOM, consultez le guide dédié SBOM : comprendre le Software Bill of Materials.
Intégration CI/CD
Section intitulée « Intégration CI/CD »Générer un SBOM une fois sur votre poste ne sert à rien si personne ne le refait au commit suivant. L'inventaire doit être produit automatiquement à chaque build, sinon il devient obsolète dès que la première dépendance change. L'exemple ci-dessous génère et archive un SBOM CycloneDX à chaque push sur main, avec les permissions minimales et un checkout qui ne persiste pas d'identifiants.
name: Generate SBOM
on: push: branches: [main]
permissions: {}
jobs: sbom: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false
- name: Generate SBOM uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 with: format: cyclonedx-json output-file: sbom.json
- name: Upload SBOM uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: sbom path: sbom.jsonSLSA : le framework de maturité
Section intitulée « SLSA : le framework de maturité »SLSA (Supply-chain Levels for Software Artifacts, prononcé "salsa") est un framework qui définit des niveaux de sécurité progressifs pour la chaîne de build.
Analogie : Pensez aux normes de sécurité automobile. Une voiture peut avoir :
- Niveau 0 : Aucune garantie (pas même une ceinture de sécurité documentée)
- Niveau 1 : Des ceintures de sécurité (c'est mieux que rien, mais ça reste déclaratif)
- Niveau 2 : Des airbags homologués en usine (protection automatique, garantie par le fabricant)
- Niveau 3 : ABS + contrôle de stabilité isolé du conducteur (même le constructeur ne peut pas le désactiver discrètement)
SLSA fait la même chose pour le logiciel. Depuis la version 1.0 du framework, publiée en 2023 et affinée jusqu'à la 1.2 actuelle, le volet "Source" historique a été retiré pour se concentrer sur le track Build : quatre niveaux mesurables (0 à 3, il n'existe plus de niveau 4) qui répondent à une question : Peut-on faire confiance à cet artefact ?
Les niveaux SLSA du track Build
Section intitulée « Les niveaux SLSA du track Build »Chaque niveau rajoute des garanties techniques qui rendent la falsification plus difficile :
| Niveau | Exigences | Ce que ça prouve | Effort |
|---|---|---|---|
| SLSA 0 | Aucune exigence | Absence de toute garantie formelle | - |
| SLSA 1 | Provenance générée et distribuable | Le build est documenté et traçable | Faible |
| SLSA 2 | Provenance signée, build sur plateforme hébergée | Le processus n'a pas été altéré après coup | Moyen |
| SLSA 3 | Build isolé, secrets de signature inaccessibles aux étapes définies par l'utilisateur | Même un accès root au runner ne permet pas de falsifier la provenance | Élevé |
Pourquoi une progression ? Parce que viser directement le niveau 3 est irréaliste pour la plupart des organisations. SLSA 2 est un bon compromis : la provenance est générée automatiquement par votre CI/CD (GitHub Actions, GitLab CI), donc un développeur malveillant ne peut pas la modifier facilement. SLSA 3 va plus loin : même avec un accès root au runner CI, la falsification devient extrêmement difficile parce que le secret de signature n'est jamais exposé aux étapes de build définies par l'utilisateur.
Anatomie de la provenance SLSA
Section intitulée « Anatomie de la provenance SLSA »Une attestation de provenance SLSA contient :
{ "_type": "https://in-toto.io/Statement/v1", "subject": [{ "name": "ghcr.io/myorg/myapp", "digest": { "sha256": "abc123..." } }], "predicateType": "https://slsa.dev/provenance/v1", "predicate": { "buildDefinition": { "buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v2", "externalParameters": { "source": { "uri": "git+https://github.com/myorg/myapp@refs/heads/main", "digest": { "sha1": "def456..." } } } }, "runDetails": { "builder": { "id": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@refs/tags/v2.1.0" }, "metadata": { "invocationId": "https://github.com/myorg/myapp/actions/runs/123456789" } } }}Cette attestation prouve :
- Quoi : L'image
ghcr.io/myorg/myappavec ce digest - D'où : Du repo
myorg/myapp, commitdef456... - Comment : Via le workflow GitHub Actions
generator_container_slsa3.yml - Quand : Run ID
123456789
Implémentation SLSA 3 avec GitHub Actions
Section intitulée « Implémentation SLSA 3 avec GitHub Actions »Atteindre le niveau 3 ne demande pas de réécrire votre pipeline de zéro : il suffit de déléguer la génération de la provenance à un générateur SLSA réutilisable, séparé de votre job de build. C'est ce découplage qui garantit qu'un attaquant ayant compromis votre job de build ne peut pas falsifier l'attestation, puisqu'il n'a jamais accès au secret de signature du générateur.
name: Release with SLSA
on: push: tags: ['v*']
permissions: {}
jobs: build: outputs: digest: ${{ steps.build.outputs.digest }} runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false
- name: Build and push id: build run: | docker build -t ghcr.io/${{ github.repository }}:${{ github.ref_name }} . docker push ghcr.io/${{ github.repository }}:${{ github.ref_name }} echo "digest=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/${{ github.repository }}:${{ github.ref_name }} | cut -d'@' -f2)" >> $GITHUB_OUTPUT
provenance: needs: build permissions: actions: read id-token: write packages: write uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0 with: image: ghcr.io/${{ github.repository }} digest: ${{ needs.build.outputs.digest }} registry-username: ${{ github.actor }} secrets: registry-password: ${{ secrets.GITHUB_TOKEN }}Sigstore : l'écosystème de signature
Section intitulée « Sigstore : l'écosystème de signature »Sigstore simplifie radicalement la signature d'artefacts en éliminant le problème le plus complexe : la gestion des clés privées.
Le problème historique : pourquoi personne ne signait
Section intitulée « Le problème historique : pourquoi personne ne signait »Imaginez que pour prouver votre identité, vous deviez porter en permanence un coffre-fort contenant votre passeport. Si vous le perdez, votre identité est volée. Si quelqu'un le vole, il peut se faire passer pour vous. Vous devez le garder accessible 24/7 (pour prouver qui vous êtes), mais absolument sécurisé (pour qu'on ne vous le vole pas). C'est impossible.
Avant Sigstore, signer un artefact logiciel était exactement ce cauchemar :
- Générer une paire de clés : Créer une clé privée (votre passeport numérique)
- Stocker la clé privée de manière sécurisée : Coffre-fort chiffré, HSM, KMS, coûteux
- Distribuer la clé publique : Comment les autres savent-ils que cette clé publique est vraiment la vôtre ?
- Gérer la rotation des clés : Changer de clé tous les X mois (cauchemar opérationnel)
- Révoquer les clés compromises : Si la clé fuite, comment annuler toutes les signatures passées ?
Résultat : la grande majorité des projets open source ne signaient rien. C'était trop complexe, trop cher, trop risqué. Les développeurs préféraient ne rien faire plutôt que de mal gérer une clé privée.
Sigstore résout ce problème avec une idée brillante : et si on n'avait pas besoin de gérer des clés privées ?
L'approche keyless de Sigstore
Section intitulée « L'approche keyless de Sigstore »Sigstore utilise des certificats éphémères liés à votre identité OIDC (GitHub, GitLab, Google). Voici comment ça fonctionne concrètement :
Scénario : Vous êtes développeur chez Acme Corp. Votre CI/CD GitHub Actions doit signer une image Docker.
-
Vous vous authentifiez via OIDC : Votre workflow GitHub Actions prouve son identité auprès de Sigstore : "Je suis le workflow
release.ymldu repoacme/app, déclenché par le tagv1.0.0, par l'utilisateuralice." -
Fulcio émet un certificat de courte durée (10 minutes) : Sigstore vous donne un certificat qui dit : "Ce certificat est valide pendant 10 minutes et atteste que le signataire est bien le workflow GitHub Actions de acme/app."
-
Vous signez avec ce certificat : Votre image Docker
ghcr.io/acme/app:v1.0.0est signée avec ce certificat temporaire. -
La signature est enregistrée dans Rekor (log de transparence) : Un registre public et immuable enregistre que le workflow
acme/app/.github/workflows/release.ymla signé l'image sha256:abc123 à une date donnée. -
Le certificat expire, mais la signature reste vérifiable : 10 minutes plus tard, le certificat est inutilisable. Mais n'importe qui peut vérifier la signature en consultant Rekor : "Cette image a bien été signée par le workflow officiel d'Acme Corp."
Résultat : Pas de clé privée à gérer (pas de risque de fuite), mais une traçabilité complète et vérifiable publiquement. Si un attaquant compromet votre repo, il peut signer une fois pendant 10 minutes, mais chaque signature est enregistrée dans Rekor. L'attaque sera visible.
Les composants Sigstore
Section intitulée « Les composants Sigstore »Sigstore n'est pas un outil unique mais un écosystème de trois briques qui coopèrent : une pour signer, une pour certifier l'identité du signataire, une pour enregistrer publiquement l'événement.
| Composant | Rôle | Analogie |
|---|---|---|
| Cosign | CLI pour signer/vérifier | Le stylo qui signe |
| Fulcio | Autorité de certification | Le notaire qui vérifie l'identité |
| Rekor | Log de transparence | Le registre public des actes |
| Gitsign | Signature des commits Git | Cosign pour Git |
Depuis octobre 2025, Rekor v2 est passé en disponibilité générale : le log de transparence repose désormais sur une architecture en tuiles (Trillian-Tessera) qui réduit fortement le coût d'exploitation côté Sigstore, sans rien changer à votre usage quotidien de Cosign. Les versions récentes du client (Cosign 2.6.0+ ou 3.0.1+) basculent automatiquement vers ce nouveau backend.
Signature avec Cosign
Section intitulée « Signature avec Cosign »Cosign est l'outil en ligne de commande de Sigstore : il signe et vérifie des images conteneurs (ou tout autre artefact OCI) en une seule commande. Deux approches coexistent. La signature keyless, recommandée, s'appuie sur votre identité OIDC (GitHub Actions, GitLab CI) sans jamais manipuler de clé privée. La signature avec clé, plus classique, reste utile quand votre organisation impose déjà une gestion de clés (HSM, KMS) ou fonctionne dans un environnement air-gapped sans accès à Fulcio.
# Signer (ouvre une fenêtre d'authentification OIDC)cosign sign ghcr.io/myorg/myapp:v1.0.0
# Vérifiercosign verify \ --certificate-identity "https://github.com/myorg/myrepo/.github/workflows/release.yml@refs/tags/v1.0.0" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ ghcr.io/myorg/myapp:v1.0.0# Générer une paire de cléscosign generate-key-pair
# Signercosign sign --key cosign.key ghcr.io/myorg/myapp:v1.0.0
# Vérifiercosign verify --key cosign.pub ghcr.io/myorg/myapp:v1.0.0Trusted Publishing : signer sans jeton
Section intitulée « Trusted Publishing : signer sans jeton »Sigstore ne protège que ce qui est effectivement signé. Or l'attaque Shai-Hulud (2025) a justement exploité le maillon le plus faible restant : des jetons npm à longue durée de vie, volés sur des postes de développeurs ou dans des variables d'environnement CI, permettant de republier automatiquement de nouveaux paquets infectés.
Depuis 2025, npm et PyPI répondent avec le Trusted Publishing : au lieu d'un jeton stocké en secret CI, le pipeline s'authentifie via OIDC directement auprès du registry, qui délivre un jeton de publication éphémère valable quelques minutes. Un paquet publié via Trusted Publishing est signé automatiquement par Sigstore, avec sa provenance publiée sans configuration supplémentaire. npm a définitivement désactivé ses anciens jetons classiques en décembre 2025, ce qui rend cette méthode incontournable pour tout mainteneur de paquet public.
Vérification dans Kubernetes
Section intitulée « Vérification dans Kubernetes »Générer et vérifier des signatures ne sert à rien si le cluster accepte quand même une image non signée. Kubernetes délègue ce contrôle à un admission controller, un composant qui intercepte chaque création de Pod et peut la refuser avant qu'elle n'atteigne un nœud. Kyverno est l'un des plus utilisés pour cet usage : sa ressource ImageValidatingPolicy bloque le déploiement de toute image qui ne porte pas une signature Cosign valide, sans action manuelle du développeur à chaque mise en production.
# ImageValidatingPolicy KyvernoapiVersion: policies.kyverno.io/v1kind: ImageValidatingPolicymetadata: name: verify-signaturesspec: validationActions: [Deny] matchConstraints: resourceRules: - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["pods"] matchImageReferences: - glob: "ghcr.io/myorg/*" attestors: - name: cosign-key cosign: key: data: |- -----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY----- validations: - expression: "true" message: "Image must be signed with our Cosign key."Cette politique refuse (validationActions: [Deny]) toute création ou mise à jour de Pod dont l'image ghcr.io/myorg/* ne correspond pas à la clé publique déclarée dans l'attestor cosign-key. En production, la vérification keyless (identité OIDC du workflow CI/CD plutôt qu'une clé statique à stocker et faire tourner) est généralement préférable à l'approche par clé montrée ici.
Sécuriser les dépendances
Section intitulée « Sécuriser les dépendances »Les dépendances sont le vecteur d'attaque le plus courant dans la supply chain logicielle. La raison est simple : vous ne contrôlez pas leur code, mais vous l'exécutez avec les mêmes privilèges que le vôtre.
Scénario réel : En 2021, un développeur a compromis son propre package npm ua-parser-js (des millions de téléchargements par semaine) pour y injecter un cryptominer. En quelques heures, des milliers d'applications ont commencé à miner de la cryptomonnaie pour l'attaquant, sans que personne ne s'en rende compte. Pourquoi ? Parce que les versions n'étaient pas épinglées, et que npm install a automatiquement téléchargé la version compromise.
Plusieurs pratiques complémentaires permettent de réduire ce risque de manière pragmatique. Le guide Sécuriser les dépendances npm, PyPI et Go détaille ces pratiques écosystème par écosystème, avec les commandes spécifiques à chaque gestionnaire de paquets.
Épingler les versions : arrêter de faire confiance aux futurs
Section intitulée « Épingler les versions : arrêter de faire confiance aux futurs »Quand vous écrivez "lodash": "^4.17.0" dans votre package.json, vous dites à npm : "Télécharge n'importe quelle version 4.17.x, y compris celles qui n'existent pas encore." C'est un chèque en blanc.
Si demain le compte npm du mainteneur de lodash est compromis (mot de passe faible, pas de 2FA), l'attaquant peut publier lodash@4.17.22 avec un backdoor. Votre prochain npm install téléchargera cette version malveillante. Vous aurez fait confiance à une version que vous n'avez jamais testée.
Ne laissez jamais le gestionnaire de packages choisir la version pour vous :
// Dangereux{ "dependencies": { "lodash": "^4.17.0", "express": "*" }}
// Sécurisé{ "dependencies": { "lodash": "4.17.21", "express": "4.18.2" }}Utiliser des lock files : figer l'arbre complet
Section intitulée « Utiliser des lock files : figer l'arbre complet »Épingler les versions dans package.json ne suffit pas. Pourquoi ? Parce que vos dépendances ont elles-mêmes des dépendances (dépendances transitives), et vous ne contrôlez pas leurs versions.
Exemple : Vous épinglez express@4.18.2. Mais Express dépend de body-parser, qui dépend de iconv-lite, qui dépend de safer-buffer. Si demain safer-buffer publie une nouvelle version avec un malware, et que iconv-lite accepte cette version, votre build téléchargera le malware même si vous n'avez jamais entendu parler de safer-buffer.
Les lock files (package-lock.json, yarn.lock, Pipfile.lock) résolvent ce problème en figeant l'arbre complet des dépendances : chaque package, chaque version, chaque hash. C'est une photo complète de l'état du monde au moment du lock.
# Installer uniquement ce qui est dans le lock filenpm ci # Pas `npm install`Pourquoi npm ci et pas npm install ? Parce que npm install peut mettre à jour le lock file si de nouvelles versions compatibles sont disponibles. npm ci refuse : il installe exactement ce qui est dans le lock file, ou il échoue. C'est ce que vous voulez en CI/CD.
Vérifier les checksums : détecter les substitutions
Section intitulée « Vérifier les checksums : détecter les substitutions »Le problème : Même avec un lock file, un attaquant qui contrôle le registry (ou un man-in-the-middle) peut substituer un package par une version malveillante qui porte le même nom et la même version.
La solution : Les lock files modernes incluent des hashes cryptographiques (SHA-512) de chaque package. Si le contenu téléchargé ne correspond pas au hash attendu, l'installation échoue.
# npm vérifie automatiquement les checksums du lock filenpm ci --ignore-scripts # Bonus : désactive les scripts post-install
# Python avec pip-toolspip-compile requirements.in --generate-hashespip-sync requirements.txtPourquoi --ignore-scripts ? Parce que certains packages npm exécutent des scripts arbitraires après installation (post-install hooks). Si un package est compromis, ce script peut exfiltrer vos secrets. En désactivant les scripts, vous limitez la surface d'attaque.
Scanner les vulnérabilités : réagir aux CVE connues
Section intitulée « Scanner les vulnérabilités : réagir aux CVE connues »Le contexte : Chaque semaine, de nouvelles vulnérabilités (CVE) sont publiées. Si vous ne scannez pas vos dépendances, vous ne saurez pas que vous êtes vulnérable. C'est comme conduire une voiture rappelée pour défaut de frein sans le savoir.
Les scanners de vulnérabilités comparent vos dépendances à des bases de données de CVE connues (NVD, GitHub Advisory Database, etc.) et vous alertent instantanément.
# npm audit (intégré à npm)npm audit --audit-level=high
# Trivy (multi-écosystème : npm, pip, Go, Rust, Java...)trivy fs --severity HIGH,CRITICAL .
# Grype (Anchore, alternative à Trivy)grype dir:.En pratique : Intégrez un de ces scanners dans votre CI/CD. Si une vulnérabilité HIGH ou CRITICAL est détectée, le build échoue, et vous forcez ainsi les équipes à corriger avant de déployer. Pour aller plus loin sur le triage et la remédiation une fois la CVE identifiée, consultez le guide Gestion des vulnérabilités CVE.
Roadmap d'implémentation
Section intitulée « Roadmap d'implémentation »La sécurisation de la supply chain est un voyage, pas une destination. Plutôt que de tout implémenter d'un coup, adoptez une approche progressive qui construit la maturité par étapes :
-
Mois 1-2 : Visibilité
- Générer des SBOM pour les projets critiques
- Scanner les dépendances (SCA) dans la CI
- Inventorier les registries et sources de dépendances
-
Mois 3-4 : Intégrité
- Signer les images Docker avec Cosign
- Vérifier les checksums des dépendances
- Activer les lock files et
npm ci - Migrer vers le Trusted Publishing (OIDC) pour vos propres paquets publiés
-
Mois 5-6 : Provenance
- Générer des attestations SLSA (niveau 2)
- Configurer la vérification de signatures dans Kubernetes
- Auditer les workflows CI/CD
-
Mois 7+ : Maturité
- Viser SLSA niveau 3
- Déployer Dependency-Track pour le suivi centralisé
- Automatiser la génération de VEX
À retenir
Section intitulée « À retenir »- SBOM : Savoir ce qui compose vos logiciels, obligatoire pour répondre aux CVE en minutes plutôt qu'en semaines
- SLSA : Framework de maturité en 4 niveaux (0 à 3 depuis la v1.0), viser le niveau 2 minimum
- Sigstore : Signature keyless via Cosign, Fulcio et Rekor, plus d'excuse pour ne pas signer
- Trusted Publishing : OIDC remplace les jetons npm/PyPI longue durée, exploités par des attaques comme Shai-Hulud
- Dépendances : Épingler, verrouiller, scanner, vérifier les checksums
- OWASP : la supply chain est désormais classée 3e risque applicatif dans le Top 10:2025
- Progressivité : Commencer par la visibilité, puis intégrité, puis provenance
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes »syft packages dir:. -o cyclonedx-json > sbom.json produit un inventaire exploitable dès le premier build.package-lock.json) avec npm ci pour figer l'arbre complet des dépendances, vérifier les checksums cryptographiques à l'installation, et scanner régulièrement avec un outil comme Trivy ou Grype pour détecter les CVE connues avant qu'elles n'atteignent la production.