Sécuriser la Supply Chain avec Cosign
Mise à jour :
La sécurité des images de conteneurs est un enjeu majeur. Comment être certain qu’une image provient bien de sa source officielle et qu’elle n’a pas été altérée ? C’est là qu’intervient Cosign, un outil développé par Sigstore pour signer et vérifier des images de manière simple et sécurisée.
Avec Cosign, plus besoin de stocker des clés privées sur votre machine, et les signatures peuvent être directement enregistrées dans un registre OCI. Cet outil s’intègre facilement dans une chaîne CI/CD et renforce la confiance dans le déploiement des applications.
Origine et historique
L’adoption massive des conteneurs a apporté de nombreux avantages, mais aussi des défis en matière de sécurité. Comment garantir qu’une image téléchargée sur un registry n’a pas été modifiée ou compromise ? C’est pour répondre à ce problème que Cosign a été créé.
Au fil des années, plusieurs attaques ont mis en lumière la vulnérabilité des chaînes d’approvisionnement logicielles. Les images conteneurisées ne font pas exception. Des images malveillantes peuvent être publiées sous des noms similaires à des versions officielles, ou bien des images peuvent être altérées avant d’être utilisées en production.
En 2021, Cosign a vu le jour sous l’égide de Sigstore, un projet open source soutenu par Google, Red Hat et la Linux Foundation. L’objectif de Sigstore est de faciliter la signature et la vérification de logiciels, sans imposer de complexité supplémentaire aux développeurs.
Depuis son lancement, Cosign a été rapidement adopté par les entreprises et les projets open source soucieux de renforcer leur chaîne de confiance. Il est désormais intégré à de nombreuses pipelines CI/CD, compatible avec les registries OCI, et utilisé par des plateformes comme Kubernetes pour vérifier l’authenticité des images avant leur déploiement.
Fonctionnement
Cosign simplifie la signature et la vérification des images de conteneurs sans complexité inutile. Contrairement aux méthodes traditionnelles qui nécessitent des certificats lourds à gérer, Cosign adopte une approche plus fluide et mieux intégrée aux workflows DevSecOps. Voici ses principales fonctionnalités.
L’une des innovations de Cosign est de permettre la signature sans stocker de clé privée sur l’ordinateur. Il prend en charge l’authentification via des fournisseurs OIDC ou un KMS comme Google Cloud KMS, AWS KMS ou HashiCorp Vault, garantissant ainsi que les clés sont générées et stockées de manière sécurisée.
Les signatures ne sont pas stockées dans un fichier séparé, mais directement dans le registry OCI à côté de l’image signée. Cela permet :
- D’éviter les pertes ou incohérences entre l’image et sa signature.
- De faciliter la vérification automatique par des outils tiers.
- D’assurer une intégration native avec les CI/CD pipelines.
Une fois une image signée, Cosign permet de vérifier en une commande si elle est authentique. Il peut aussi s’intégrer avec Kubernetes pour imposer des politiques d’admission qui bloquent le déploiement d’images non signées ou provenant de sources inconnues.
En plus de la signature, Cosign permet d’ajouter des attestations qui décrivent le processus de build, garantissant qu’une image provient bien d’une build validé. Cela est essentiel pour répondre aux exigences de Supply Chain Security et aux frameworks comme SLSA.
L’outil est conçu pour fonctionner avec des systèmes d’intégration et de déploiement continue comme GitHub Actions, Gitlab CI et Tekton. Il permet d’automatiser la signature et la vérification des images avant leur déploiement en production.
Grâce à ces fonctionnalités, Cosign devient un élément clé de la sécurisation des images de conteneurs et s’impose comme un standard dans la gestion de la chaîne de confiance logicielle. Dans le prochain chapitre, nous explorerons les concepts fondamentaux de la signature et de la vérification avec Cosign.
Installation et configuration de Cosign
Avant de commencer à signer et vérifier des images, il faut installer et configurer Cosign correctement. Voici les étapes selon votre système d’exploitation.
Si vous utilisez Homebrew :
brew install cosign
On peut aussi télécharger le binaire depuis GitHub ↗ pour toutes les trois plateformes (Linux, MacOS, Windows) :
wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o cosign # LinuxInvoke-WebRequest -Uri "https://github.com/sigstore/cosign/releases/latest/download/cosign-windows-amd64.exe" -OutFile "cosign.exe" #
Pour Linux, rendez le binaire exécutable et installez-le dans le répertoire
/usr/local/bin
:
chmod +x cosignsudo install cosign /usr/local/bin/cosign
Une fois installé, vérifiez que Cosign fonctionne correctement :
❯ cosign version ______ ______ _______. __ _______ .__ __. / | / __ \ / || | / _____|| \ | || ,----'| | | | | (----`| | | | __ | \| || | | | | | \ \ | | | | |_ | | . ` || `----.| `--' | .----) | | | | |__| | | |\ | \______| \______/ |_______/ |__| \______| |__| \__|cosign: A tool for Container Signing, Verification and Storage in an OCI registry.
GitVersion: v2.4.1GitCommit: 9a4cfe1aae777984c07ce373d97a65428bbff734GitTreeState: cleanBuildDate: 2024-10-03T17:01:50ZGoVersion: go1.22.7Compiler: gcPlatform: linux/amd64
Vous devriez voir la version installée s’afficher comme ci-dessus.
Générer une paire de clés pour Cosign
Générer une paire de clés locales
Si vous ne l’avez pas encore fait, commencez par générer une paire de clés :
cosign generate-key-pair
Entrez une paraphrase, cela crée deux fichiers :
cosign.key
: la clé privée utilisée pour signer les images.cosign.pub
: la clé publique qui permettra de vérifier les signatures.
Configurer Cosign avec une clé avec un KMS
Il est possible de configurer Cosign pour utiliser un Key Management Service (KMS) externe, offrant ainsi une sécurité renforcée et un meilleur contrôle des clés.
Lorsqu’un KMS est utilisé, Cosign n’a plus besoin de stocker des clés privées localement. À la place, il se connecte à un fournisseur de gestion de clés, qui sécurise les signatures et évite les risques de vol ou de fuite de clés.
Cosign utilise une URI spécifique pour identifier chaque fournisseur de KMS :
- AWS KMS →
awskms://
- Google Cloud KMS →
gcpkms://
- Azure Key Vault →
azurekms://
- HashiCorp Vault →
hashivault://
- Kubernetes Secrets →
k8s://
Chaque KMS a sa propre syntaxe d’URI, que nous détaillerons plus loin.
Pour créer une clé de signature dans un KMS, utilisez la commande suivante :
cosign generate-key-pair --kms <provider>://<clé>
Par exemple, pour générer une clé sur AWS KMS :
cosign generate-key-pair --kms awskms://arn:aws:kms:us-west-2:123456789012:key/abcd-1234-efgh-5678
Pour Google Cloud KMS :
cosign generate-key-pair --kms gcpkms://projects/mon-projet/locations/global/keyRings/monKeyRing/cryptoKeys/maClé
Et pour Azure Key Vault :
cosign generate-key-pair --kms azurekms://mon-vault/ma-clé
Une fois la clé générée, Cosign utilisera automatiquement le KMS pour signer et vérifier les images.
Signer une image avec Cosign
Maintenant que Cosign est installé et configuré, nous allons voir comment signer une image de conteneur. La signature garantit que l’image provient bien d’une source vérifiée et qu’elle n’a pas été modifiée.
Signer une image avec une clé locale
Pour signer une image, utilisez la commande suivante :
cosign sign --key cosign.key mon-registry/mon-image:latest
Cosign vous demandera la passphrase de votre clé. Une fois l’image signée, la signature sera stockée directement dans le registre OCI.
Signer une image avec un KMS
Si vous avez configuré Cosign avec un KMS, vous pouvez signer une image en appelant directement le KMS :
Avec AWS KMS :
cosign sign --key awskms://arn:aws:kms:us-west-2:123456789012:key/abcd-1234-efgh-5678 mon-registry/mon-image:latest
Avec Google Cloud KMS :
cosign sign --key gcpkms://projects/mon-projet/locations/global/keyRings/monKeyRing/cryptoKeys/maClé mon-registry/mon-image:latest
Avec Azure Key Vault :
cosign sign --key azurekms://mon-vault/ma-clé mon-registry/mon-image:latest
Et pour HashiCorp Vault :
cosign sign --key hashivault://mon-vault/ma-clé mon-registry/mon-image:latest
Vérifier une image signée
Une fois une image signée avec Cosign, il est essentiel de pouvoir vérifier son authenticité avant de l’utiliser ou de la déployer. La vérification permet de s’assurer que l’image provient bien de son auteur d’origine et n’a pas été altérée.
Vérifier une image avec une clé publique locale
Si une image a été signée avec une clé privée, elle peut être vérifiée avec la clé publique correspondante. Voici la commande pour vérifier une image :
cosign verify --key cosign.pub mon-registry/mon-image:latest
Si la signature est valide, Cosign affichera un message confirmant que l’image est authentique.
Vérification avec un KMS
Si l’image a été signée avec un KMS, la vérification se fait en appelant le fournisseur de clés :
Pour AWS KMS :
cosign verify --key awskms://arn:aws:kms:us-west-2:123456789012:key/abcd-1234-efgh-5678 mon-registry/mon-image:latest
Pour Google Cloud KMS :
cosign verify --key gcpkms://projects/mon-projet/locations/global/keyRings/monKeyRing/cryptoKeys/maClé mon-registry/mon-image:latest
Ou avec HashiCorp Vault :
cosign verify --key hashivault://mon-vault/ma-clé mon-registry/mon-image:latest
Cosign récupérera la signature enregistrée dans le registre et la comparera avec la clé stockée dans le KMS.
Intégration à des pipelines CI/CD
L’automatisation de la signature et de la vérification des images dans un pipeline CI/CD permet de garantir qu’aucune image non signée ou compromise n’est déployée en production. Cosign s’intègre facilement avec des outils comme GitHub Actions, GitLab CI et Jenkins.
Automatiser la signature avec GitHub Actions
Si vous utilisez GitHub Actions, vous pouvez ajouter une étape pour signer automatiquement les images générées. Voici un exemple de workflow GitHub Actions :
name: Build and Sign Container
on: push: branches: - main
jobs: build-and-sign: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v3
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v2.5.0
- name: Login to GitHub Container Registry uses: docker/login-action@v2.1.0 with: registry: quay.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Dockerfile uses: docker/build-push-action@v4 id: build-and-push with: context: . file: ./Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: quay.io/${{ github.repository }}:latest
- name: Install Cosign uses: sigstore/cosign-installer@v3.1.1
- name: Sign image with a key run: | cosign sign --yes --key env://COSIGN_PRIVATE_KEY quay.io/${{ github.repository }}:latest env: COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
Vérification automatique dans GitLab CI/CD
Dans un pipeline GitLab CI/CD, vous pouvez par exemple ajouter une étape pour vérifier les images avant déploiement :
verify_image: image: alpine:3.20 stage: verify before_script: - apk add --update cosign docker - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY script: - cosign verify "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" --certificate-identity "https://gitlab.com/my-group/my-project//path/to/.gitlab-ci.yml@refs/heads/main" --certificate-oidc-issuer "https://gitlab.com"
Conclusion
Nous avons vu comment Cosign permet de signer, vérifier et sécuriser les images de conteneurs à l’aide de clés et de services KMS. Que ce soit pour un usage individuel ou une intégration en CI/CD, Cosign offre une solution efficace et simple à mettre en place pour renforcer la chaîne de de livraison logicielle.
Cependant, ce guide n’est qu’une introduction à l’écosystème Sigstore. Cosign n’est qu’un des outils de cet environnement plus vaste, qui inclut également Rekor (journalisation des signatures), Fulcio (certificat d’identité OIDC).
De plus, nous n’avons pas encore abordé la vérification des images avant leur déploiement dans un cluster Kubernetes. Comment empêcher l’exécution d’images non signées dans un cluster ? Comment intégrer Cosign avec des Admission Controllers comme Kyverno ou OPA Gatekeeper ? Ces sujets feront l’objet d’autres guides pour aller encore plus loin dans la sécurisation des environnements conteneurisés.
Si vous souhaitez approfondir l’utilisation de Sigstore et Cosign, n’hésitez pas à explorer la documentation officielle ↗ et à expérimenter l’outil dans vos propres pipelines. La sécurité des conteneurs n’est plus une option, c’est une nécessité.