Fulcio : l'autorité de certification de Sigstore
Mise à jour :
Dans l’écosystème Sigstore, Fulcio est l’autorité de certification (CA) qui rend possible la signature sans clé (keyless). Au lieu de gérer vos propres clés cryptographiques, vous prouvez votre identité via un provider OIDC (GitHub, Google, GitLab…) et Fulcio vous délivre un certificat éphémère pour signer vos artefacts.
Qu’est-ce que Fulcio exactement ?
Fulcio est une autorité de certification (CA) spécialisée pour la signature de code. Son rôle : convertir une preuve d’identité OIDC en un certificat X.509 éphémère.
L’analogie du badge temporaire
Imaginez Fulcio comme un bureau de délivrance de badges visiteurs :
- Vous arrivez à l’accueil avec votre carte d’identité (token OIDC de GitHub, Google, etc.)
- L’agent vérifie que votre carte est authentique et que vous êtes bien la personne indiquée
- Il vous délivre un badge visiteur valable 10 minutes
- Avec ce badge, vous pouvez accéder au bâtiment (signer un artefact)
- Après 10 minutes, le badge expire — mais votre visite reste dans le registre (Rekor)
Pourquoi des certificats éphémères ?
La grande innovation de Fulcio est la durée de vie très courte des certificats (10 minutes). Comparé aux certificats traditionnels :
| Aspect | Certificat traditionnel | Certificat Fulcio |
|---|---|---|
| Durée de validité | 1 à 3 ans | 10 minutes |
| Gestion de la clé privée | Vous devez la protéger pendant des années | Détruite immédiatement après signature |
| Si la clé est volée | Toutes les signatures sont compromises | Fenêtre d’attaque de 10 min maximum |
| Révocation | Processus complexe (CRL, OCSP) | Inutile, le certificat expire |
| Vérification à long terme | Le certificat doit rester valide | La preuve Rekor suffit |
La courte durée de vie n’est pas un problème car chaque signature est enregistrée dans Rekor avec un timestamp cryptographique. On peut vérifier indéfiniment que la signature a été faite pendant la validité du certificat.
Comment fonctionne Fulcio
Voici ce qui se passe quand vous signez avec Cosign en mode keyless :
-
Authentification OIDC
Cosign vous redirige vers un provider OIDC (GitHub, Google, etc.). Vous vous authentifiez et recevez un token JWT contenant votre identité.
Token JWT contient :- iss: "https://token.actions.githubusercontent.com" (qui a émis le token)- sub: "repo:mon-org/mon-app:ref:refs/heads/main" (sujet)- email: "workflow@github.com" (identité) -
Génération d’une paire de clés éphémère
Côté client, Cosign génère une paire de clés (publique + privée) qui ne sera utilisée qu’une seule fois.
-
Demande de certificat à Fulcio
Cosign envoie à Fulcio :
- Le token OIDC (preuve d’identité)
- La clé publique (à inclure dans le certificat)
- Une preuve de possession de la clé privée (signature du token)
-
Vérification et émission par Fulcio
Fulcio vérifie :
- Le token OIDC est valide (signature, expiration)
- L’issuer OIDC est dans sa liste autorisée
- La preuve de possession est correcte
Puis il génère un certificat X.509 contenant l’identité extraite du token OIDC.
-
Signature de l’artefact
Cosign utilise la clé privée pour signer l’artefact, puis détruit immédiatement la clé. Le certificat est attaché à la signature.
-
Enregistrement dans Rekor
La signature et le certificat sont enregistrés dans Rekor, créant une preuve immuable et horodatée.
Diagramme du flux
Deux façons d’utiliser Fulcio
Avant d’aller plus loin, clarifiez votre contexte d’utilisation :
| Mode | Quand l’utiliser | Ce dont vous avez besoin |
|---|---|---|
| Instance publique | Projets open source, entreprises connectées à Internet | Rien à déployer, juste utiliser Cosign |
| Instance privée | Environnements air-gapped, confidentialité requise, contrôle total | Déployer Fulcio + Rekor + (optionnel) Dex |
Sigstore opère gratuitement une instance publique accessible à tous sur
fulcio.sigstore.dev. C’est le mode par défaut quand vous utilisez Cosign.
Avantages :
- Rien à installer ni maintenir
- Haute disponibilité, sauvegardé par la communauté
- Compatible GitHub Actions, GitLab CI, Google Cloud Build…
Inconvénients :
- Nécessite une connexion Internet
- Vos signatures sont visibles publiquement dans Rekor
- Vous dépendez de l’infrastructure Sigstore
Pour qui : la majorité des utilisateurs, surtout pour les projets open source.
Vous déployez votre propre stack Sigstore (Fulcio + Rekor + optionnellement Dex comme provider OIDC).
Avantages :
- Fonctionne en environnement air-gapped (déconnecté)
- Signatures et certificats restent privés
- Contrôle total sur les policies et providers OIDC
- Conformité pour les environnements réglementés
Inconvénients :
- Infrastructure à déployer et maintenir
- Gestion de votre propre trust root (PKI)
- Plus complexe à mettre en place
Pour qui : entreprises avec des contraintes de sécurité fortes, défense, finance, ou environnements déconnectés.
Que contient un certificat Fulcio ?
Un certificat Fulcio est un certificat X.509 standard enrichi d’extensions spécifiques contenant les métadonnées de l’identité OIDC.
Exemple de certificat
Certificate: Subject: (vide - l'identité est dans les extensions) Issuer: CN=sigstore-intermediate
Validity: Not Before: Dec 29 10:00:00 2025 UTC Not After: Dec 29 10:10:00 2025 UTC ← 10 minutes !
X509v3 extensions: Subject Alternative Name: email: https://github.com/mon-org/mon-app/.github/workflows/build.yml@refs/heads/main
1.3.6.1.4.1.57264.1.1: ← OIDC Issuer https://token.actions.githubusercontent.com
1.3.6.1.4.1.57264.1.5: ← GitHub Repository mon-org/mon-app
1.3.6.1.4.1.57264.1.6: ← GitHub Workflow Ref refs/heads/mainExtensions OID Sigstore
Fulcio utilise des OID (Object Identifiers) personnalisés pour stocker les métadonnées :
| OID | Nom | Contenu |
|---|---|---|
1.3.6.1.4.1.57264.1.1 | OIDC Issuer | URL du provider (GitHub, Google…) |
1.3.6.1.4.1.57264.1.2 | Workflow Trigger | Événement déclencheur (push, PR…) |
1.3.6.1.4.1.57264.1.3 | Workflow SHA | Commit SHA du workflow exécuté |
1.3.6.1.4.1.57264.1.4 | Workflow Name | Nom du workflow GitHub Actions |
1.3.6.1.4.1.57264.1.5 | Repository | Dépôt source (org/repo) |
1.3.6.1.4.1.57264.1.6 | Workflow Ref | Branche ou tag (refs/heads/main) |
Ces extensions permettent une vérification très précise : vous pouvez exiger qu’une image soit signée par un workflow spécifique, depuis une branche spécifique, d’un dépôt spécifique.
Utiliser l’instance publique
L’instance publique est le mode par défaut. Aucune configuration n’est nécessaire.
Providers OIDC supportés
| Provider | Issuer URL | Usage |
|---|---|---|
| GitHub Actions | https://token.actions.githubusercontent.com | CI/CD GitHub |
| GitLab CI | https://gitlab.com | CI/CD GitLab |
https://accounts.google.com | Développeurs, GCP | |
| Microsoft | https://login.microsoftonline.com/{tenant} | Azure DevOps |
| Kubernetes | Service Account tokens | Pods K8s |
Exemple : signer dans GitHub Actions
name: Build and Sign
on: push: branches: [main]
jobs: sign: runs-on: ubuntu-24.04 permissions: contents: read id-token: write # ← Requis pour obtenir le token OIDC
steps: - uses: actions/checkout@v4
- name: Install Cosign uses: sigstore/cosign-installer@v3
- name: Sign image run: | cosign sign --yes ghcr.io/mon-org/mon-app@sha256:abc123Le token OIDC est automatiquement disponible. Cosign contacte fulcio.sigstore.dev,
obtient un certificat, signe l’image, et enregistre dans Rekor — tout cela en
une commande.
Exemple : signer en local (interactif)
# Cosign ouvre le navigateur pour l'authentificationcosign sign --yes mon-registry/mon-image:tagVous vous authentifiez via Google ou GitHub, et recevez un certificat avec votre email.
Vérifier une signature
# Vérification stricte : spécifier l'identité attenduecosign verify ghcr.io/mon-org/mon-app@sha256:abc123 \ --certificate-identity="https://github.com/mon-org/mon-app/.github/workflows/build.yml@refs/heads/main" \ --certificate-oidc-issuer="https://token.actions.githubusercontent.com"Cette commande vérifie :
- La signature est cryptographiquement valide
- Le certificat a été émis par Fulcio (chaîne de confiance)
- L’identité dans le certificat correspond exactement
- L’issuer OIDC est celui attendu
- La signature est enregistrée dans Rekor
Examiner le certificat d’une signature
# Télécharger le certificatcosign verify ghcr.io/mon-org/mon-app@sha256:abc123 \ --certificate-identity-regexp=".*" \ --certificate-oidc-issuer-regexp=".*" \ 2>/dev/null | jq -r '.[0].optional.Bundle.Payload.body' | base64 -d | jq .
# Ou extraire et décoder le certificatcosign download signature ghcr.io/mon-org/mon-app@sha256:abc123 | \ jq -r '.Cert' | base64 -d | openssl x509 -text -nooutDéployer une instance privée
Pour les environnements déconnectés ou nécessitant confidentialité, déployez votre propre Fulcio.
Architecture d’une instance privée
Installation avec Helm
# Ajouter le repo Sigstorehelm repo add sigstore https://sigstore.github.io/helm-chartshelm repo update
# Créer le namespacekubectl create namespace sigstore-system
# Installer Fulciohelm install fulcio sigstore/fulcio \ --namespace sigstore-system \ --values fulcio-values.yamlConfiguration de base (fulcio-values.yaml)
server: # Providers OIDC autorisés # Chaque provider doit être explicitement listé oidcIssuers: # Provider interne (Dex) - issuer: "https://dex.votre-domaine.internal" clientID: "sigstore" type: "email"
# Ou un provider externe - issuer: "https://keycloak.votre-domaine.internal/realms/sigstore" clientID: "fulcio" type: "email"
# Configuration du CT log (Certificate Transparency)ctlog: enabled: true publicURL: "https://ctlog.votre-domaine.internal"
# Configuration TLSingress: enabled: true className: nginx hosts: - host: fulcio.votre-domaine.internal paths: - path: / pathType: Prefix tls: - secretName: fulcio-tls hosts: - fulcio.votre-domaine.internal
# CA configuration# Option 1 : générer une CA (dev/test)createCA: true
# Option 2 : utiliser votre propre CA (production)# createCA: false# ca:# secretName: fulcio-ca-secret# certKey: ca.crt# privateKeyKey: ca.keyConfigurer les clients pour l’instance privée
Les clients doivent pointer vers votre instance au lieu de l’instance publique :
# Variables d'environnementexport COSIGN_FULCIO_URL=https://fulcio.votre-domaine.internalexport COSIGN_REKOR_URL=https://rekor.votre-domaine.internalexport COSIGN_OIDC_ISSUER=https://dex.votre-domaine.internal
# Trust root personnalisé (si vous avez votre propre CA)export SIGSTORE_ROOT_FILE=/path/to/your/root.json
# Signer avec votre instancecosign sign --yes mon-registry/mon-image:tagPour une configuration permanente, créez un fichier de trust root TUF.
Chaîne de confiance et Trust Root
Architecture PKI de Sigstore
Fulcio s’inscrit dans une hiérarchie PKI :
Distribution via TUF
Les métadonnées de confiance (clés publiques, certificats racine) sont distribuées via TUF (The Update Framework), un protocole sécurisé contre les attaques de rollback et de compromission partielle.
# Initialiser le trust root Sigstorecosign initialize
# Les fichiers sont téléchargés dans ~/.sigstore/root/ls ~/.sigstore/root/# targets.json root.json snapshot.json timestamp.jsonPour une instance privée, vous devez créer et distribuer votre propre trust root TUF.
Sécurité de Fulcio
Ce que Fulcio vérifie
Avant d’émettre un certificat, Fulcio effectue ces vérifications :
| Vérification | Description | Attaque bloquée |
|---|---|---|
| Signature du token JWT | Le token est signé par le provider OIDC | Token forgé |
| Expiration du token | Le claim exp n’est pas dépassé | Replay avec vieux token |
| Issuer autorisé | L’issuer est dans la liste blanche | Provider OIDC malveillant |
| Audience correcte | Le token est destiné à Fulcio | Token volé d’une autre app |
| Preuve de possession | Le demandeur possède la clé privée | Interception de la requête |
Limites et considérations
| Limite | Implication | Mitigation |
|---|---|---|
| Confiance dans le provider OIDC | Si GitHub est compromis, les certificats le sont | Diversifier les providers, auditer |
| Pas de révocation | Un certificat émis ne peut être annulé | Durée de vie de 10 min limite l’impact |
| Identité = identité OIDC | Pas d’anonymat possible | Utiliser des identités de service |
| Dépendance réseau (public) | Nécessite Internet | Instance privée pour air-gapped |
Bonnes pratiques
-
Vérifiez toujours l’issuer OIDC
Ne faites confiance qu’aux providers attendus. Utilisez
--certificate-oidc-issuerexact, pas de regexp trop large. -
Utilisez des contraintes d’identité strictes
Spécifiez
--certificate-identityavec le chemin exact du workflow, pas juste le repository. -
Activez 2FA sur vos comptes OIDC
La sécurité de Fulcio repose sur celle de votre provider OIDC.
-
Surveillez les signatures dans Rekor
Configurez des alertes sur les signatures inattendues depuis vos repositories.
À retenir
| Concept | Résumé |
|---|---|
| Rôle de Fulcio | Convertit une identité OIDC en certificat X.509 |
| Certificats éphémères | 10 minutes de validité, clé détruite après signature |
| Instance publique | Gratuite, prête à l’emploi, pour la majorité des usages |
| Instance privée | Pour air-gapped, confidentialité, contrôle total |
| Extensions OID | Le certificat contient les métadonnées du workflow/repo |
| Vérification | Toujours spécifier --certificate-identity et --certificate-oidc-issuer |