Outils de Signature d’Images Container Comparés : Cosign vs Notation vs GPG

Pourquoi la signature d’images container est essentielle

Chaque fois que vous récupérez une image container et la déployez en production, vous accordez une confiance implicite à cet artefact. Mais comment vérifiez-vous que l’image n’a pas été altérée ? Comment confirmez-vous qu’elle a réellement été construite par votre pipeline CI/CD et non injectée par un attaquant ayant compromis votre registre ?

La signature d’images container résout ce problème en attachant une signature cryptographique à vos images. Avant le déploiement, votre orchestrateur ou contrôleur d’admission peut vérifier cette signature, garantissant que seules des images fiables et authentifiées accèdent à votre environnement. C’est un pilier fondamental de la sécurité de la chaîne d’approvisionnement logicielle et une exigence dans des référentiels tels que SLSA et NIST SSDF.

Cependant, tous les outils de signature ne se valent pas. Les trois approches dominantes aujourd’hui — Cosign (issu du projet Sigstore), Notation (le client Notary v2) et GPG (l’approche traditionnelle) — présentent chacune des compromis radicalement différents en matière de gestion des clés, d’intégration CI/CD et de compatibilité avec l’écosystème.

Dans ce guide, nous réalisons une comparaison approfondie et pratique des trois outils afin de vous aider à faire le bon choix pour vos pipelines.

Cosign et l’écosystème Sigstore

Présentation

Cosign est l’outil de signature d’images container du projet Sigstore, désormais un projet diplômé (graduated) sous la Linux Foundation. La mission de Sigstore est de rendre la signature logicielle omniprésente en supprimant le plus grand obstacle : la gestion des clés.

Cosign stocke les signatures en tant qu’artefacts OCI directement aux côtés de l’image signée dans le même registre. Cela signifie qu’il n’y a aucun système de stockage de signatures séparé à maintenir — votre registre de conteneurs existant (Docker Hub, GitHub Container Registry, AWS ECR, Google Artifact Registry, etc.) remplit cette double fonction.

Signature keyless avec Fulcio et Rekor

La fonctionnalité la plus révolutionnaire de Cosign est la signature keyless. Au lieu de gérer des clés de signature à longue durée de vie, Cosign s’intègre à deux services :

  • Fulcio — Une autorité de certification qui émet des certificats de signature à durée de vie courte basés sur une identité OpenID Connect (OIDC). Dans un contexte CI/CD, il s’agit généralement du jeton d’identité fourni par votre fournisseur de pipeline (GitHub Actions OIDC, GitLab CI OIDC, etc.).
  • Rekor — Un journal de transparence immuable qui enregistre chaque événement de signature. Cela fournit une piste d’audit infalsifiable indiquant qui a signé quoi et quand.

Avec la signature keyless, le flux de travail se déroule ainsi :

  1. Votre pipeline CI demande un jeton OIDC au fournisseur de pipeline.
  2. Cosign présente ce jeton à Fulcio, qui émet un certificat à courte durée de vie liant l’identité du pipeline à une paire de clés éphémère.
  3. Cosign signe le digest de l’image avec la clé privée éphémère.
  4. La signature et le certificat sont enregistrés dans le journal de transparence Rekor.
  5. La clé privée éphémère est supprimée — elle n’a existé que pendant quelques secondes.

Cela élimine toute la catégorie de problèmes liés à la rotation des clés, au stockage des clés et à la compromission des clés. Il n’y a aucun secret à longue durée de vie à protéger.

Signature basée sur des clés

Cosign prend également en charge la signature traditionnelle par paire de clés pour les environnements où le mode keyless n’est pas envisageable (réseaux isolés, exigences réglementaires imposant une garde spécifique des clés). Vous générez une paire de clés avec cosign generate-key-pair et signez avec cosign sign --key cosign.key.

Exemple d’intégration CI/CD : GitHub Actions

# .github/workflows/sign.yml
jobs:
  sign:
    runs-on: ubuntu-latest
    permissions:
      id-token: write   # Required for keyless signing
      packages: write   # Required to push signatures to GHCR
    steps:
      - uses: sigstore/cosign-installer@v3

      - name: Sign the container image (keyless)
        env:
          COSIGN_EXPERIMENTAL: 1
        run: |
          cosign sign --yes ghcr.io/myorg/myapp@sha256:abc123...

      - name: Verify the signature
        run: |
          cosign verify \
            --certificate-oidc-issuer https://token.actions.githubusercontent.com \
            --certificate-identity-regexp https://github.com/myorg/myapp/.github/workflows/* \
            ghcr.io/myorg/myapp@sha256:abc123...

La permission id-token: write est l’élément critique — elle permet à GitHub Actions de générer le jeton OIDC que Fulcio utilise pour émettre le certificat de signature. Aucun secret à configurer, aucune clé à stocker. Pour un tutoriel pratique pas à pas, consultez notre Lab de signature keyless avec Cosign.

Points forts

  • La signature keyless élimine entièrement la gestion des clés en CI/CD
  • Le journal de transparence (Rekor) fournit une piste d’audit immuable
  • Stockage natif en artefact OCI — aucun magasin de signatures externe nécessaire
  • Vérification riche par politique avec correspondance d’identité de certificat
  • Large support de l’écosystème (Kyverno, OPA Gatekeeper, contrôleurs de politiques Kubernetes)
  • Communauté open source active et bien financée

Limitations

  • Le mode keyless nécessite un accès internet à Fulcio et Rekor (contraignant pour les environnements isolés)
  • La vérification en environnement isolé nécessite la mise en miroir du journal de transparence
  • Projet relativement jeune par rapport à GPG (bien que désormais stable et diplômé)

Notation et Notary v2

Présentation

Notation est le client CLI de la spécification Notary v2, un projet CNCF soutenu principalement par Microsoft et AWS. Là où Cosign a été conçu spécifiquement pour l’écosystème Sigstore, Notation a été pensé pour s’intégrer aux infrastructures PKI d’entreprise et aux workflows de certificats X.509 existants.

Notation utilise des signatures COSE (CBOR Object Signing and Encryption) stockées en tant qu’artefacts OCI attachés à l’image signée via la spécification ORAS (OCI Registry As Storage). Comme Cosign, cela signifie que les signatures résident dans le registre OCI aux côtés des images.

Gestion des clés avec des plugins

Notation utilise une architecture de plugins pour la gestion des clés. Au lieu de manipuler les clés directement, il délègue à des plugins qui interfacent avec des coffres-forts de clés externes :

  • Plugin Azure Key Vault — Signe en utilisant des clés stockées dans Azure Key Vault.
  • Plugin AWS Signer — Utilise AWS Signer, un service de signature entièrement managé.
  • Plugin HashiCorp Vault — S’intègre au moteur de secrets de transit de Vault.

Ce modèle de plugins est naturellement adapté aux entreprises disposant déjà d’une gestion centralisée des clés et d’une infrastructure PKI. La clé de signature ne quitte jamais le HSM ou le KMS cloud — Notation envoie le digest au plugin, et le plugin renvoie la signature.

Politiques de confiance et magasins de confiance

Notation utilise un système de politiques de confiance basé sur JSON pour la vérification. Vous définissez quels registres, dépôts et images vous faites confiance, ainsi que les certificats ou chaînes de certificats autorisés à les signer. Ceci est particulièrement puissant pour les scénarios de gouvernance d’entreprise où différentes équipes disposent de différentes autorités de signature.

// trustpolicy.json
{
  "version": "1.0",
  "trustPolicies": [
    {
      "name": "production-images",
      "registryScopes": ["registry.example.com/prod/*"],
      "signatureVerification": {
        "level": "strict"
      },
      "trustStores": ["ca:production-ca"],
      "trustedIdentities": ["x509.subject: CN=prod-signer, O=MyOrg"]
    }
  ]
}

Exemple d’intégration CI/CD : GitHub Actions avec AWS Signer

# .github/workflows/notation-sign.yml
jobs:
  sign:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # For AWS OIDC federation
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/signer-role
          aws-region: us-east-1

      - name: Setup Notation
        uses: notaryproject/notation-action/setup@v1

      - name: Install AWS Signer plugin
        run: |
          notation plugin install \
            --url https://d2hvyiie56hcat.cloudfront.net/linux/amd64/plugin/latest/notation-aws-signer-plugin.zip

      - name: Sign the container image
        run: |
          notation sign \
            --plugin com.amazonaws.signer.notation.plugin \
            --id arn:aws:signer:us-east-1:123456789012:/signing-profiles/MyProfile \
            registry.example.com/myapp@sha256:abc123...

Points forts

  • Architecture de plugins adaptée aux entreprises, s’intégrant aux PKI et KMS existants
  • Cadre riche de politiques de confiance pour une vérification granulaire par registre
  • Le format de signature COSE est un standard IETF bien établi
  • Fort soutien de Microsoft (Azure) et AWS
  • Conçu pour les organisations disposant de workflows de certificats X.509 existants
  • La vérification hors ligne est simple — il suffit de disposer des certificats du magasin de confiance

Limitations

  • Pas de signature keyless — vous devez gérer des certificats et des clés (même si délégués à un KMS)
  • Pas d’équivalent intégré de journal de transparence
  • L’écosystème de plugins est encore en croissance ; moins de plugins que les points d’intégration de Cosign
  • Communauté plus restreinte et moins de tutoriels par rapport à Cosign
  • La configuration des politiques de confiance peut être complexe pour des cas d’usage simples

GPG : l’approche traditionnelle

Présentation

GPG (GNU Privacy Guard) est le vétéran du monde de la signature. Bien avant l’existence des outils de signature natifs pour conteneurs, GPG était utilisé pour signer de tout — des courriels aux commits Git en passant par les paquets Linux. Certaines équipes utilisent encore GPG pour signer des images container, notamment via Docker Content Trust (DCT) ou en signant les manifestes d’images de manière externe (out-of-band).

Fonctionnement de la signature GPG pour les conteneurs

La signature GPG des conteneurs suit généralement l’un de ces deux schémas :

  • Signature out-of-band : Exporter le manifeste ou le digest de l’image, le signer avec gpg --detach-sign, et stocker le fichier .sig aux côtés de l’image (dans un dépôt d’artefacts séparé, un bucket S3 ou un dépôt Git).
  • Intégration Podman/Skopeo : Podman et Skopeo disposent d’un support natif des signatures GPG. Les signatures sont stockées sur un serveur de signatures séparé (un serveur web servant des signatures détachées) et vérifiées au moment du pull à l’aide d’un fichier de politique (/etc/containers/policy.json).

Docker Content Trust (DCT) utilise une approche apparentée mais distincte basée sur The Update Framework (TUF), avec Notary v1 comme backend. Bien que DCT utilise des primitives cryptographiques différentes du GPG brut, il partage le même défi fondamental : la gestion de clés à longue durée de vie.

Défis de la gestion des clés

La plus grande faiblesse de GPG dans un contexte CI/CD est la gestion des clés :

  • Vous devez générer, distribuer, renouveler et révoquer des paires de clés à longue durée de vie
  • Les clés privées doivent être injectées de manière sécurisée dans les runners CI/CD en tant que secrets
  • Il n’existe aucun mécanisme intégré de séquestre ou de récupération de clés
  • La distribution des clés aux vérificateurs (nœuds de cluster, contrôleurs d’admission) nécessite des processus manuels ou un serveur de clés
  • La compromission d’une clé nécessite une rotation d’urgence sur tous les systèmes

Exemple d’intégration CI/CD : GitLab CI avec GPG

# .gitlab-ci.yml
sign-image:
  stage: sign
  image: alpine:latest
  before_script:
    - apk add --no-cache gnupg skopeo
    - echo "$GPG_PRIVATE_KEY" | gpg --batch --import
  script:
    - skopeo copy \
        --sign-by signing-key@myorg.com \
        docker://registry.example.com/myapp:${CI_COMMIT_SHORT_SHA} \
        docker://registry.example.com/myapp:${CI_COMMIT_SHORT_SHA}
  variables:
    GPG_PRIVATE_KEY: $GPG_SIGNING_KEY  # Stored in CI/CD variables

Remarquez comment la clé privée doit être stockée en tant que secret CI/CD et injectée au moment de l’exécution — exactement le type de gestion de secrets à longue durée de vie que la signature keyless a été conçue pour éliminer.

Points forts

  • Cryptographie éprouvée — GPG a été audité et durci pendant des décennies
  • Fonctionne dans des environnements entièrement isolés sans aucune dépendance externe
  • Familier pour les équipes d’exploitation ayant une expérience Linux/sécurité
  • Large support d’outillage dans l’écosystème Podman/Skopeo
  • Contrôle total sur le matériel cryptographique (important pour certains cadres de conformité)

Limitations

  • La gestion manuelle et sujette aux erreurs des clés est le principal fardeau opérationnel
  • Pas de mode keyless — les clés privées doivent résider quelque part accessible au CI/CD
  • Pas de stockage natif en artefact OCI — les signatures sont stockées de manière externe (out-of-band)
  • Pas de journal de transparence pour les pistes d’audit
  • La distribution et la découverte des signatures sont fragmentées
  • Docker/containerd ne vérifient pas nativement les signatures GPG (nécessite Podman/Skopeo ou un outillage personnalisé)

Comparaison côte à côte

Fonctionnalité Cosign (Sigstore) Notation (Notary v2) GPG
Gestion des clés Keyless (OIDC) ou paires de clés statiques Basée sur des plugins (KMS, HSM, coffres-forts cloud) Paires de clés PGP manuelles
Signature keyless Oui (Fulcio + OIDC) Non Non
Format de signature Enveloppe JSON (in-toto/DSSE) Signatures COSE (CBOR) Signatures détachées PGP
Stockage des signatures Registre OCI (en tant qu’artefacts OCI) Registre OCI (via ORAS) Externe (serveur web, S3, Git)
Compatibilité registre OCI Excellente — fonctionne avec tous les registres majeurs Bonne — nécessite le support de l’API OCI 1.1 referrers Aucune — signatures stockées en externe
Journal de transparence Oui (Rekor) Non (prévu) Non
Intégration CI/CD Excellente — GitHub Actions, GitLab CI, Tekton, support OIDC natif Bonne — GitHub Actions, compatible avec tout CI via plugins Manuelle — nécessite l’injection de secrets de clés privées
Politiques Kubernetes Kyverno, OPA Gatekeeper, Sigstore Policy Controller Ratify (avec Gatekeeper), Kyverno (limité) Nécessite un webhook d’admission personnalisé
Support environnement isolé Possible (nécessite miroir TUF root, miroir Rekor) Oui (simple avec un magasin de confiance local) Oui (entièrement utilisable hors ligne)
Écosystème et communauté Large — Linux Foundation, Google, Red Hat, GitHub En croissance — CNCF, Microsoft, AWS Mature mais en déclin pour l’usage container
Courbe d’apprentissage Faible (keyless) à Moyenne (clés avec politiques) Moyenne à Élevée (plugins, politiques de confiance, PKI) Moyenne (outillage familier, opérations pénibles)
Support des attestations Oui (SBOM, provenance SLSA, prédicats personnalisés) Oui (via artefacts attachés ORAS) Pas de support natif

Matrice de décision : quand utiliser quel outil

Le choix du bon outil de signature dépend du contexte de votre organisation. Voici un cadre décisionnel pratique :

Choisissez Cosign si :

  • Vous démarrez de zéro avec la signature de conteneurs et souhaitez le chemin le plus rapide vers la production.
  • Vous utilisez GitHub Actions, GitLab CI ou un autre système CI/CD compatible OIDC — la signature keyless fonctionne immédiatement.
  • Vous souhaitez un journal de transparence pour l’audit et la conformité sans avoir à en construire un vous-même.
  • Vous adoptez les attestations SLSA ou in-toto — Cosign offre un support de premier ordre pour attacher des SBOM et des métadonnées de provenance.
  • Vous souhaitez une large intégration des politiques Kubernetes avec Kyverno ou Sigstore Policy Controller.
  • Vous êtes une startup ou une organisation de taille moyenne sans équipe PKI dédiée.

Pour un guide complet sur Sigstore et la signature keyless, consultez notre Guide de signature keyless Sigstore et Cosign.

Choisissez Notation si :

  • Votre organisation dispose d’une infrastructure PKI existante et de workflows de gestion de certificats X.509 que vous souhaitez exploiter.
  • Vous êtes fortement investi dans Azure ou AWS et souhaitez une intégration native avec Azure Key Vault ou AWS Signer.
  • Vous avez besoin de politiques de confiance granulaires scopées à des registres, dépôts ou équipes spécifiques.
  • Les exigences de conformité imposent une garde spécifique des clés (FIPS 140-2, FedRAMP) où la signature keyless ne satisfait pas aux critères.
  • Vous opérez dans un environnement où l’infrastructure publique Sigstore n’est pas accessible mais vous disposez d’une PKI interne.

Choisissez GPG si :

  • Vous êtes dans un environnement entièrement isolé sans aucune dépendance externe autorisée.
  • Vous utilisez Podman/Skopeo comme runtime de conteneurs principal et disposez déjà d’une infrastructure de clés GPG.
  • Des exigences réglementaires imposent spécifiquement GPG (rare, mais certains contrats gouvernementaux le spécifient).
  • Vous signez des artefacts non-OCI en plus des conteneurs et souhaitez un outil de signature unique.

Pour la plupart des équipes développant des applications cloud-native modernes, Cosign avec la signature keyless est le choix recommandé par défaut. Il offre le meilleur ratio sécurité/complexité opérationnelle et élimine le fardeau de la gestion des clés qui fait échouer la plupart des initiatives de signature en pratique.

Schémas d’intégration CI/CD

Au-delà des exemples individuels ci-dessus, voici des schémas architecturaux pour intégrer la signature dans votre pipeline :

Schéma 1 : Signature à la construction (Cosign Keyless)

Le schéma le plus simple. Le même job de pipeline qui construit et pousse l’image la signe également. La signature keyless signifie qu’aucun secret n’est à gérer :

Build Image → Push to Registry → Cosign Sign (keyless) → Record in Rekor

Cela fonctionne parfaitement avec GitHub Actions, GitLab CI 16.0+ et tout système CI fournissant des jetons OIDC. L’identité OIDC du pipeline devient l’identité de signature, créant une chaîne vérifiable du commit source à l’image signée.

Schéma 2 : Service de signature centralisé (Notation + KMS)

Pour les entreprises souhaitant une séparation des responsabilités, un service de signature centralisé reçoit les artefacts de build et les signe à l’aide de clés stockées dans un KMS :

Build Pipeline → Push to Registry → Request Signing → Notation Sign (KMS plugin) → Approval Workflow

Ce schéma permet des scénarios où l’équipe de build ne peut pas signer directement — une équipe de sécurité distincte ou un moteur de politiques automatisé doit approuver et signer l’artefact. Les politiques d’accès d’AWS Signer et d’Azure Key Vault contrôlent qui peut demander des signatures.

Schéma 3 : Portes de vérification (tout outil)

Quel que soit l’outil de signature utilisé, la vérification est tout aussi importante. Implémentez la vérification à plusieurs points :

  • Porte de pré-déploiement : Un contrôleur d’admission Kubernetes (Kyverno, Gatekeeper + Ratify, Sigstore Policy Controller) rejette les images non signées ou mal signées.
  • Porte de promotion : Avant de promouvoir une image du registre de staging vers celui de production, vérifiez sa signature.
  • Audit en runtime : Analysez périodiquement les charges de travail en cours d’exécution et vérifiez que leurs signatures sont toujours valides par rapport aux politiques de confiance actuelles.

Stratégie multi-outils

Certaines organisations utilisent plusieurs outils. Par exemple, Cosign pour la signature dans les pipelines CI/CD (commodité du keyless) et Notation pour la signature des releases (conformité PKI d’entreprise). Les deux stockent les signatures en tant qu’artefacts OCI, ils peuvent donc coexister sur la même image. Les politiques de vérification peuvent exiger des signatures des deux outils avant d’autoriser le déploiement.

L’avenir de la signature de conteneurs

Le paysage de la signature de conteneurs converge vers plusieurs tendances importantes :

  • OCI 1.1 et l’API Referrers : La spécification de distribution OCI supporte désormais nativement les références d’artefacts, que Cosign et Notation exploitent. Cela standardise la façon dont les signatures, SBOM et attestations s’attachent aux images.
  • Attestations SLSA et in-toto : La signature évolue au-delà de « qui a construit ceci » pour inclure la provenance de build vérifiable, les manifestes de dépendances et les résultats d’analyses de sécurité — le tout signé et attaché à l’image.
  • Policy-as-Code : Des outils comme Kyverno et Gatekeeper permettent d’exprimer des exigences de signature complexes sous forme de politiques déclaratives, réduisant l’écart entre l’intention de sécurité et son application.
  • Adoption de Sigstore : Les écosystèmes majeurs de paquets (npm, PyPI, Maven Central) adoptent Sigstore, ce qui accroît la familiarité et la maturité de l’outillage à travers l’industrie.

Conclusion et recommandation

Les trois outils résolvent le problème fondamental de la vérification de l’authenticité des images container, mais ils répondent à des contextes différents :

  • Cosign est le meilleur choix pour la plupart des équipes. La signature keyless supprime le fardeau opérationnel qui fait échouer les initiatives de signature, le journal de transparence fournit des capacités d’audit prêtes à l’emploi, et l’intégration dans l’écosystème est la plus large. Si vous lancez une nouvelle initiative de signature de conteneurs, commencez ici.
  • Notation est le bon choix pour les entreprises disposant d’une PKI établie et d’exigences de conformité spécifiques en matière de garde des clés. Son modèle de plugins et son cadre de politiques de confiance sont conçus pour les organisations nécessitant une autorité de signature fine et déléguée.
  • GPG devrait être réservé aux environnements legacy, aux systèmes entièrement isolés ou aux workflows natifs Podman où les autres outils ne peuvent véritablement pas être utilisés. Pour les nouveaux déploiements, la charge opérationnelle de la gestion des clés GPG est difficile à justifier.

Le plus important est de commencer à signer. Une implémentation de signature imparfaite qui est réellement mise en production a infiniment plus de valeur qu’une implémentation parfaite qui reste dans une feuille de route. Choisissez l’outil qui correspond aux capacités de votre équipe, implémentez-le dans votre pipeline et ajoutez des portes de vérification dans Kubernetes. Vous pourrez toujours faire évoluer votre outillage par la suite — l’étape critique est d’établir la pratique.

Prêt à passer à la pratique ? Commencez par notre Guide de signature keyless Sigstore pour les fondements conceptuels, puis travaillez sur le Lab de signature keyless Cosign pour l’implémenter dans un vrai pipeline GitHub Actions.