Aller au contenu

Rekor : le log de transparence de Sigstore

Mise à jour :

Rekor est le log de transparence de l’écosystème Sigstore. Il enregistre chaque signature dans un registre public et immuable, permettant de prouver qu’une signature existait à un moment précis, d’auditer les signatures d’une identité, et de détecter les signatures frauduleuses.

Pour comprendre comment Rekor s’intègre dans l’écosystème Sigstore (avec Fulcio et Cosign), consultez le guide Sigstore.

Pourquoi Rekor est essentiel

Avec la signature keyless de Sigstore, vous signez avec un certificat Fulcio qui expire après 10 minutes. Sans Rekor, impossible de prouver que la signature était valide au moment de sa création.

Le problème des certificats éphémères

Rekor résout ce problème en enregistrant la signature au moment de sa création avec un horodatage cryptographique :

La solution Rekor

Propriétés du log

PropriétéDescriptionPourquoi c’est important
ImmuableUne entrée ne peut pas être modifiéeGarantit l’intégrité historique
Append-onlyOn ne peut qu’ajouter, jamais réécrireEmpêche la réécriture de l’historique
VérifiableStructure en arbre de MerklePreuves cryptographiques d’inclusion
PublicTout le monde peut lire et auditerTransparence totale
HorodatéTimestamp RFC3161 sur chaque entréePreuve temporelle incontestable

Comment fonctionne un log de transparence

Rekor utilise un arbre de Merkle : une structure où chaque nœud est le hash de ses enfants. Si vous modifiez une seule entrée, le hash racine change.

Structure d'un arbre de Merkle

Preuve d’inclusion

Pour prouver qu’une entrée existe, il suffit de fournir les hashs intermédiaires qui permettent de recalculer le root hash :

Preuve d'inclusion pour l'entrée B

Cas d’usage concrets

1. Audit de sécurité

Votre entreprise veut auditer toutes les signatures effectuées par ses développeurs sur les 6 derniers mois :

Terminal window
# Rechercher toutes les signatures de l'équipe
rekor-cli search --email "@votre-entreprise.com"

2. Détection de compromission

Vous configurez une alerte qui vous notifie dès qu’une signature est créée avec votre identité. Si vous recevez une alerte pour une signature que vous n’avez pas faite, vous savez que votre compte est compromis.

3. Conformité réglementaire

Le Cyber Resilience Act (CRA) européen exige la traçabilité des artefacts logiciels. Rekor fournit une preuve cryptographique de qui a signé quoi et quand.

4. Incident response

Après un incident de sécurité, vous pouvez retracer l’historique complet des signatures pour identifier le point de compromission.

ScénarioQuestionRéponse de Rekor
AuditQui a signé nos artefacts ce mois-ci ?Liste des signatures par email/hash
CompromissionQuelqu’un a-t-il signé à ma place ?Oui, entrée #12345 le 15/12
ConformitéPreuve de traçabilité ?Inclusion proof + timestamp
IncidentQuand l’image malveillante a-t-elle été signée ?Timestamp précis

Prérequis

Avant de commencer :

  • Connexion Internet : pour accéder à l’instance publique Rekor
  • jq (optionnel) : pour parser les réponses JSON dans vos scripts
Terminal window
# Installer jq si nécessaire
# Debian/Ubuntu
sudo apt install jq
# macOS
brew install jq

Installation de rekor-cli

Terminal window
# Télécharger la dernière version
REKOR_VERSION=$(curl -s https://api.github.com/repos/sigstore/rekor/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -LO "https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}/rekor-cli-linux-amd64"
# Installer
chmod +x rekor-cli-linux-amd64
sudo mv rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
# Vérifier
rekor-cli version

Sortie attendue :

rekor-cli: vX.Y.Z

Interroger le log public

L’instance publique de Rekor est accessible à rekor.sigstore.dev. C’est l’instance utilisée par défaut par Cosign et gitsign. Elle offre un SLA de 99.5% et est utilisée par npm, PyPI, Kubernetes et des milliers de projets open source.

Comprendre les identifiants Rekor

Chaque entrée dans Rekor peut être identifiée de plusieurs façons :

IdentifiantFormatExempleUsage
IndexEntier séquentiel7403797Position dans le log
UUIDChaîne hexadécimale24296fb24b8ad77a8...Identifiant unique
HashSHA256 de l’artefact97fc222cee7991b5...Recherche par artefact
EmailIdentité OIDCdev@example.comRecherche par signataire

Informations sur le log

Commençons par vérifier que nous pouvons accéder au log et voir son état actuel :

Terminal window
rekor-cli loginfo

Sortie :

Verification Successful!
Active Tree Size: 98765432
Total Tree Size: 98765432
Root Hash: abc123def456...
Timestamp: 2025-12-29T10:30:00Z
ChampSignification
Active Tree SizeNombre d’entrées dans le log
Root HashHash racine de l’arbre de Merkle
TimestampDate de la dernière mise à jour

Le Root Hash est la donnée la plus importante : c’est le hash qui “résume” tout le contenu du log. Si une seule entrée était modifiée, ce hash changerait.

Rechercher par email

C’est la recherche la plus courante. Elle permet de retrouver toutes les signatures associées à une identité OIDC (votre compte GitHub, Google, etc.) :

Terminal window
rekor-cli search --email votre@email.com

Sortie :

Found matching entries (showing first 10):
24296fb24b8ad77a8...
24296fb24b8ad77a9...

Rechercher par hash d’artefact

Si vous avez une image conteneur ou un fichier et que vous voulez savoir s’il a été signé, utilisez son hash SHA256 :

Terminal window
# Calculer le hash d'un fichier local
sha256sum mon-fichier.txt
# Sortie : 97fc222cee7991b5b061d4d4afdb5f3428fcb0c9 mon-fichier.txt
# Rechercher dans Rekor
rekor-cli search --sha 97fc222cee7991b5b061d4d4afdb5f3428fcb0c9

Cette recherche est utile pour vérifier la provenance d’un artefact : a-t-il été signé ? Par qui ? Quand ?

Rechercher par index

Chaque entrée a un index unique (numéro séquentiel). L’index 0 est la première entrée du log, l’index 1 la deuxième, etc.

Terminal window
# Récupérer l'entrée numéro 7403797
rekor-cli get --log-index 7403797

Cette commande retourne toutes les informations de l’entrée : le type d’artefact, le hash, la signature, le certificat utilisé, etc.

Rechercher par UUID

L’UUID est l’identifiant unique global d’une entrée. Contrairement à l’index qui dépend de l’instance Rekor, l’UUID est calculé à partir du contenu de l’entrée :

Terminal window
rekor-cli get --uuid 24296fb24b8ad77a8d5b76c36...

Récupérer les détails d’une entrée

Une fois que vous avez trouvé une entrée (par email, hash, index ou UUID), vous pouvez afficher tous ses détails :

Terminal window
rekor-cli get --log-index 7403797

Sortie typique :

LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
Index: 7403797
IntegratedTime: 2025-06-15T14:30:00Z
UUID: 24296fb24b8ad77a8d5b76c36...
Body: {
"kind": "hashedrekord",
"apiVersion": "0.0.1",
"spec": {
"data": {
"hash": {
"algorithm": "sha256",
"value": "97fc222cee7991b5..."
}
},
"signature": {
"content": "MEUCIQDx...",
"publicKey": {
"content": "LS0tLS1CRUdJTi..."
}
}
}
}

Format JSON pour l’automatisation

Pour intégrer Rekor dans vos scripts ou pipelines CI/CD, utilisez le format JSON :

Terminal window
# Récupérer une entrée en JSON
rekor-cli get --log-index 7403797 --format json
# Extraire le hash de l'artefact avec jq
rekor-cli get --log-index 7403797 --format json | jq -r '.Body.HashedRekordObj.data.hash.value'
# Extraire l'email du signataire
rekor-cli get --log-index 7403797 --format json | jq -r '.Body.HashedRekordObj.signature.publicKey.content' | base64 -d | openssl x509 -noout -email

Vérifier une signature

La vérification est l’opération la plus importante de Rekor. Elle permet de prouver cryptographiquement qu’une signature existe dans le log et qu’elle est valide.

Comprendre la preuve d’inclusion

Quand vous vérifiez une entrée, Rekor retourne une inclusion proof (preuve d’inclusion). Cette preuve est un ensemble de hashs qui permettent de recalculer le Root Hash à partir de l’entrée.

Fonctionnement de la preuve d'inclusion

Étapes de vérification pour une entrée B :

  1. Calculer Hash(B)
  2. Calculer Hash(A+B) avec le Hash(A) fourni dans la preuve
  3. Calculer Root = Hash(Hash(A+B) + Hash(C+D))
  4. Comparer avec le Root Hash public
  5. Si égal → l’entrée B existe vraiment dans le log

Vérification en pratique

Pour vérifier qu’une signature est bien dans le log :

Terminal window
rekor-cli verify --artifact mon-fichier.txt \
--signature signature.sig \
--public-key cle-publique.pem

Sortie si valide :

Inclusion Proof:
Index: 7403797
Root Hash: abc123...
Tree Size: 98765432
Hashes: [def456..., ghi789...]
Entry was verified in Rekor!

Ce que la vérification prouve

Élément vérifiéSignification
Inclusion proofL’entrée existe bien dans le log
Signature validityLa signature correspond à l’artefact
TimestampLa signature a été créée à un moment précis

Vérification automatique avec Cosign

En pratique, vous n’avez pas besoin d’appeler rekor-cli verify directement. Cosign vérifie automatiquement les preuves Rekor lors de la vérification d’une signature :

Terminal window
# Cosign vérifie automatiquement l'inclusion dans Rekor
cosign verify mon-registry/mon-image:v1.0.0
# Pour désactiver la vérification Rekor (non recommandé)
cosign verify --insecure-ignore-tlog mon-registry/mon-image:v1.0.0

Explorer avec l’interface web

Pour une exploration visuelle, Rekor dispose d’une interface web :

search.sigstore.dev

Rekor Search Interface

Fonctionnalités :

  • Recherche par email, hash, UUID, index
  • Visualisation des détails complets d’une entrée
  • Affichage du certificat décodé
  • Export des données en JSON

Intégration CI/CD

L’intégration de Rekor dans vos pipelines CI/CD permet d’automatiser la vérification et la surveillance des signatures.

Scénarios d’intégration

Intégration Rekor dans un pipeline CI/CD

Vérifier les signatures dans un pipeline

GitHub Actions avec bonnes pratiques de sécurité :

name: Verify Signatures
on:
push:
branches: [main]
schedule:
- cron: '0 2 * * *' # Vérification quotidienne à 2h
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install rekor-cli
run: |
REKOR_VERSION=$(curl -s https://api.github.com/repos/sigstore/rekor/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -LO "https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}/rekor-cli-linux-amd64"
chmod +x rekor-cli-linux-amd64
sudo mv rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
- name: Search for signatures
run: |
# Rechercher les signatures de l'image
rekor-cli search --sha $(sha256sum mon-artefact | cut -d ' ' -f 1)
- name: Verify inclusion proof
run: |
rekor-cli verify --artifact mon-artefact \
--signature signature.sig \
--public-key public-key.pem

Audit continu avec GitHub Attestations

Vérifiez automatiquement les attestations SLSA de vos images :

name: SLSA Audit
on:
schedule:
- cron: '0 */6 * * *' # Toutes les 6 heures
workflow_dispatch:
permissions:
contents: read
jobs:
audit:
runs-on: ubuntu-24.04
steps:
- name: Get latest release
id: release
run: |
LATEST_TAG=$(gh api repos/${{ github.repository }}/tags --jq '.[0].name')
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get image digest
id: digest
run: |
IMAGE="ghcr.io/${{ github.repository }}:${{ steps.release.outputs.tag }}"
DIGEST=$(docker pull "${IMAGE}" 2>&1 | grep "Digest:" | cut -d' ' -f2)
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
- name: Verify SLSA attestation
run: |
gh attestation verify \
oci://ghcr.io/${{ github.repository }}@${{ steps.digest.outputs.digest }} \
--owner ${{ github.repository_owner }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check Rekor entries
run: |
# Installer rekor-cli
REKOR_VERSION=$(curl -s https://api.github.com/repos/sigstore/rekor/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -LO "https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}/rekor-cli-linux-amd64"
chmod +x rekor-cli-linux-amd64
sudo mv rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
# Rechercher les signatures de cette image
IMAGE_SHA=$(echo "${{ steps.digest.outputs.digest }}" | cut -d':' -f2)
echo "Searching Rekor for image SHA: ${IMAGE_SHA}"
rekor-cli search --sha "${IMAGE_SHA}"
- name: Report audit results
if: always()
run: |
if [ "${{ job.status }}" == "success" ]; then
echo "✅ Audit passed for ${{ steps.release.outputs.tag }}"
echo "- SLSA attestation: verified"
echo "- Rekor entries: found"
else
echo "❌ Audit failed for ${{ steps.release.outputs.tag }}"
exit 1
fi

Alerter sur les nouvelles signatures

Créez un job qui surveille les signatures pour votre domaine :

monitor-signatures.sh
#!/bin/bash
EMAIL_DOMAIN="@votre-entreprise.com"
LAST_CHECK_FILE="/tmp/rekor-last-check"
# Récupérer le dernier index vérifié
if [ -f "$LAST_CHECK_FILE" ]; then
LAST_INDEX=$(cat "$LAST_CHECK_FILE")
else
LAST_INDEX=0
fi
# Récupérer la taille actuelle du log
CURRENT_SIZE=$(rekor-cli loginfo --format json | jq -r '.ActiveTreeSize')
# Vérifier les nouvelles entrées
for i in $(seq $((LAST_INDEX + 1)) $CURRENT_SIZE); do
ENTRY=$(rekor-cli get --log-index $i --format json 2>/dev/null)
if echo "$ENTRY" | grep -q "$EMAIL_DOMAIN"; then
echo "Nouvelle signature détectée à l'index $i"
# Envoyer une alerte (Slack, email, etc.)
fi
done
echo "$CURRENT_SIZE" > "$LAST_CHECK_FILE"

Déployer Rekor en privé

L’instance publique de Rekor convient à la plupart des cas d’usage open source. Cependant, certaines situations nécessitent une instance privée.

Quand déployer en privé ?

SituationPourquoi une instance privée
Air-gappedPas d’accès à Internet depuis l’environnement de build
ConfidentialitéLes emails/signatures ne doivent pas être publics
ConformitéLes données doivent rester dans une région géographique
PerformanceContrôle total sur la latence et la disponibilité
SouverainetéIndépendance vis-à-vis de l’infrastructure Sigstore

Architecture d’un déploiement privé

Une instance Rekor nécessite plusieurs composants :

Architecture Rekor privé

Déploiement avec Docker Compose

Voici un exemple de déploiement simplifié pour tests et développement :

docker-compose.yml
version: '3.8'
services:
mysql:
image: mariadb:10.11
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: trillian
MYSQL_USER: trillian
MYSQL_PASSWORD: trillian
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:7-alpine
trillian-log-server:
image: gcr.io/trillian-opensource-ci/log_server:latest
command:
- --storage_system=mysql
- --mysql_uri=trillian:trillian@tcp(mysql:3306)/trillian
- --rpc_endpoint=0.0.0.0:8090
- --http_endpoint=0.0.0.0:8091
depends_on:
- mysql
trillian-log-signer:
image: gcr.io/trillian-opensource-ci/log_signer:latest
command:
- --storage_system=mysql
- --mysql_uri=trillian:trillian@tcp(mysql:3306)/trillian
- --rpc_endpoint=0.0.0.0:8090
- --force_master=true
depends_on:
- mysql
rekor-server:
image: gcr.io/projectsigstore/rekor-server:latest
command:
- serve
- --trillian_log_server.address=trillian-log-server
- --trillian_log_server.port=8090
- --redis_server.address=redis
- --redis_server.port=6379
- --rekor_server.address=0.0.0.0
- --rekor_server.port=3000
ports:
- "3000:3000"
depends_on:
- trillian-log-server
- redis
volumes:
mysql-data:

Utiliser votre instance privée

Terminal window
# Configurer rekor-cli pour utiliser votre serveur
export REKOR_SERVER=https://rekor.votre-entreprise.com
# Ou par commande
rekor-cli --rekor_server https://rekor.votre-entreprise.com loginfo

Dépannage

Problèmes courants

SymptômeCause probableSolution
connection refusedServeur Rekor inaccessibleVérifier la connexion Internet
entry not foundUUID/index invalideVérifier le format de l’identifiant
verification failedArtefact modifiéL’artefact ne correspond pas à la signature
timeoutRéseau lentRéessayer ou augmenter le timeout

Vérifier la connectivité

Terminal window
# Tester l'accès au serveur public
curl -s https://rekor.sigstore.dev/api/v1/log | jq .
# Sortie attendue :
# {
# "rootHash": "abc123...",
# "signedTreeHead": "...",
# "treeSize": 98765432
# }

Sécurité et limites

Comprendre ce que Rekor protège (et ne protège pas) est essentiel pour une utilisation éclairée.

Ce que Rekor garantit

Garanties de sécurité de Rekor

Scénarios d’attaque et protections

AttaqueProtection RekorLimite
Usurpation d’identitéSignature visible publiquementSi compte OIDC compromis, attaquant peut signer
Modification d’artefactHash enregistré dans le logDétection a posteriori uniquement
Falsification du logArbre de Merkle + signaturesRequiert compromission de l’infrastructure
Suppression d’entréeStructure append-onlyOpérateur malveillant pourrait “fork” le log

Bonnes pratiques

PratiquePourquoi
Vérifier les signatures en CIDétecte les artefacts non signés ou falsifiés
Monitorer les nouvelles signaturesAlerte immédiate si usurpation d’identité
Activer 2FA sur les comptes OIDCRéduit le risque de compromission
Archiver les preuves d’inclusionAudit trail pour conformité
Utiliser Rekor privé si confidentialité requiseEmails sont publics sinon

Ce que Rekor ne protège pas

À retenir

Voici les 5 points essentiels à retenir sur Rekor :

  1. Rekor = registre notarial numérique : chaque signature est horodatée et enregistrée dans un log public et immuable

  2. Arbre de Merkle : structure cryptographique qui garantit que le log ne peut pas être modifié sans que cela soit détectable

  3. Preuve temporelle : résout le problème des certificats éphémères en prouvant qu’une signature existait à un moment précis

  4. Auditabilité totale : n’importe qui peut rechercher et vérifier les signatures (attention : les emails sont publics)

  5. Instance privée possible : pour les environnements air-gapped ou nécessitant la confidentialité

Résumé Rekor

Liens utiles

Ressources externes