Aller au contenu

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 :

  1. Vous arrivez à l’accueil avec votre carte d’identité (token OIDC de GitHub, Google, etc.)
  2. L’agent vérifie que votre carte est authentique et que vous êtes bien la personne indiquée
  3. Il vous délivre un badge visiteur valable 10 minutes
  4. Avec ce badge, vous pouvez accéder au bâtiment (signer un artefact)
  5. 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 :

AspectCertificat traditionnelCertificat Fulcio
Durée de validité1 à 3 ans10 minutes
Gestion de la clé privéeVous devez la protéger pendant des annéesDétruite immédiatement après signature
Si la clé est voléeToutes les signatures sont compromisesFenêtre d’attaque de 10 min maximum
RévocationProcessus complexe (CRL, OCSP)Inutile, le certificat expire
Vérification à long termeLe certificat doit rester valideLa 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 :

  1. 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é)
  2. 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.

  3. 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)
  4. 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.

  5. 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.

  6. Enregistrement dans Rekor

    La signature et le certificat sont enregistrés dans Rekor, créant une preuve immuable et horodatée.

Diagramme du flux

Flux de signature keyless avec Fulcio : authentification OIDC, émission du certificat éphémère, signature et enregistrement Rekor

Deux façons d’utiliser Fulcio

Avant d’aller plus loin, clarifiez votre contexte d’utilisation :

ModeQuand l’utiliserCe dont vous avez besoin
Instance publiqueProjets open source, entreprises connectées à InternetRien à déployer, juste utiliser Cosign
Instance privéeEnvironnements air-gapped, confidentialité requise, contrôle totalDé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.

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/main

Extensions OID Sigstore

Fulcio utilise des OID (Object Identifiers) personnalisés pour stocker les métadonnées :

OIDNomContenu
1.3.6.1.4.1.57264.1.1OIDC IssuerURL du provider (GitHub, Google…)
1.3.6.1.4.1.57264.1.2Workflow TriggerÉvénement déclencheur (push, PR…)
1.3.6.1.4.1.57264.1.3Workflow SHACommit SHA du workflow exécuté
1.3.6.1.4.1.57264.1.4Workflow NameNom du workflow GitHub Actions
1.3.6.1.4.1.57264.1.5RepositoryDépôt source (org/repo)
1.3.6.1.4.1.57264.1.6Workflow RefBranche 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

ProviderIssuer URLUsage
GitHub Actionshttps://token.actions.githubusercontent.comCI/CD GitHub
GitLab CIhttps://gitlab.comCI/CD GitLab
Googlehttps://accounts.google.comDéveloppeurs, GCP
Microsofthttps://login.microsoftonline.com/{tenant}Azure DevOps
KubernetesService Account tokensPods K8s

Exemple : signer dans GitHub Actions

.github/workflows/sign.yml
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:abc123

Le 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)

Terminal window
# Cosign ouvre le navigateur pour l'authentification
cosign sign --yes mon-registry/mon-image:tag

Vous vous authentifiez via Google ou GitHub, et recevez un certificat avec votre email.

Vérifier une signature

Terminal window
# Vérification stricte : spécifier l'identité attendue
cosign 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 :

  1. La signature est cryptographiquement valide
  2. Le certificat a été émis par Fulcio (chaîne de confiance)
  3. L’identité dans le certificat correspond exactement
  4. L’issuer OIDC est celui attendu
  5. La signature est enregistrée dans Rekor

Examiner le certificat d’une signature

Terminal window
# Télécharger le certificat
cosign 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 certificat
cosign download signature ghcr.io/mon-org/mon-app@sha256:abc123 | \
jq -r '.Cert' | base64 -d | openssl x509 -text -noout

Dé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

Architecture Sigstore privée : Dex (OIDC), Fulcio (CA) et Rekor (CT Log) communiquant avec les clients

Installation avec Helm

Terminal window
# Ajouter le repo Sigstore
helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
# Créer le namespace
kubectl create namespace sigstore-system
# Installer Fulcio
helm install fulcio sigstore/fulcio \
--namespace sigstore-system \
--values fulcio-values.yaml

Configuration de base (fulcio-values.yaml)

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 TLS
ingress:
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.key

Configurer les clients pour l’instance privée

Les clients doivent pointer vers votre instance au lieu de l’instance publique :

Terminal window
# Variables d'environnement
export COSIGN_FULCIO_URL=https://fulcio.votre-domaine.internal
export COSIGN_REKOR_URL=https://rekor.votre-domaine.internal
export 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 instance
cosign sign --yes mon-registry/mon-image:tag

Pour 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 :

Hiérarchie PKI Sigstore : Root CA offline, Intermediate CA utilisée par Fulcio, certificat end-entity éphémère

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.

Terminal window
# Initialiser le trust root Sigstore
cosign initialize
# Les fichiers sont téléchargés dans ~/.sigstore/root/
ls ~/.sigstore/root/
# targets.json root.json snapshot.json timestamp.json

Pour 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érificationDescriptionAttaque bloquée
Signature du token JWTLe token est signé par le provider OIDCToken forgé
Expiration du tokenLe claim exp n’est pas dépasséReplay avec vieux token
Issuer autoriséL’issuer est dans la liste blancheProvider OIDC malveillant
Audience correcteLe token est destiné à FulcioToken volé d’une autre app
Preuve de possessionLe demandeur possède la clé privéeInterception de la requête

Limites et considérations

LimiteImplicationMitigation
Confiance dans le provider OIDCSi GitHub est compromis, les certificats le sontDiversifier les providers, auditer
Pas de révocationUn certificat émis ne peut être annuléDurée de vie de 10 min limite l’impact
Identité = identité OIDCPas d’anonymat possibleUtiliser des identités de service
Dépendance réseau (public)Nécessite InternetInstance privée pour air-gapped

Bonnes pratiques

  1. Vérifiez toujours l’issuer OIDC

    Ne faites confiance qu’aux providers attendus. Utilisez --certificate-oidc-issuer exact, pas de regexp trop large.

  2. Utilisez des contraintes d’identité strictes

    Spécifiez --certificate-identity avec le chemin exact du workflow, pas juste le repository.

  3. Activez 2FA sur vos comptes OIDC

    La sécurité de Fulcio repose sur celle de votre provider OIDC.

  4. Surveillez les signatures dans Rekor

    Configurez des alertes sur les signatures inattendues depuis vos repositories.

À retenir

ConceptRésumé
Rôle de FulcioConvertit une identité OIDC en certificat X.509
Certificats éphémères10 minutes de validité, clé détruite après signature
Instance publiqueGratuite, prête à l’emploi, pour la majorité des usages
Instance privéePour air-gapped, confidentialité, contrôle total
Extensions OIDLe certificat contient les métadonnées du workflow/repo
VérificationToujours spécifier --certificate-identity et --certificate-oidc-issuer

Pour aller plus loin

Ressources externes