Technical Guide Advanced 13 min read

Sigstore : signature keyless pour les chaînes d'approvisionnement logicielles

Sigstore est un projet OpenSSF qui permet aux développeurs et aux pipelines CI de signer des artefacts logiciels sans avoir à gérer de clés privées à longue durée de vie. Il remplace les clés de signature enfouies dans des HSM et des coffres CI par une identité OIDC et des certificats à courte durée de vie. Ce guide couvre Fulcio, Rekor, Cosign, Gitsign et la mise en œuvre de la signature keyless en production.

En bref

Type
Technical Guide
Niveau
Advanced
Suivant
Certificate Transparency

Vue d'ensemble

Sigstore est un projet OpenSSF qui permet aux développeurs et aux pipelines CI de signer des artefacts sans gérer de clés privées à longue durée de vie. Il repose sur un petit ensemble de composants : Fulcio (l'autorité de certification), Rekor (le journal de transparence), Cosign (la CLI utilisée pour signer conteneurs, blobs et attestations) et Gitsign (pour les commits Git). Les quatre sont pensés pour être exploités comme un service, soit via l'instance publique Sigstore, soit dans un déploiement privé.

Toute l'astuce tient dans l'identité. Plutôt que de lier une signature à une clé qu'un utilisateur détient et protège pendant des années, Sigstore la lie à une identité OIDC — un workflow GitHub Actions, un compte Google, un IdP d'entreprise — et émet un certificat X.509 valable une dizaine de minutes. La clé privée éphémère n'a jamais à être stockée, ni renouvelée, ni révoquée : avant même que quiconque puisse tenter d'en abuser, le certificat a déjà expiré.

Ce que l'on vérifie ensuite n'est plus « avez-vous bien protégé votre clé ? », mais « est-ce la bonne identité qui a signé, à un instant que le journal peut prouver ? ». Ce guide explique comment les pièces s'emboîtent, ce que le vérificateur contrôle réellement, en quoi Sigstore change le modèle opérationnel par rapport aux certificats de signature de code traditionnels, et comment il emprunte son modèle d'auditabilité à Certificate Transparency.

Les quatre composants

Depuis vingt ans, la signature de code repose sur le même postulat : un développeur ou un ingénieur de release garde une clé privée, parfois à l'intérieur d'un module matériel de sécurité, parfois dans un coffre CI, et le monde fait confiance à ce que cette clé signe. Le modèle fonctionne, mais il vieillit mal. Les clés fuitent depuis les runners CI, se font subtiliser sur des ordinateurs portables, se retrouvent embarquées par accident dans des images de conteneur, et survivent pendant des années au-delà du moment où l'on aurait raisonnablement pu détecter leur vol. La compromission Solorigate de SolarWinds, les détournements de packages npm, les certificats de signature de code Nvidia fuités et exploités par des malwares — tous ces incidents partagent la même forme : une clé à longue durée de vie, à un endroit où elle n'aurait pas dû être, signant des choses qu'elle n'aurait pas dû signer.

Sigstore prend l'autre voie. Plutôt que de se demander « comment mieux protéger la clé ? », il sort purement et simplement la clé à longue durée de vie de l'équation. Une nouvelle paire de clés est générée pour chaque signature, utilisée une seule fois, puis détruite. Le certificat qui atteste de cette clé éphémère n'est valable qu'une dizaine de minutes : assez pour signer un artefact, pas assez pour en faire quoi que ce soit d'autre. Ce qui rattache la signature à une identité réelle, ce n'est plus la clé — c'est un jeton OIDC émis par un fournisseur d'identité auquel le vérificateur fait déjà confiance.

Le projet appartient à l'écosystème OpenSSF et est exploité à la fois comme un bien public (sigstore.dev fait tourner une instance gratuite et publiquement auditable) et comme un modèle que toute organisation peut réhéberger en interne. Ses quatre composants s'enchaînent dans une séquence qu'il vaut la peine de dérouler de bout en bout.

Le vrai basculement ne porte pas sur ce qui est signé, mais sur ce à quoi l'on fait confiance. Dans la signature de code traditionnelle, le vérificateur fait confiance à un détenteur de clé. Dans Sigstore, il fait confiance à un fournisseur d'identité et à un opérateur de journal. Aucun des deux n'est intrinsèquement meilleur — ce sont simplement des surfaces d'attaque différentes, et pour les artefacts construits en CI le nouveau compromis est en général le bon.

1

S'authentifier via OIDC

Le signataire — un développeur derrière un terminal ou un workload CI tel qu'un job GitHub Actions — obtient un jeton d'identité OIDC auprès d'un fournisseur pris en charge (GitHub OIDC, Google, Microsoft, un IdP d'entreprise fédéré via Dex, etc.). Pour les workflows automatisés, cela se fait de manière implicite, sans aucune intervention humaine.

2

Demander un certificat à Fulcio

Le signataire génère localement une paire de clés éphémère, puis envoie une demande de certificat à Fulcio accompagnée du jeton OIDC. Fulcio vérifie la signature du jeton à l'aide du JWKS du fournisseur, extrait les revendications d'identité, et émet un certificat X.509 qui lie la clé publique à cette identité sous forme d'URI dans le Subject Alternative Name (par exemple `https://github.com/org/repo/.github/workflows/release.yml@refs/tags/v1.2.0`). Le certificat est valable une dizaine de minutes.

3

Signer l'artefact avec Cosign

Cosign calcule l'empreinte de l'artefact (une image de conteneur, une tarball, une attestation in-toto), signe cette empreinte avec la clé privée éphémère, et s'arrête. La clé privée n'existe qu'en mémoire et est détruite à la sortie du processus.

4

Publier dans Rekor

La signature, le certificat Fulcio et quelques métadonnées sont ajoutés comme entrée à Rekor, un journal de transparence en arbre de Merkle, immuable et publiquement vérifiable. Rekor renvoie une preuve d'inclusion signée et un horodatage. C'est cet horodatage qui ancre ensuite la confiance dans la signature, car au moment où le vérificateur la consulte, la fenêtre notBefore/notAfter du certificat sera déjà fermée.

5

Le vérificateur contrôle les quatre éléments

Un consommateur de l'artefact remonte plus tard la même chaîne à l'envers : la signature correspond bien à l'empreinte, le certificat se rattache à une racine Fulcio connue, l'identité présente dans le SAN respecte la politique (« seul le workflow de release de ce dépôt, marqué par un tag semver, est autorisé à signer »), et la preuve d'inclusion Rekor montre que l'entrée a été journalisée alors que le certificat était encore valable.

Les composants

Il y a aussi un cinquième élément à mentionner : la racine TUF (The Update Framework) qui distribue les racines de confiance de Sigstore elles-mêmes. Les vérificateurs ne codent pas en dur le certificat racine de Fulcio ou la clé publique de Rekor ; ils les récupèrent via un canal de métadonnées TUF signé, ce qui permet au projet de faire tourner ses racines en toute sécurité. C'est le genre de détail opérationnel qui ne compte que le jour où quelque chose casse, mais il vaut mieux savoir qu'il existe avant ce jour-là.

Fulcio

L'autorité de certification keyless. Fulcio reçoit un jeton OIDC et une CSR, valide la signature et la revendication d'audience du jeton, puis émet un certificat X.509 à courte durée de vie (~10 minutes) dont le Subject Alternative Name encode l'identité vérifiée sous forme d'URI. La racine Fulcio repose sur une clé adossée à un HSM et est publiquement auditable : la racine Fulcio est distribuée via les métadonnées TUF, et chaque certificat émis par Fulcio est enregistré dans un journal CT public pour supervision.

Rekor

Le journal de transparence. Rekor stocke des entrées signées dans un arbre de Merkle en ajout seul, dans le même esprit que Certificate Transparency pour le WebPKI. N'importe qui peut récupérer le journal, le rejouer et en vérifier la cohérence. Chaque entrée Rekor est horodatée par le journal lui-même, et la preuve d'inclusion renvoyée au moment de la signature est ce qui permet ensuite au vérificateur d'affirmer « cela a été signé alors que le certificat était actif ».

Cosign

La CLI avec laquelle la plupart des utilisateurs interagissent. Elle signe les images de conteneur par empreinte, des blobs arbitraires, des attestations in-toto et des SBOM. Elle vérifie également l'ensemble de la chaîne de preuve Fulcio + Rekor, avec des politiques strictes sur l'identité signataire et sur l'émetteur qui l'a authentifiée.

Gitsign

L'outil de signature de commits Git. Il se branche sur `git commit -S` en tant que credential helper, exécute le même enchaînement OIDC vers Fulcio vers Rekor, et remplace les clés GPG à longue durée de vie que la plupart des dépôts n'ont jamais réussi à faire tourner.

Sigstore face à la signature de code traditionnelle

Le moyen le plus clair de voir ce que Sigstore change est de placer les deux modèles côte à côte et de regarder comment chaque propriété se déplace.

Aucune des deux colonnes n'est universellement meilleure. La signature de code traditionnelle l'emporte partout où le consommateur doit vérifier la signature hors ligne, des années après son émission, sans pouvoir interroger un journal — chargeurs d'amorçage de systèmes d'exploitation, mises à jour de firmware, équipements de type kiosque. Sigstore l'emporte partout où le consommateur est en ligne, où l'événement de signature est fréquent, et où le lien à l'identité importe plus que la pérennité de la clé.

Signature de code traditionnelleSigstore (keyless)
Détention de la cléClé privée à longue durée de vie sur le poste du développeur, sur un serveur de build ou dans un HSMPaire de clés éphémère générée par signature, détruite quelques secondes plus tard
Lien à l'identitéConfiance à l'humain ou à l'organisation qui détient la cléConfiance à l'identité OIDC authentifiée au moment de la signature
Durée de vie du certificatDe 1 à 3 ans, souvent davantageEnviron 10 minutes
Rayon d'impact d'une compromissionTous les artefacts signés tant que la clé n'est pas renouvelée et révoquéeUn seul événement de signature
AuditabilitéRévocation via CRL ou OCSP, sans trace publique des émissionsJournal Rekor public et en ajout seul pour chaque signature
RévocationIndispensable, complexe, souvent lente à se propagerLargement sans objet — le certificat est déjà expiré
Complexité côté vérificateurVérifier la signature, construire la chaîne, contrôler CRL ou OCSPVérifier la signature, remonter à la racine Fulcio, valider la preuve d'inclusion Rekor, appliquer la politique d'identité
Cas d'usage privilégiéLogiciels distribués, modules noyau, pilotes, firmware signé, installateurs MSIArtefacts construits en CI, images de conteneur, SBOM, attestations in-toto, commits Git

À quoi ressemblent vraiment la signature et la vérification

À noter : l'image est référencée par son empreinte, pas par son tag. Cosign refuse de signer un tag mutable, car tout l'intérêt de la signature est de la rattacher à un artefact immuable et adressable par contenu.

La politique d'identité est l'élément que les opérateurs ratent le plus souvent. Une vérification qui contrôle uniquement « n'importe quel certificat Fulcio » n'a aucune valeur — n'importe quelle personne disposant d'un compte GitHub peut en obtenir un. La politique doit épingler le chemin exact du workflow, le motif de branche ou de tag, et l'émetteur.

Pour les attestations (SBOM, provenance SLSA, scans de vulnérabilité), la surface est la même mais s'appuie sur `cosign verify-attestation` :

Dans un admission controller Kubernetes (par exemple avec le policy-controller de Sigstore ou avec Kyverno), les mêmes contrôles s'exécutent à chaque admission de pod, bloquant les images dont la signature, l'identité ou l'attestation ne satisfait pas la politique du cluster.

# Signer une image de conteneur avec Cosign en mode keyless (comportement par défaut en Cosign v2.x)
cosign sign ghcr.io/example/api@sha256:7f8a...

# Ce que cela fait réellement :
#   1. ouvre un onglet de navigateur vers votre fournisseur OIDC, ou utilise
#      l'OIDC GitHub implicite si l'on est dans un job GitHub Actions
#   2. échange le jeton d'identité avec Fulcio contre un certificat X.509 valable ~10 minutes
#   3. signe l'empreinte de l'image avec une clé éphémère, attestée par ce certificat
#   4. publie la signature + le certificat dans le registre OCI comme un tag séparé
#   5. envoie l'entrée à Rekor et stocke la preuve d'inclusion à côté
# Vérifier en mode keyless en épinglant l'identité et l'émetteur attendus
cosign verify ghcr.io/example/api@sha256:7f8a... \
--certificate-identity-regexp '^https://github\.com/example/api/\.github/workflows/release\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com

# La vérification échoue de manière stricte si :
#   - la signature ne correspond pas à l'empreinte de l'artefact
#   - l'identité ou l'émetteur ne correspondent pas à l'expression régulière de la politique
#   - aucune preuve d'inclusion Rekor valide n'existe
#   - le certificat ne se rattachait pas à une racine Fulcio de confiance
#     au moment enregistré par Rekor
# Vérifier une attestation de provenance SLSA liée au build
cosign verify-attestation \
--type slsaprovenance \
--certificate-identity-regexp '^https://github\.com/example/api/\.github/workflows/release\.yml@refs/tags/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/example/api@sha256:7f8a...
Keyless ne signifie pas « sans cryptographie ». Une paire de clés est toujours générée pour chaque signature — le nom du projet renvoie au fait qu'aucun humain ni aucune machine n'a jamais à stocker une clé privée d'une signature à l'autre. Le modèle de compromission glisse de « quelqu'un a-t-il volé ma clé ? » à « quelqu'un a-t-il trompé mon fournisseur OIDC pour obtenir un jeton sur une identité que je n'avais pas autorisée ? ».

Considérations de production

Épinglez l'identité, pas seulement le certificat

Une vérification Cosign qui omet `--certificate-identity[-regexp]` et `--certificate-oidc-issuer` accepte n'importe quelle signature produite par n'importe quel utilisateur de Sigstore. La vérification doit épingler à la fois l'URL de l'émetteur et le motif d'identité, idéalement jusqu'au fichier de workflow précis, au motif de branche ou de tag, et (pour les fournisseurs OIDC qui les exposent) à l'audience et au type d'événement. Traitez la politique de vérification comme du code, revue et versionnée au même titre que le reste de votre configuration de chaîne d'approvisionnement.

Rekor est public

Chaque signature réalisée contre l'instance publique Sigstore est journalisée dans Rekor — le chemin du workflow, le nom du dépôt, l'e-mail du développeur qui a signé en local. Ces données restent visibles indéfiniment par quiconque peut récupérer le journal. Pour des projets internes, des produits non annoncés ou tout ce dont la simple existence est sensible, l'instance publique n'est pas adaptée. Le même logiciel peut tourner en déploiement privé, où Fulcio, Rekor et la racine TUF sont exploités à l'intérieur de votre propre périmètre.

Confiance à l'instant de signature

Comme le certificat est déjà expiré au moment où l'on vérifie, le vérificateur reconstruit la confiance en combinant deux horodatages : l'instant d'entrée dans Rekor et la fenêtre notBefore/notAfter du certificat. Si l'entrée Rekor a été enregistrée alors que le certificat était valable, la signature est acceptée. Cela signifie que l'intégrité de Rekor est porteuse — si le journal peut être réécrit ou ses horodatages falsifiés, toute la vérification s'effondre. Le journal public est audité par des tiers ; un journal privé n'est digne de confiance que dans la mesure où son opérateur l'est. Prévoyez des témoins indépendants, des répliques hors site et des preuves de cohérence périodiques.

Ce n'est pas un remplacement universel

Sigstore est conçu pour la signature en ligne, fréquente et pilotée par l'identité. Il ne remplace pas la signature de release à longue durée de vie lorsque le vérificateur est hors ligne, que l'artefact vit des années et que la chaîne de confiance doit être contrôlable sans accès réseau — pilotes noyau Windows, firmware UEFI, installateurs MSI distribués sur support physique. Pour ces cas, le bon outil reste un certificat de signature de code à longue durée de vie, adossé à un HSM. Dans la plupart des organisations, la bonne architecture combine les deux chemins, côte à côte, avec une politique claire sur celui que prend chaque artefact.

Le vrai défi, c'est la vérification

Signer avec Cosign tient en une commande et quelques lignes de CI. C'est sur la vérification que l'adoption cale — et c'est là que la valeur de sécurité réside vraiment. Chaque point de consommation compte : l'admission controller Kubernetes qui tire l'image, le registre d'artefacts qui la sert, le gestionnaire de packages qui l'installe, le développeur qui l'exécute en local. Si seuls certains de ces points vérifient, un attaquant cible simplement les autres. Traitez la couverture de vérification comme un indicateur mesurable, pas comme un binaire « nous utilisons Sigstore ».

Inventoriez aussi les certificats à courte durée de vie

La plupart des inventaires de certificats ont été conçus pour des certificats qui vivent plusieurs mois et se renouvellent au calendrier. Sigstore produit des certificats qui vivent quelques minutes et ne se renouvellent jamais, dans des volumes qui peuvent atteindre des millions par jour sur des pipelines chargés. Une démarche de découverte et d'inventaire qui les ignore est aveugle à une part significative de l'activité de signature de l'organisation. L'inventaire doit ingérer Rekor (ou le journal privé) et le corréler avec le chemin de signature à longue durée de vie.

Où Sigstore s'inscrit dans une stratégie de signature plus large

La plupart des entreprises ne choisiront pas un modèle au détriment de l'autre. Le tableau réaliste ressemble à ceci :

- Artefacts CI, images de conteneur, SBOM et attestations SLSA, commits Git : keyless via Sigstore, avec des identités épinglées à des workflows précis. Fort volume, fréquent, en ligne — exactement le terrain de jeu de Sigstore. - Binaires publiés à destination des utilisateurs finaux (applications de bureau, agents, pilotes, firmware) : certificats de signature de code à longue durée de vie, adossés à un HSM, encadrés par une politique qui restreint qui peut les demander et comment. - Services internes et identités machines : un mélange entre la gestion automatisée des certificats pour TLS / mTLS et Sigstore pour les artefacts que ces services consomment.

La vraie question de conception n'est pas « Sigstore, oui ou non ? » mais « où passe la frontière, et qui la fait respecter de manière cohérente ? ». C'est davantage une question de CLM et de politique que de Sigstore.

Comment nous aidons

Evertrust & Sigstore : signature keyless pour les chaînes d'approvisionnement logicielles

Émission privée pour les organisations qui ne peuvent pas utiliser l'instance publiquepour les organisations dont les chemins de workflow, les noms de dépôts ou les identités de développeurs ne peuvent pas être exposés dans un journal public, Evertrust PKI fournit l'émission de certificats pilotée par la politique et de niveau audit dont vous avez besoin pour soutenir une infrastructure de signature opérée en interne, en gardant toutes les métadonnées dans votre propre périmètre.

Visibilité unifiée sur les certificats à longue et à courte durée de vieEvertrust CLM maintient un inventaire unique couvrant à la fois les certificats de signature de code à longue durée de vie qui accompagnent les binaires publiés (modules noyau, installateurs, firmware) et les certificats à courte durée de vie produits par Sigstore. Deux modèles opérationnels, une seule source de vérité.

Alignement des politiques entre les chemins de signatureles releases destinées aux utilisateurs finaux passent par le chemin de signature à longue durée de vie avec des clés protégées par HSM, les artefacts CI passent par le keyless. Evertrust impose cette distinction avec le même modèle de gouvernance, d'approbation et d'audit des deux côtés, pour qu'il n'y ait pas deux programmes de sécurité parallèles.