Supply chain et images
Sécuriser la chaîne d'approvisionnement d'un cluster Kubernetes : inventorier le contenu des images avec un SBOM, vérifier leur origine par signature cryptographique, et faire appliquer ces contrôles au moment du déploiement via les admission controllers.
Table des matières
Pourquoi ce chapitre est le plus utile
Les chapitres précédents traitent de ce qui se passe une fois qu'un pod tourne sur le cluster — RBAC, isolation réseau, contextefenêtre de contexteIAQuantité de texte qu'un modèle peut prendre en compte simultanément : question, documents fournis et historique. Au-delà, les éléments les plus anciens sortent du champ.Voir dans le glossaire de sécurité. Celui-ci traite d'une question antérieure : d'où vient le contenu de ce pod, et pourquoi lui faire confiance. Une image de conteneur n'est pas un objet neutre : c'est un assemblage de couches produites par des dizaines de parties différentes — mainteneur de la distribution de base, mainteneurs de paquets système, mainteneurs de bibliothèques applicatives, votre propre équipe pour le code métier. Chaque maillon peut introduire une vulnérabilité, volontairement ou non, et Kubernetes ne vérifie par défaut aucun d'entre eux.
Un cluster peut avoir un RBAC irréprochable, des NetworkPolicy strictes et des pods en non-root, et rester compromis dès le premier déploiement si l'image contient une porte dérobée ou une dépendance vulnérable connue. La sécurité de la chaîne d'approvisionnement n'est pas une couche optionnelle ajoutée aux autres contrôles : c'est une condition préalable à leur utilité, puisqu'elle porte sur ce qui s'exécute réellement dans le périmètre qu'ils protègent.
Kubernetes ne vérifie par défaut ni l'intégrité, ni l'origine, ni le contenu d'une image avant de la déployer. Tant qu'aucun admission controller n'est configuré pour l'exiger, n'importe quelle image accessible depuis un registre atteignable par le cluster peut être déployée. Le champ
imaged'un manifeste de pod est une simple chaîne de caractères ; rien dans l'API Kubernetes n'impose qu'elle pointe vers un contenu de confiance.
Anatomie du risque dans une image
Une image combine trois strates de risque distinctes, utiles à séparer pour comprendre quel contrôle traite quoi.
L'image de base. La plupart des images applicatives partent d'une distribution existante — Debian slim, Alpine, ou une image distroless. Chaque paquet système embarqué peut porter une CVE connue, et une base non reconstruite depuis plusieurs mois en accumule mécaniquement, même sans changement du code applicatif.
Les dépendances applicatives. Bibliothèques installées via npm, pip, Maven ou Go modules. C'est le vecteur le plus documenté ces dernières années : compromission d'un mainteneur légitime, typosquatting sur un nom proche d'un paquet populaire, ou code malveillant injecté dans une mise à jour mineure qui passe inaperçue en revue rapide.
La provenance de construction. Même avec une base saine et des dépendances propres, rien ne garantit que l'image en production est bien celle produite par le pipeline CI officiel, et non une variante poussée directement sur le registre par quelqu'un disposant d'un accès en écriture. C'est le risque le moins intuitif des trois, et celui que la signature d'image adresse spécifiquement.
L'incident SolarWinds de 2020 reste la référence la plus citée en matière de compromission de chaîne d'approvisionnement logicielle : des attaquants ont inséré du code malveillant directement dans le processus de build officiel d'un logiciel largement déployé, avant sa signature et sa distribution. Le mécanisme transposé aux conteneurs est identique : si le pipeline CI est compromis, ou si un registre accepte des pushs non authentifiés, l'image publiée peut différer de ce que le code source laisse penser — sans qu'aucun scan classique ne le détecte, puisque le code inséré n'est pas nécessairement une CVE connue.
SBOM : savoir ce qu'une image contient réellement
Un SBOM, Software Bill of Materials, est un inventaire structuré et machine-lisible du contenu d'une image : paquets système, bibliothèques applicatives, versions exactes, licences. Deux formats dominent l'écosystème, SPDX et CycloneDX.
Son intérêt ne se limite pas à la conformité réglementaire, même si c'est souvent ce qui motive son adoption initiale. Son usage concret est la réponse rapide à une CVE critique : quand une vulnérabilité majeure touche une bibliothèque donnée, la question immédiate est « quelles images en production l'utilisent, et dans quelle version ». Sans SBOM archivé au build, cette réponse nécessite de re-scanner chaque image, une opération lente et parfois impossible si l'image d'origine a été retirée du registre entre-temps.
# Génération d'un SBOM au format SPDX avec Syft
syft mon-registre.io/app:1.4.2 -o spdx-json=app-1.4.2.sbom.json
# Scan de vulnérabilités à partir du SBOM déjà généré, sans re-télécharger l'image
grype sbom:app-1.4.2.sbom.json
Séparer génération du SBOM et scan a un avantage pratique : le SBOM reste stable tant que l'image ne change pas, alors que la base de CVE évolue en continu. Un même SBOM peut être re-scanné chaque jour sans reconstruire l'image, ce qui rend possible une détection rétroactive — une image saine à sa publication peut être signalée automatiquement dès qu'une nouvelle CVE touche l'un de ses composants.
Archivez systématiquement le SBOM produit à chaque build, attaché à l'image via un registre qui le supporte (OCI artifact) ou dans un stockage indexé par le hash de l'image. Le jour où une CVE critique touche une bibliothèque largement utilisée, répondre en quelques minutes plutôt qu'en plusieurs heures de scan manuel fait une différence réelle, sous la pression d'une divulgation publique.
Signature d'image : garantir l'origine
Un SBOM répond à « que contient cette image ». La signature répond à une question différente : « provient-elle bien de la source que je crois, inchangée depuis sa construction ». Sans signature, rien n'empêche un attaquant disposant d'un accès en écriture sur un registre de remplacer une image légitime par une version modifiée portant le même tag.
Sigstore, projet porté par la Cloud Native Computing Foundation, s'est imposé comme référence pour la signature d'images, principalement via son outil cosign. Deux approches coexistent : la signature avec clé privée classique, où la clé signe l'image à la publication et sa clé publique vérifie la signature au déploiement — avec le défi de gérer et faire tourner cette clé en CI comme n'importe quel secret sensible ; et la signature « keyless », où cosign s'appuie sur une identité OIDC (GitHub Actions, GitLab CI, compte de service cloud) pour générer une signature éphémère enregistrée dans un journal de transparence public (Rekor), sans clé longue durée à gérer.
# Signature keyless dans un pipeline CI authentifié via OIDC
cosign sign mon-registre.io/app@sha256:3f29a...c1
# Vérification avant déploiement, en exigeant une identité précise
cosign verify mon-registre.io/app@sha256:3f29a...c1 \
--certificate-identity="https://github.com/mon-org/mon-repo/.github/workflows/build.yml@refs/heads/main" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
Signer une image ne suffit à rien si rien n'exige la vérification de cette signature avant exécution. Un pipeline qui signe consciencieusement chaque image, sans admission controller configuré pour rejeter les images non signées, produit des signatures jamais consultées. L'effort porte alors sur la production de la preuve, pas sur son application, ce qui laisse la porte ouverte à un déploiement direct d'une image non signée par quiconque dispose des droits RBAC suffisants.
Signez toujours au niveau du digest (@sha256:...), pas du tag mutable : un tag comme app:latest peut être réassigné à un nouveau contenu sans que la signature d'origine s'applique au contenu réellement servi, alors que le digest est un hash du contenu, non réutilisable pour une image différente.
Admission controllers : appliquer la politique au déploiement
Un admission controller intercepte chaque requête de création ou modification de ressource envoyée à l'API server, après authentification et autorisation RBAC, mais avant la persistance dans etcd. Kubernetes distingue les webhooks de validation, qui acceptent ou rejettent une requête, et les webhooks de mutation, qui la modifient avant de la laisser passer.
Deux projets dominent l'écosystème : OPA Gatekeeper, basé sur le langage Rego, et Kyverno, qui exprime ses politiques directement en YAML, plus accessible à une équipe sans expertise Rego.
Appliqué à la chaîne d'approvisionnement, un admission controller permet de faire respecter :
- Le rejet des images dont le tag n'est pas un digest immuable
- Le rejet des images ne provenant pas d'un registre explicitement autorisé
- L'exigence d'une signature Sigstore valide, émise par une identité CI précise
- L'exigence de l'absence de vulnérabilité critique connue, via un scan interrogé à l'admission
- Le rejet des images construites depuis une base marquée obsolète
# Politique Kyverno : exiger une image signée par une identité CI précise
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: exiger-image-signee
spec:
validationFailureAction: Enforce
rules:
- name: verifier-signature-cosign
match:
any:
- resources:
kinds: ["Pod"]
verifyImages:
- imageReferences:
- "mon-registre.io/*"
attestors:
- entries:
- keyless:
subject: "https://github.com/mon-org/*/.github/workflows/*"
issuer: "https://token.actions.githubusercontent.com"
validationFailureAction: Enforce bloque réellement les déploiements non conformes ; Audit se contente de journaliser les violations. Déploiement progressif recommandé : démarrer en audit, mesurer le volume de violations sur quelques semaines, corriger les cas légitimes, puis basculer en enforce — un passage direct en mode strict sur un cluster jamais audité casse une part importante des déploiements existants et pousse à désactiver la politique plutôt qu'à corriger les images.
Registres : le maillon souvent négligé
Un registre de conteneurs est souvent traité comme un simple entrepôt neutre, alors qu'il constitue un point de passage critique au même titre que l'API server. Un registre mal durci annule une bonne partie des efforts de signature et de scan en amont.
- Accès en écriture restreint : seul le pipeline CI authentifié devrait pousser vers les dépôts de production ; un accès large ouvert à toute l'équipe permet à un poste compromis de remplacer une image existante.
- Immuabilité des tags : Amazon ECR, Google Artifact Registry ou Harbor proposent un verrouillage des tags publiés, empêchant de réécrire silencieusement
app:1.4.2après coup. - Réplication contrôlée : un registre public utilisé directement en production, sans miroir interne, expose le cluster à une indisponibilité ou un retrait d'image décidé par un tiers.
- Scan intégré au registre : la plupart des registres managés proposent un scan automatique au push, qui complète — sans le remplacer — le scan effectué en amont en CI.
Utiliser exclusivement une image de base minimale, de type distroless ou une image Alpine réduite au strict nécessaire, diminue mécaniquement la surface de vulnérabilités. Une image distroless ne contient généralement ni shell, ni gestionnaire de paquets, ni outilstool callingIACapacité d'un agent ou d'un LLM à invoquer des outils externes (API, calcul, recherche) pendant le raisonnement.Voir dans le glossaire réseau, ce qui limite aussi ce qu'un attaquant peut faire une fois un accès obtenu à l'intérieur du conteneur.
Provenance et attestations SLSA
Au-delà de la signature, le cadre SLSA (Supply-chain Levels for Software Artifacts) formalise des niveaux de garantie croissants sur la façon dont un artefact a été construit : build reproductible, isolation de l'environnement de build, génération automatique d'une attestation de provenance signée.
Une attestation de provenance va plus loin que la signature seule : non seulement « cette image vient de mon pipeline CI », mais aussi « voici quel commit, quelle version de chaque dépendance et quel environnement de build l'ont produite ». cosign permet d'attacher cette attestation directement à l'image, vérifiable via cosign verify-attestation.
Adopter SLSA en totalité représente un investissement significatif, rarement justifié pour une petite équipe. Viser les premiers niveaux — build automatisé et traçable, provenance minimale systématique — reste accessible et améliore réellement la situation par rapport à l'absence totale de traçabilité, encore la norme sur la majorité des pipelines existants.
Récapitulatif des contrôles par niveau de maturité
| Niveau | Contrôle | Effort de mise en œuvre |
|---|---|---|
| Minimal | Scan de vulnérabilités en CI, échec du build sur CVE critique | Faible — outil unique à intégrer |
| Minimal | Registre privé avec accès en écriture restreint au pipeline CI | Faible — configuration du registre |
| Intermédiaire | Génération et archivage d'un SBOM à chaque build | Moyen — ajout d'une étape CI |
| Intermédiaire | Signature keyless des images avec cosign | Moyen — intégration OIDC du pipeline |
| Avancé | Admission controller en mode audit puis enforce | Élevé — politique à tester avant activationfonction d'activationIAOpération non linéaire appliquée en sortie d'un neurone. Sans elle, empiler des couches serait inutile : une succession d'opérations linéaires reste équivalente à une seule.Voir dans le glossaire stricte |
| Avancé | Attestation de provenance SLSA | Élevé — build reproductible requis |
Pièges fréquents
Scanner uniquement à la construction, jamais après. Une image saine à sa publication ne le reste pas indéfiniment : de nouvelles CVE sont publiées en continu sur des composants déjà déployés. Un scan périodique en production, pas seulement au build, est nécessaire pour détecter ce risque rétroactif.
Activer l'enforce sans phase d'audit. Un passage direct en blocage strict sur un cluster jamais préparé casse une part importante des déploiements existants, ce qui pousse presque toujours à désactiver la politique en urgence plutôt qu'à corriger les images.
Signer sans jamais vérifier au déploiement. Une signature jamais contrôlée par un admission controller n'apporte aucune protection réelle, seulement une trace exploitable après coup en investigation.
Confondre scan de vulnérabilités et vérification de provenance. Un scan détecte des CVE connues dans des composants identifiés ; il ne détecte pas qu'une image a été altérée après sa construction légitime. Les deux contrôles sont complémentaires, pas interchangeables.
Négliger la sécurité du registre lui-même. Un pipeline exemplaire en amont ne protège rien si le registre accepte des pushs non authentifiés ou si les tags peuvent être réécrits silencieusement.
L'essentiel à retenir
Ce chapitre traite la sécurité de tout ce qui entre dans le cluster sous forme d'image de conteneur, depuis sa construction jusqu'à son exécution effective sur un nœud. Il détaille comment produire et exploiter un SBOM pour savoir précisément ce que contient une image, comment signer et vérifier une image avec Sigstore et cosign pour garantir son origine, et comment un admission controller applique ces vérifications au moment du déploiement plutôt qu'après coup. Il couvre également le durcissement des registres eux-mêmes, trop souvent traités comme un simple entrepôt neutre alors qu'ils constituent un point de passage critique de la chaîne. Le chapitre se termine par une checklist de mise en œuvre progressive, du scan de vulnérabilités jusqu'au blocage strict des images non signées.
- SBOM (Software Bill of Materials)
- Signature d'image avec Sigstore et cosign
- Admission controller de validation et de mutation
- Provenance et attestation SLSA
- Durcissement et contrôle d'accès des registres
- Scan de vulnérabilités (Trivy, Grype)
- Politique d'admission (Kyverno, OPA Gatekeeper)
- Image de base minimale (distroless)
Questions fréquentes
Faut-il absolument signer toutes les images pour être considéré comme sécurisé ?
Quelle est la différence entre un scan de vulnérabilités et un SBOM ?
La signature keyless avec Sigstore est-elle vraiment plus sûre qu'une signature avec clé privée classique ?
Un admission controller ralentit-il significativement les déploiements ?
Faut-il appliquer les mêmes contrôles de supply chain à un cluster de développement qu'à un cluster de production ?
Que faire si un fournisseur tiers livre une image que l'on ne peut ni scanner en profondeur ni signer soi-même ?
Kyverno ou OPA Gatekeeper, lequel choisir pour débuter ?
Progression sauvegardée dans votre navigateur.
Quiz de validation
Quiz Player
Quiz de validation
Plusieurs réponses possibles — validez ensuite.
Vrai ou faux.
Quiz indisponible (données invalides).