{"id":476,"date":"2026-02-03T11:37:47","date_gmt":"2026-02-03T10:37:47","guid":{"rendered":"https:\/\/secure-pipelines.com\/?p=476"},"modified":"2026-03-24T12:54:34","modified_gmt":"2026-03-24T11:54:34","slug":"signing-verifying-container-images-sigstore-cosign","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/signing-verifying-container-images-sigstore-cosign\/","title":{"rendered":"Signature et V\u00e9rification des Images Container avec Sigstore et Cosign"},"content":{"rendered":"<h2>Introduction : Pourquoi la signature des artefacts est essentielle en CI\/CD<\/h2>\n<p>Les pipelines modernes de livraison logicielle sont remarquablement efficaces pour construire et livrer du code rapidement. Mais la rapidit\u00e9 sans confiance est un risque. Entre le moment o\u00f9 le code source est commit\u00e9 et celui o\u00f9 une image container s&rsquo;ex\u00e9cute en production, il existe un intervalle \u2014 un intervalle o\u00f9 la falsification, la substitution ou la corruption silencieuse peuvent survenir sans que personne ne s&rsquo;en aper\u00e7oive.<\/p>\n<p>Il ne s&rsquo;agit pas d&rsquo;une pr\u00e9occupation th\u00e9orique. L&rsquo;attaque <strong>SolarWinds<\/strong> en 2020 a d\u00e9montr\u00e9 comment des adversaires pouvaient injecter du code malveillant dans un processus de build, produisant des artefacts sign\u00e9s mais compromis qui se sont propag\u00e9s \u00e0 des milliers d&rsquo;organisations. La br\u00e8che <strong>Codecov<\/strong> en 2021 a montr\u00e9 comment un script CI falsifi\u00e9 pouvait exfiltrer des secrets de chaque d\u00e9p\u00f4t l&rsquo;utilisant. Dans les deux cas, la supply chain \u2014 l&rsquo;infrastructure entre le code et le d\u00e9ploiement \u2014 constituait la surface d&rsquo;attaque.<\/p>\n<p>La signature des artefacts r\u00e9pond \u00e0 une pi\u00e8ce critique de ce puzzle : <strong>l&rsquo;authenticit\u00e9 et l&rsquo;int\u00e9grit\u00e9<\/strong>. En signant cryptographiquement une image container, vous cr\u00e9ez un lien v\u00e9rifiable entre l&rsquo;image et l&rsquo;identit\u00e9 (personne, \u00e9quipe ou syst\u00e8me CI) qui l&rsquo;a produite. Les consommateurs de cette image peuvent alors v\u00e9rifier la signature avant de l&rsquo;ex\u00e9cuter, s&rsquo;assurant qu&rsquo;elle n&rsquo;a pas \u00e9t\u00e9 modifi\u00e9e depuis sa construction.<\/p>\n<p>Pendant des ann\u00e9es, la signature \u00e9tait impraticable dans la plupart des organisations. La gestion des cl\u00e9s GPG \u00e9tait fastidieuse, la distribution des cl\u00e9s \u00e9tait fragile, et l&rsquo;outillage n\u00e9cessitait une expertise cryptographique approfondie. <strong>Sigstore<\/strong> a chang\u00e9 la donne. Il a introduit une suite d&rsquo;outils open-source qui rendent la signature et la v\u00e9rification accessibles, automatis\u00e9es et \u2014 point crucial \u2014 sans cl\u00e9 (keyless).<\/p>\n<p>Ce guide parcourt l&rsquo;\u00e9cosyst\u00e8me Sigstore, vous montre comment signer et v\u00e9rifier des images container avec <strong>Cosign<\/strong>, int\u00e9grer la signature dans les pipelines CI\/CD, et attacher des attestations et des SBOMs. \u00c0 la fin, vous aurez une compr\u00e9hension pratique de la fa\u00e7on d&rsquo;int\u00e9grer la signature des artefacts comme partie standard de votre processus de livraison.<\/p>\n<h2>Qu&rsquo;est-ce que Sigstore ?<\/h2>\n<p>Sigstore est un projet open-source sous la Linux Foundation qui fournit des outils gratuits, transparents et faciles \u00e0 utiliser pour signer, v\u00e9rifier et prot\u00e9ger les artefacts logiciels. Il a \u00e9t\u00e9 cr\u00e9\u00e9 pour r\u00e9soudre un probl\u00e8me sp\u00e9cifique : rendre la signature cryptographique pratique pour l&rsquo;\u00e9cosyst\u00e8me open-source et au-del\u00e0.<\/p>\n<p>L&rsquo;\u00e9cosyst\u00e8me Sigstore se compose de trois composants fondamentaux :<\/p>\n<h3>Cosign<\/h3>\n<p><strong>Cosign<\/strong> est l&rsquo;outil c\u00f4t\u00e9 client pour signer et v\u00e9rifier les images container et autres artefacts OCI. C&rsquo;est ce avec quoi les d\u00e9veloppeurs et les pipelines CI\/CD interagissent directement. Cosign prend en charge \u00e0 la fois la signature traditionnelle par paire de cl\u00e9s et le nouveau flux de signature keyless.<\/p>\n<h3>Fulcio<\/h3>\n<p><strong>Fulcio<\/strong> est une autorit\u00e9 de certification (CA) gratuite qui \u00e9met des certificats \u00e0 courte dur\u00e9e de vie bas\u00e9s sur une identit\u00e9 OpenID Connect (OIDC). Lorsque vous utilisez la signature keyless, Fulcio v\u00e9rifie votre identit\u00e9 via un fournisseur OIDC (tel que Google, GitHub ou Microsoft) et \u00e9met un certificat qui lie votre identit\u00e9 \u00e0 une cl\u00e9 de signature. Le certificat n&rsquo;est valide que quelques minutes \u2014 suffisamment longtemps pour signer un artefact, mais assez court pour que la compromission de cl\u00e9 ne soit pas un risque persistant.<\/p>\n<h3>Rekor<\/h3>\n<p><strong>Rekor<\/strong> est un log de transparence \u2014 un registre immuable, en ajout seul, qui enregistre les \u00e9v\u00e9nements de signature. Chaque fois qu&rsquo;un artefact est sign\u00e9, un enregistrement est ajout\u00e9 \u00e0 Rekor. Cela fournit une piste publique et auditable de qui a sign\u00e9 quoi et quand. C&rsquo;est conceptuellement similaire aux logs de Certificate Transparency utilis\u00e9s dans l&rsquo;\u00e9cosyst\u00e8me TLS.<\/p>\n<h3>En quoi la signature keyless diff\u00e8re de GPG<\/h3>\n<p>La signature traditionnelle bas\u00e9e sur GPG vous oblige \u00e0 g\u00e9n\u00e9rer une paire de cl\u00e9s \u00e0 longue dur\u00e9e de vie, prot\u00e9ger la cl\u00e9 priv\u00e9e, distribuer la cl\u00e9 publique, et g\u00e9rer la rotation et la r\u00e9vocation des cl\u00e9s. C&rsquo;est op\u00e9rationnellement lourd et sujet aux erreurs, c&rsquo;est pourquoi la plupart des projets n&rsquo;ont jamais adopt\u00e9 la signature.<\/p>\n<p>La signature keyless de Sigstore \u00e9limine cette charge :<\/p>\n<ul>\n<li><strong>Pas de cl\u00e9s \u00e0 longue dur\u00e9e de vie<\/strong> \u2014 Les cl\u00e9s de signature sont \u00e9ph\u00e9m\u00e8res. Elles n&rsquo;existent que pendant la dur\u00e9e de l&rsquo;op\u00e9ration de signature.<\/li>\n<li><strong>Confiance bas\u00e9e sur l&rsquo;identit\u00e9<\/strong> \u2014 Au lieu de faire confiance \u00e0 une cl\u00e9, vous faites confiance \u00e0 une identit\u00e9 (par exemple, un workflow GitHub Actions, une adresse e-mail sp\u00e9cifique). Fulcio lie l&rsquo;identit\u00e9 \u00e0 la cl\u00e9 \u00e9ph\u00e9m\u00e8re via un certificat \u00e0 courte dur\u00e9e de vie.<\/li>\n<li><strong>Transparence par d\u00e9faut<\/strong> \u2014 Chaque \u00e9v\u00e9nement de signature est enregistr\u00e9 dans Rekor, cr\u00e9ant un enregistrement auditable sans n\u00e9cessiter l&rsquo;exploitation de votre propre infrastructure.<\/li>\n<li><strong>Pas de probl\u00e8me de distribution de cl\u00e9s<\/strong> \u2014 Les v\u00e9rificateurs n&rsquo;ont pas besoin d&rsquo;obtenir une cl\u00e9 publique par un canal s\u00e9par\u00e9. Ils v\u00e9rifient par rapport \u00e0 l&rsquo;identit\u00e9 et au log de transparence.<\/li>\n<\/ul>\n<h2>Signer des images container avec Cosign<\/h2>\n<h3>Installation de Cosign<\/h3>\n<p>Cosign est distribu\u00e9 sous forme de binaire unique. Vous pouvez l&rsquo;installer sur la plupart des plateformes :<\/p>\n<pre><code># macOS (Homebrew)\nbrew install cosign\n\n# Linux (Go install)\ngo install github.com\/sigstore\/cosign\/v2\/cmd\/cosign@latest\n\n# Linux (binary release)\ncurl -LO https:\/\/github.com\/sigstore\/cosign\/releases\/latest\/download\/cosign-linux-amd64\nchmod +x cosign-linux-amd64\nsudo mv cosign-linux-amd64 \/usr\/local\/bin\/cosign\n\n# Verify installation\ncosign version<\/code><\/pre>\n<h3>Signature avec une paire de cl\u00e9s<\/h3>\n<p>L&rsquo;approche la plus simple consiste \u00e0 g\u00e9n\u00e9rer une paire de cl\u00e9s et \u00e0 l&rsquo;utiliser pour signer les images. C&rsquo;est utile lorsque vous souhaitez un contr\u00f4le total sur la gestion des cl\u00e9s ou lorsque la signature keyless n&rsquo;est pas disponible dans votre environnement.<\/p>\n<p><strong>\u00c9tape 1 : G\u00e9n\u00e9rer une paire de cl\u00e9s<\/strong><\/p>\n<pre><code>cosign generate-key-pair<\/code><\/pre>\n<p>Cela cr\u00e9e deux fichiers : <code>cosign.key<\/code> (cl\u00e9 priv\u00e9e, prot\u00e9g\u00e9e par mot de passe) et <code>cosign.pub<\/code> (cl\u00e9 publique). Stockez la cl\u00e9 priv\u00e9e en lieu s\u00fbr \u2014 dans un gestionnaire de secrets, un HSM ou un coffre-fort chiffr\u00e9.<\/p>\n<p><strong>\u00c9tape 2 : Signer une image container<\/strong><\/p>\n<pre><code># Signer une image par son digest (toujours pr\u00e9f\u00e9rer le digest au tag)\ncosign sign --key cosign.key ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Cosign vous demandera le mot de passe de la cl\u00e9 priv\u00e9e, g\u00e9n\u00e9rera une signature et la poussera vers le m\u00eame registre OCI \u00e0 c\u00f4t\u00e9 de l&rsquo;image. La signature est stock\u00e9e comme un artefact OCI s\u00e9par\u00e9, tagu\u00e9 selon une convention qui la lie au digest de l&rsquo;image.<\/p>\n<p><strong>Important :<\/strong> Signez toujours par digest, pas par tag. Les tags sont mutables \u2014 quelqu&rsquo;un pourrait d\u00e9placer un tag pour pointer vers une image diff\u00e9rente apr\u00e8s la signature. Les digests sont adress\u00e9s par contenu et immuables.<\/p>\n<h3>Signature keyless avec identit\u00e9 OIDC<\/h3>\n<p>La signature keyless est l&rsquo;approche recommand\u00e9e pour les pipelines CI\/CD. Elle supprime enti\u00e8rement la n\u00e9cessit\u00e9 de g\u00e9rer des cl\u00e9s de signature.<\/p>\n<pre><code># Signature keyless (interactive \u2014 ouvre le navigateur pour la connexion OIDC)\ncosign sign ghcr.io\/myorg\/myapp@sha256:abc123...\n\n# Signature keyless (non interactive, pour CI\/CD)\n# Le flag --yes ignore l'invite de confirmation\ncosign sign --yes ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Dans un environnement CI\/CD comme GitHub Actions, Cosign d\u00e9tecte automatiquement le jeton OIDC ambiant fourni par la plateforme. Aucune interaction navigateur n&rsquo;est n\u00e9cessaire.<\/p>\n<h3>Ce qui se passe en coulisses<\/h3>\n<p>Lorsque vous ex\u00e9cutez <code>cosign sign --yes<\/code> en mode keyless, la s\u00e9quence suivante se produit :<\/p>\n<ol>\n<li><strong>G\u00e9n\u00e9ration de cl\u00e9 \u00e9ph\u00e9m\u00e8re<\/strong> \u2014 Cosign g\u00e9n\u00e8re une paire de cl\u00e9s temporaire en m\u00e9moire.<\/li>\n<li><strong>Authentification OIDC<\/strong> \u2014 Cosign obtient un jeton d&rsquo;identit\u00e9 OIDC depuis l&rsquo;environnement (par exemple, le fournisseur OIDC de GitHub Actions) ou vous invite \u00e0 vous authentifier via un navigateur.<\/li>\n<li><strong>\u00c9mission du certificat<\/strong> \u2014 Cosign envoie la cl\u00e9 publique et le jeton OIDC \u00e0 <strong>Fulcio<\/strong>. Fulcio v\u00e9rifie le jeton, extrait l&rsquo;identit\u00e9 (e-mail, URI du workflow, etc.) et \u00e9met un certificat X.509 \u00e0 courte dur\u00e9e de vie liant l&rsquo;identit\u00e9 \u00e0 la cl\u00e9 publique.<\/li>\n<li><strong>Signature<\/strong> \u2014 Cosign signe le digest de l&rsquo;image en utilisant la cl\u00e9 priv\u00e9e \u00e9ph\u00e9m\u00e8re.<\/li>\n<li><strong>Journalisation de transparence<\/strong> \u2014 La signature, le certificat et le digest de l&rsquo;image sont enregistr\u00e9s dans <strong>Rekor<\/strong>. Cette entr\u00e9e est horodat\u00e9e et immuable.<\/li>\n<li><strong>T\u00e9l\u00e9versement de la signature<\/strong> \u2014 La signature est pouss\u00e9e vers le registre OCI en tant qu&rsquo;artefact compagnon.<\/li>\n<li><strong>Destruction de la cl\u00e9<\/strong> \u2014 La cl\u00e9 priv\u00e9e \u00e9ph\u00e9m\u00e8re est supprim\u00e9e. Elle n&rsquo;est jamais stock\u00e9e nulle part.<\/li>\n<\/ol>\n<p>Le r\u00e9sultat est une image sign\u00e9e avec une cha\u00eene v\u00e9rifiable : le log Rekor prouve que la signature a \u00e9t\u00e9 cr\u00e9\u00e9e \u00e0 un moment pr\u00e9cis par une identit\u00e9 sp\u00e9cifique, et le certificat Fulcio prouve que l&rsquo;identit\u00e9 a \u00e9t\u00e9 authentifi\u00e9e au moment de la signature.<\/p>\n<h2>V\u00e9rification des signatures<\/h2>\n<p>La signature n&rsquo;est utile que si les consommateurs v\u00e9rifient. Cosign fournit des commandes de v\u00e9rification simples pour les sc\u00e9narios bas\u00e9s sur des cl\u00e9s et keyless.<\/p>\n<h3>V\u00e9rification avec une cl\u00e9 publique<\/h3>\n<p>Si l&rsquo;image a \u00e9t\u00e9 sign\u00e9e avec une paire de cl\u00e9s, v\u00e9rifiez en utilisant la cl\u00e9 publique :<\/p>\n<pre><code>cosign verify --key cosign.pub ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Cosign r\u00e9cup\u00e8re la signature depuis le registre OCI, la v\u00e9rifie par rapport \u00e0 la cl\u00e9 publique et affiche le r\u00e9sultat. Si la signature est valide, il affiche la charge utile de signature. Sinon, il se termine avec une erreur.<\/p>\n<h3>V\u00e9rification keyless<\/h3>\n<p>Pour les images sign\u00e9es en mode keyless, la v\u00e9rification est bas\u00e9e sur l&rsquo;identit\u00e9 plut\u00f4t que sur une cl\u00e9. Vous sp\u00e9cifiez <em>qui<\/em> vous vous attendez \u00e0 avoir sign\u00e9 l&rsquo;image :<\/p>\n<pre><code># V\u00e9rifier qu'un workflow GitHub Actions sp\u00e9cifique a sign\u00e9 l'image\ncosign verify \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Cette commande v\u00e9rifie que :<\/p>\n<ul>\n<li>L&rsquo;image poss\u00e8de une signature valide.<\/li>\n<li>Le certificat de signature a \u00e9t\u00e9 \u00e9mis par Fulcio.<\/li>\n<li>L&rsquo;identit\u00e9 dans le certificat correspond au <code>--certificate-identity<\/code> sp\u00e9cifi\u00e9.<\/li>\n<li>L&rsquo;\u00e9metteur OIDC correspond au <code>--certificate-oidc-issuer<\/code>.<\/li>\n<li>L&rsquo;\u00e9v\u00e9nement de signature est enregistr\u00e9 dans le log de transparence Rekor.<\/li>\n<\/ul>\n<p>Vous pouvez \u00e9galement utiliser la correspondance par expression r\u00e9guli\u00e8re pour des politiques plus flexibles :<\/p>\n<pre><code>cosign verify \\\n  --certificate-identity-regexp \"https:\/\/github.com\/myorg\/.*\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h3>Application de la v\u00e9rification dans les contr\u00f4leurs d&rsquo;admission<\/h3>\n<p>La v\u00e9rification manuelle est utile pour le d\u00e9bogage, mais les environnements de production n\u00e9cessitent une application automatis\u00e9e. Les contr\u00f4leurs d&rsquo;admission Kubernetes peuvent rejeter toute image qui ne poss\u00e8de pas de signature valide.<\/p>\n<p><strong>Kyverno<\/strong> est un moteur de politiques populaire avec une prise en charge int\u00e9gr\u00e9e de la v\u00e9rification Cosign :<\/p>\n<pre><code>apiVersion: kyverno.io\/v1\nkind: ClusterPolicy\nmetadata:\n  name: verify-image-signatures\nspec:\n  validationFailureAction: Enforce\n  background: false\n  rules:\n    - name: verify-cosign-signature\n      match:\n        any:\n          - resources:\n              kinds:\n                - Pod\n      verifyImages:\n        - imageReferences:\n            - \"ghcr.io\/myorg\/*\"\n          attestors:\n            - entries:\n                - keyless:\n                    subject: \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\"\n                    issuer: \"https:\/\/token.actions.githubusercontent.com\"\n                    rekor:\n                      url: https:\/\/rekor.sigstore.dev<\/code><\/pre>\n<p>Le <strong>Sigstore Policy Controller<\/strong> (anciennement Cosign Policy Webhook) fournit une fonctionnalit\u00e9 similaire avec une approche native Sigstore :<\/p>\n<pre><code>apiVersion: policy.sigstore.dev\/v1beta1\nkind: ClusterImagePolicy\nmetadata:\n  name: require-signed-images\nspec:\n  images:\n    - glob: \"ghcr.io\/myorg\/**\"\n  authorities:\n    - keyless:\n        identities:\n          - issuer: \"https:\/\/token.actions.githubusercontent.com\"\n            subject: \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\"\n        ctlog:\n          url: https:\/\/rekor.sigstore.dev<\/code><\/pre>\n<p>Avec l&rsquo;une ou l&rsquo;autre approche, tout pod qui r\u00e9f\u00e9rence une image non sign\u00e9e (ou incorrectement sign\u00e9e) de votre registre sera rejet\u00e9 au moment de l&rsquo;admission.<\/p>\n<h2>Int\u00e9gration de la signature dans les pipelines CI\/CD<\/h2>\n<h3>GitHub Actions avec signature keyless<\/h3>\n<p>GitHub Actions dispose d&rsquo;un support OIDC natif, ce qui en fait l&rsquo;environnement id\u00e9al pour la signature keyless. Voici un workflow complet qui construit, pousse et signe une image container :<\/p>\n<pre><code>name: Build and Sign Container Image\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n  packages: write\n  id-token: write  # Required for keyless signing\n\njobs:\n  build-sign:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker\/setup-buildx-action@v3\n\n      - name: Log in to GHCR\n        uses: docker\/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Build and push image\n        id: build\n        uses: docker\/build-push-action@v6\n        with:\n          push: true\n          tags: ghcr.io\/${{ github.repository }}:${{ github.sha }}\n\n      - name: Install Cosign\n        uses: sigstore\/cosign-installer@v3\n\n      - name: Sign the image\n        env:\n          DIGEST: ${{ steps.build.outputs.digest }}\n        run: |\n          cosign sign --yes \\\n            ghcr.io\/${{ github.repository }}@${DIGEST}<\/code><\/pre>\n<p>Points cl\u00e9s :<\/p>\n<ul>\n<li>La permission <code>id-token: write<\/code> active le fournisseur OIDC de GitHub Actions, que Cosign utilise pour la signature keyless.<\/li>\n<li>L&rsquo;image est sign\u00e9e par <strong>digest<\/strong>, pas par tag, en utilisant la sortie de l&rsquo;\u00e9tape de build.<\/li>\n<li>Aucun secret ni cl\u00e9 n&rsquo;est n\u00e9cessaire \u2014 le jeton OIDC de GitHub est l&rsquo;identit\u00e9.<\/li>\n<\/ul>\n<h3>Exemple GitLab CI<\/h3>\n<p>GitLab CI prend \u00e9galement en charge les jetons OIDC pour la signature keyless. L&rsquo;approche est similaire mais utilise le m\u00e9canisme de jeton d&rsquo;identit\u00e9 de GitLab :<\/p>\n<pre><code>stages:\n  - build\n  - sign\n\nvariables:\n  IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}\n\nbuild:\n  stage: build\n  image: docker:24\n  services:\n    - docker:24-dind\n  script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker build -t $IMAGE .\n    - docker push $IMAGE\n    - echo \"DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $IMAGE | cut -d@ -f2)\" &gt;&gt; build.env\n  artifacts:\n    reports:\n      dotenv: build.env\n\nsign:\n  stage: sign\n  image: alpine:3.19\n  id_tokens:\n    SIGSTORE_ID_TOKEN:\n      aud: sigstore\n  before_script:\n    - apk add --no-cache cosign\n  script:\n    - cosign sign --yes ${CI_REGISTRY_IMAGE}@${DIGEST}<\/code><\/pre>\n<p>Le bloc <code>id_tokens<\/code> indique \u00e0 GitLab de g\u00e9n\u00e9rer un jeton OIDC avec l&rsquo;audience <code>sigstore<\/code>. Cosign r\u00e9cup\u00e8re automatiquement le jeton depuis la variable d&rsquo;environnement <code>SIGSTORE_ID_TOKEN<\/code>.<\/p>\n<h3>Stockage des signatures dans les registres OCI<\/h3>\n<p>Par d\u00e9faut, Cosign stocke les signatures dans le m\u00eame registre OCI que l&rsquo;image sign\u00e9e. La signature est pouss\u00e9e en tant que tag s\u00e9par\u00e9 suivant la convention <code>sha256-&lt;digest&gt;.sig<\/code>. Cela signifie :<\/p>\n<ul>\n<li>Aucune infrastructure suppl\u00e9mentaire n&rsquo;est n\u00e9cessaire pour le stockage des signatures.<\/li>\n<li>Les signatures accompagnent l&rsquo;image lors de la mise en miroir ou de la r\u00e9plication.<\/li>\n<li>La plupart des registres majeurs (GHCR, Docker Hub, ECR, GCR, ACR, Harbor) prennent en charge les artefacts OCI et fonctionnent avec Cosign nativement.<\/li>\n<\/ul>\n<p>Si vous devez stocker les signatures dans un registre diff\u00e9rent (par exemple, un stockage d\u00e9di\u00e9 aux signatures), vous pouvez utiliser la variable d&rsquo;environnement <code>COSIGN_REPOSITORY<\/code> :<\/p>\n<pre><code>export COSIGN_REPOSITORY=ghcr.io\/myorg\/signatures\ncosign sign --yes ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h2>Attestations et rattachement de SBOM<\/h2>\n<p>Les signatures prouvent <em>qui<\/em> a construit une image. Les attestations vont plus loin \u2014 elles prouvent <em>comment<\/em> elle a \u00e9t\u00e9 construite et <em>ce qu&rsquo;elle contient<\/em>. Cosign prend en charge le rattachement de m\u00e9tadonn\u00e9es structur\u00e9es aux images sous forme d&rsquo;attestations in-toto.<\/p>\n<h3>Rattachement de la provenance SLSA avec <code>cosign attest<\/code><\/h3>\n<p>SLSA (Supply-chain Levels for Software Artifacts) d\u00e9crit le processus de build : quelle source a \u00e9t\u00e9 utilis\u00e9e, quel constructeur a \u00e9t\u00e9 ex\u00e9cut\u00e9, quelles \u00e9tapes ont \u00e9t\u00e9 r\u00e9alis\u00e9es. Vous pouvez rattacher une attestation de provenance SLSA \u00e0 une image :<\/p>\n<pre><code># Cr\u00e9er une d\u00e9claration de provenance (exemple simplifi\u00e9)\ncat > provenance.json <<'EOF'\n{\n  \"_type\": \"https:\/\/in-toto.io\/Statement\/v1\",\n  \"subject\": [\n    {\n      \"name\": \"ghcr.io\/myorg\/myapp\",\n      \"digest\": {\n        \"sha256\": \"abc123...\"\n      }\n    }\n  ],\n  \"predicateType\": \"https:\/\/slsa.dev\/provenance\/v1\",\n  \"predicate\": {\n    \"buildDefinition\": {\n      \"buildType\": \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml\",\n      \"resolvedDependencies\": [\n        {\n          \"uri\": \"git+https:\/\/github.com\/myorg\/myapp@refs\/heads\/main\",\n          \"digest\": {\n            \"sha1\": \"def456...\"\n          }\n        }\n      ]\n    },\n    \"runDetails\": {\n      \"builder\": {\n        \"id\": \"https:\/\/github.com\/actions\/runner\"\n      }\n    }\n  }\n}\nEOF\n\n# Attester l'image avec la d\u00e9claration de provenance (keyless)\ncosign attest --yes \\\n  --predicate provenance.json \\\n  --type slsaprovenance \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>En pratique, vous utiliseriez un g\u00e9n\u00e9rateur SLSA (tel que <code>slsa-github-generator<\/code>) pour produire automatiquement la provenance plut\u00f4t que de la r\u00e9diger manuellement.<\/p>\n<h3>Rattachement des SBOMs<\/h3>\n<p>Un Software Bill of Materials (SBOM) liste chaque composant \u00e0 l'int\u00e9rieur de votre image container. Cosign peut rattacher un SBOM \u00e0 une image afin que les consommateurs puissent inspecter son contenu :<\/p>\n<pre><code># G\u00e9n\u00e9rer un SBOM avec Syft\nsyft ghcr.io\/myorg\/myapp@sha256:abc123... -o spdx-json > sbom.spdx.json\n\n# Rattacher le SBOM en tant qu'attestation (approche recommand\u00e9e)\ncosign attest --yes \\\n  --predicate sbom.spdx.json \\\n  --type spdxjson \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Alternativement, vous pouvez utiliser l'ancienne commande <code>cosign attach sbom<\/code>, bien que l'approche par attestation soit pr\u00e9f\u00e9r\u00e9e car elle est sign\u00e9e et v\u00e9rifiable :<\/p>\n<pre><code># Ancienne approche (rattach\u00e9 mais non sign\u00e9)\ncosign attach sbom --sbom sbom.spdx.json \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h3>V\u00e9rification des attestations<\/h3>\n<p>Les consommateurs peuvent v\u00e9rifier les attestations exactement comme les signatures. La commande <code>cosign verify-attestation<\/code> v\u00e9rifie \u00e0 la fois la signature de l'attestation et l'identit\u00e9 du signataire :<\/p>\n<pre><code># V\u00e9rifier l'attestation de provenance SLSA\ncosign verify-attestation \\\n  --type slsaprovenance \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...\n\n# V\u00e9rifier l'attestation SBOM\ncosign verify-attestation \\\n  --type spdxjson \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Vous pouvez \u00e9galement utiliser des moteurs de politiques comme Kyverno pour v\u00e9rifier les attestations au moment de l'admission, garantissant que seules les images avec une provenance ou des SBOMs valides sont d\u00e9ploy\u00e9es sur vos clusters.<\/p>\n<h2>Consid\u00e9rations de s\u00e9curit\u00e9 et compromis<\/h2>\n<p>La signature des artefacts est un outil puissant, mais il est important de comprendre ce contre quoi elle prot\u00e8ge et ce contre quoi elle ne prot\u00e8ge pas.<\/p>\n<h3>Ce contre quoi la signature prot\u00e8ge<\/h3>\n<ul>\n<li><strong>Falsification apr\u00e8s le build<\/strong> \u2014 Si quelqu'un modifie une image apr\u00e8s qu'elle a \u00e9t\u00e9 sign\u00e9e, la signature ne sera plus valide. Cela d\u00e9tecte les compromissions de registre, les attaques de type man-in-the-middle et la corruption accidentelle.<\/li>\n<li><strong>Usurpation d'identit\u00e9<\/strong> \u2014 Avec la signature keyless, l'identit\u00e9 du signataire est cryptographiquement li\u00e9e \u00e0 la signature. Un attaquant ne peut pas forger une signature pr\u00e9tendant provenir de votre pipeline CI sans compromettre le fournisseur OIDC.<\/li>\n<li><strong>R\u00e9pudiation<\/strong> \u2014 Le log de transparence Rekor fournit un enregistrement infalsifiable des \u00e9v\u00e9nements de signature. Les signataires ne peuvent pas nier avoir sign\u00e9 un artefact.<\/li>\n<\/ul>\n<h3>Ce contre quoi la signature ne prot\u00e8ge PAS<\/h3>\n<ul>\n<li><strong>Code source malveillant<\/strong> \u2014 La signature prouve que l'image a \u00e9t\u00e9 construite par un pipeline autoris\u00e9. Elle ne prouve pas que le code source est exempt de vuln\u00e9rabilit\u00e9s ou de portes d\u00e9rob\u00e9es. Un compte d\u00e9veloppeur compromis qui pousse du code malveillant produira une image l\u00e9gitimement sign\u00e9e.<\/li>\n<li><strong>Environnements de build compromis<\/strong> \u2014 Si le runner CI lui-m\u00eame est compromis (comme dans le sc\u00e9nario SolarWinds), l'attaquant peut produire des artefacts sign\u00e9s. La signature prouve l'identit\u00e9, pas l'int\u00e9grit\u00e9 de l'environnement de build.<\/li>\n<li><strong>Vuln\u00e9rabilit\u00e9s dans les d\u00e9pendances<\/strong> \u2014 Une image sign\u00e9e peut toujours contenir des CVE connues. La signature et l'analyse de vuln\u00e9rabilit\u00e9s sont compl\u00e9mentaires, pas substituables.<\/li>\n<li><strong>Contournement de politique<\/strong> \u2014 La signature ne fonctionne que si la v\u00e9rification est appliqu\u00e9e. Si votre contr\u00f4leur d'admission a des exceptions, ou si les \u00e9quipes peuvent d\u00e9ployer sans passer par celui-ci, la signature n'offre aucune protection pour ces chemins.<\/li>\n<\/ul>\n<h3>Hypoth\u00e8ses du mod\u00e8le de confiance<\/h3>\n<p>La signature keyless repose sur plusieurs hypoth\u00e8ses de confiance :<\/p>\n<ul>\n<li><strong>Confiance dans le fournisseur OIDC<\/strong> \u2014 Vous faites confiance \u00e0 GitHub, GitLab ou Google pour authentifier correctement les identit\u00e9s. Une compromission du fournisseur OIDC sape l'ensemble du mod\u00e8le.<\/li>\n<li><strong>Confiance dans Fulcio<\/strong> \u2014 Vous faites confiance \u00e0 l'instance Fulcio de Sigstore pour v\u00e9rifier correctement les jetons OIDC et \u00e9mettre des certificats uniquement aux identit\u00e9s authentifi\u00e9es.<\/li>\n<li><strong>Confiance dans Rekor<\/strong> \u2014 Vous faites confiance au log de transparence pour \u00eatre en ajout seul et infalsifiable. L'instance publique Rekor de Sigstore est op\u00e9r\u00e9e par la communaut\u00e9 ; pour les environnements \u00e0 haute assurance, vous pouvez souhaiter exploiter la v\u00f4tre.<\/li>\n<\/ul>\n<p>Pour les organisations ayant des exigences de conformit\u00e9 strictes, l'exploitation d'une infrastructure Sigstore priv\u00e9e (CA Fulcio priv\u00e9e, log Rekor priv\u00e9) offre un contr\u00f4le total sur la cha\u00eene de confiance.<\/p>\n<h3>Consid\u00e9rations de gestion des cl\u00e9s<\/h3>\n<p>Si vous choisissez la signature par cl\u00e9 au lieu de la signature keyless :<\/p>\n<ul>\n<li>Stockez les cl\u00e9s priv\u00e9es dans un KMS (AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault). Cosign dispose d'un support KMS natif : <code>cosign sign --key awskms:\/\/\/arn:aws:kms:...<\/code><\/li>\n<li>Effectuez la rotation des cl\u00e9s selon un calendrier r\u00e9gulier et disposez d'un plan de r\u00e9vocation.<\/li>\n<li>\u00c9vitez de stocker les cl\u00e9s priv\u00e9es comme secrets CI\/CD \u2014 elles sont g\u00e9n\u00e9ralement journalis\u00e9es, mises en cache et r\u00e9pliqu\u00e9es de mani\u00e8res qui augmentent l'exposition.<\/li>\n<li>Utilisez des cl\u00e9s s\u00e9par\u00e9es pour les diff\u00e9rents environnements (staging vs. production) afin de limiter le rayon d'impact.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>La signature d'images container avec Sigstore et Cosign est l'une des mesures les plus impactantes que vous puissiez prendre pour s\u00e9curiser votre supply chain logicielle. Ce n'est plus difficile, cela ne n\u00e9cessite plus une expertise cryptographique approfondie, et cela ne demande plus une infrastructure complexe de gestion des cl\u00e9s. Avec la signature keyless, un pipeline CI\/CD peut signer chaque image qu'il produit sans aucun secret \u00e0 g\u00e9rer et avec une auditabilit\u00e9 compl\u00e8te via le log de transparence Rekor.<\/p>\n<p>Mais la signature est un <strong>\u00e9l\u00e9ment constitutif<\/strong>, pas une solution miracle. Elle r\u00e9pond \u00e0 la question \u00ab cette image a-t-elle \u00e9t\u00e9 produite par un processus autoris\u00e9 ? \u00bb Elle ne r\u00e9pond pas \u00e0 \u00ab cette image est-elle s\u00fbre \u00e0 ex\u00e9cuter ? \u00bb Une strat\u00e9gie compl\u00e8te de s\u00e9curit\u00e9 de la supply chain combine la signature avec l'analyse de vuln\u00e9rabilit\u00e9s, la g\u00e9n\u00e9ration de SBOM, la provenance SLSA, l'application de politiques \u00e0 l'admission, la surveillance de s\u00e9curit\u00e9 en runtime et des contr\u00f4les d'acc\u00e8s rigoureux sur les d\u00e9p\u00f4ts source et l'infrastructure de build.<\/p>\n<p>Commencez par ajouter <code>cosign sign --yes<\/code> \u00e0 votre pipeline CI\/CD. Puis ajoutez la v\u00e9rification dans votre contr\u00f4leur d'admission. Ensuite, superposez les attestations et les SBOMs. Chaque \u00e9tape r\u00e9duit l'\u00e9cart entre la construction du logiciel et la confiance qu'on lui accorde.<\/p>\n<p>Les outils sont matures, l'\u00e9cosyst\u00e8me est en croissance, et le co\u00fbt de <em>ne pas<\/em> signer devient de plus en plus difficile \u00e0 justifier. La question n'est plus de savoir s'il faut signer vos artefacts \u2014 c'est \u00e0 quelle vitesse vous pouvez en faire la norme.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction : Pourquoi la signature des artefacts est essentielle en CI\/CD Les pipelines modernes de livraison logicielle sont remarquablement efficaces pour construire et livrer du code rapidement. Mais la rapidit\u00e9 sans confiance est un risque. Entre le moment o\u00f9 le code source est commit\u00e9 et celui o\u00f9 une image container s&rsquo;ex\u00e9cute en production, il existe &#8230; <a title=\"Signature et V\u00e9rification des Images Container avec Sigstore et Cosign\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/fr\/ci-cd-security\/signing-verifying-container-images-sigstore-cosign\/\" aria-label=\"En savoir plus sur Signature et V\u00e9rification des Images Container avec Sigstore et Cosign\">Lire la suite<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49,50],"tags":[],"post_folder":[],"class_list":["post-476","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-software-supply-chain"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/comments?post=476"}],"version-history":[{"count":1,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/476\/revisions"}],"predecessor-version":[{"id":495,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/posts\/476\/revisions\/495"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/media?parent=476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/categories?post=476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/tags?post=476"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/fr\/wp-json\/wp\/v2\/post_folder?post=476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}