Aller au contenu
Sécurité medium

Rekor : le log de transparence de Sigstore

30 min de lecture

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.

Ce log de transparence alimente les exigences de traçabilité et de provenance du référentiel Socle DevSecOps.

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

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

Ces cinq propriétés ne sont pas des arguments marketing : ce sont les garanties qui rendent une preuve recevable lors d'un audit. Lisez la colonne de droite en priorité, elle répond à la seule question qui compte, à quoi sert la propriété. Retenez surtout append-only et horodaté : la première interdit de réécrire l'histoire, la seconde donne la preuve temporelle qui survit à l'expiration du certificat Fulcio.

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

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

Pour prouver qu'une entrée existe, Rekor fournit les hashs intermédiaires qui permettent de recalculer le root hash sans télécharger tout le log :

Preuve d'inclusion pour l'entrée B

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

Fenêtre de terminal
# Rechercher toutes les signatures de l'équipe
rekor-cli search --email "@votre-entreprise.com"

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.

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.

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

Avant de commencer :

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

Téléchargez le binaire et le fichier de sommes publié par le projet, puis vérifiez l'empreinte avant d'installer. Une version figée rend la manipulation reproductible ; adaptez REKOR_VERSION quand une version plus récente sort.

Fenêtre de terminal
# Version épinglée (dernière version au moment de la rédaction)
REKOR_VERSION=v1.5.3
BASE="https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}"
# Télécharger le binaire et le fichier de sommes officiel
curl -LO "${BASE}/rekor-cli-linux-amd64"
curl -LO "${BASE}/rekor_checksums.txt"
# Vérifier l'empreinte SHA256 avant toute installation
sha256sum --check --ignore-missing rekor_checksums.txt
# rekor-cli-linux-amd64: OK
# Installer uniquement si la vérification a réussi
chmod +x rekor-cli-linux-amd64
sudo mv rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
# Vérifier
rekor-cli version

Sortie attendue :

GitVersion: v1.5.3
GitCommit: 7d9dcffcc27c4912e7d17fc768db01aa2d5cf26c
GitTreeState: clean
BuildDate: 2026-07-01T21:50:32Z
GoVersion: go1.26.3
Platform: linux/amd64

L'instance publique de Rekor est accessible à rekor.sigstore.dev. C'est l'instance utilisée par défaut par Cosign et gitsign. Gérée par l'OpenSSF avec une astreinte multi-fournisseurs, elle vise un SLO de 99,5 % sur ses principaux points d'API (état en direct sur status.sigstore.dev) et sert npm, PyPI, Kubernetes et des milliers de projets open source.

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

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

Fenêtre de terminal
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.

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

Fenêtre de terminal
rekor-cli search --email votre@email.com

Sortie :

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

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

Fenêtre de terminal
# 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 ?

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.

Fenêtre de terminal
# 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.

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 :

Fenêtre de terminal
rekor-cli get --uuid 24296fb24b8ad77a8d5b76c36...

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

Fenêtre de terminal
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..."
}
}
}
}

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

Fenêtre de terminal
# 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

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.

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

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

Fenêtre de terminal
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!

Une vérification réussie apporte trois garanties distinctes qu'il faut ne pas confondre. La preuve d'inclusion atteste que l'entrée figure bien dans le log, la validité de signature que celle-ci correspond à l'artefact, et le timestamp qu'elle existait à une date donnée. Aucune des trois ne dit que le contenu signé est sûr : elles prouvent l'origine et l'intégrité, pas la qualité.

É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

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 :

Fenêtre de terminal
# 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

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

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

Rekor trouve sa place à deux moments du pipeline, et le schéma ci-dessous les distingue. À la construction, une étape enregistre la signature de l'artefact fraîchement produit. Au déploiement ou lors d'un audit périodique, une autre étape interroge le log pour confirmer qu'un artefact a bien été signé avant de l'autoriser. C'est cette seconde étape qui apporte la valeur défensive : sans vérification à l'entrée, l'enregistrement ne sert à rien.

Intégration Rekor dans un pipeline CI/CD

GitHub Actions avec bonnes pratiques de sécurité :

name: Verify Signatures
on:
push:
branches: [main]
schedule:
- cron: '0 2 * * *' # Vérification quotidienne à 2h
permissions: {}
jobs:
verify:
runs-on: ubuntu-24.04
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install rekor-cli
run: |
REKOR_VERSION=v1.5.3
BASE="https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}"
curl -LO "${BASE}/rekor-cli-linux-amd64"
curl -LO "${BASE}/rekor_checksums.txt"
sha256sum --check --ignore-missing rekor_checksums.txt
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

Vérifiez automatiquement les attestations SLSA de vos images :

name: SLSA Audit
on:
schedule:
- cron: '0 */6 * * *' # Toutes les 6 heures
workflow_dispatch:
permissions: {}
jobs:
audit:
runs-on: ubuntu-24.04
permissions:
contents: read
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 avec vérification d'empreinte
REKOR_VERSION=v1.5.3
BASE="https://github.com/sigstore/rekor/releases/download/${REKOR_VERSION}"
curl -LO "${BASE}/rekor-cli-linux-amd64"
curl -LO "${BASE}/rekor_checksums.txt"
sha256sum --check --ignore-missing rekor_checksums.txt
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

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"

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

Cinq situations justifient de renoncer à l'instance publique, et elles se ramènent à deux motifs de fond : la confidentialité (vos identités et signatures ne doivent pas être publiques) et l'indépendance (environnement sans Internet, contrainte de souveraineté ou de région). Si aucun de ces motifs ne s'applique à votre contexte, l'instance publique reste le choix le plus simple et le mieux audité.

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

Une instance Rekor n'est pas un binaire isolé : elle repose sur Trillian, le moteur de log en arbre de Merkle développé par Google, lui-même adossé à une base de données MySQL/MariaDB qui stocke les entrées. Le schéma ci-dessous montre comment rekor-server s'appuie sur le log-server et le log-signer de Trillian. Retenez cette dépendance : sauvegarder Rekor, c'est d'abord sauvegarder cette base, sans quoi le log entier est perdu.

Architecture Rekor privé

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@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99
trillian-log-server:
image: gcr.io/trillian-opensource-ci/log_server:v1.7.3@sha256:f5e3cfb3342baf4b6d6ea289be70f0a9b9698701028511c1209f7e2dce2b06a0
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:v1.7.3@sha256:2f8139ba3ceccaa40736c4ee4ee55256d9bbee1e16c1ab79baa6d56c77af6dd9
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:v1.5.3@sha256:ef3ac5d318fe8fb50997d6bf3e39c04e8ccc87708ff991e16d74e956f85ca74e
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:
Fenêtre de terminal
# 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

La plupart des erreurs rencontrées avec rekor-cli sont soit des problèmes d'accès réseau à l'instance, soit des identifiants mal formés. Lisez d'abord le symptôme exact renvoyé par la commande, puis remontez à la cause dans le tableau : un verification failed n'a rien à voir avec la connectivité, il signale que l'artefact ne correspond plus à sa signature.

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

Avant de suspecter rekor-cli, isolez la couche réseau avec un simple appel HTTP à l'API. Si cette requête curl renvoie bien un objet JSON contenant un treeSize, l'instance est joignable et le problème vient d'ailleurs (format d'identifiant, artefact modifié). Si elle échoue, vous avez confirmé un souci de connectivité ou de proxy, indépendant de l'outil.

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

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

Avant de lire le schéma, gardez en tête une distinction qui évite les malentendus : Rekor fournit une garantie d'intégrité et de traçabilité, pas de confiance dans le signataire. Il prouve qu'une signature existait à un instant donné et n'a pas été altérée depuis. Il ne juge ni la légitimité du signataire ni la qualité de l'artefact signé, deux points que le schéma place volontairement hors de son périmètre.

Garanties de sécurité de Rekor

Ce tableau se lit en trois temps, colonne par colonne : l'attaque, ce que Rekor oppose, et surtout la limite de cette protection. C'est la troisième colonne qui compte, car elle corrige l'illusion la plus courante. Rekor est un outil de détection a posteriori, pas de prévention : il rend une falsification visible et prouvable, mais n'empêche ni la signature frauduleuse ni la modification d'un artefact.

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

Ces recommandations découlent directement des limites vues juste avant. Puisque Rekor détecte sans empêcher, l'essentiel se joue autour du log, pas dedans. Les deux premières lignes forment le socle : vérifier en CI ferme la porte aux artefacts non signés, monitorer les nouvelles signatures transforme la détection a posteriori en alerte quasi temps réel dès qu'une identité est usurpée.

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

Voici les 5 points essentiels à retenir sur Rekor :

  1. Rekor est un log de transparence append-only : chaque signature est horodatée et enregistrée dans un registre public et immuable, consultable par tous

  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

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn