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.
Rekor résout ce problème en enregistrant la signature au moment de sa création avec un horodatage cryptographique :
Propriétés du log
| Propriété | Description | Pourquoi c’est important |
|---|---|---|
| Immuable | Une entrée ne peut pas être modifiée | Garantit l’intégrité historique |
| Append-only | On ne peut qu’ajouter, jamais réécrire | Empêche la réécriture de l’historique |
| Vérifiable | Structure en arbre de Merkle | Preuves cryptographiques d’inclusion |
| Public | Tout le monde peut lire et auditer | Transparence totale |
| Horodaté | Timestamp RFC3161 sur chaque entrée | Preuve 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.
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 :
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 :
# Rechercher toutes les signatures de l'équiperekor-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énario | Question | Réponse de Rekor |
|---|---|---|
| Audit | Qui a signé nos artefacts ce mois-ci ? | Liste des signatures par email/hash |
| Compromission | Quelqu’un a-t-il signé à ma place ? | Oui, entrée #12345 le 15/12 |
| Conformité | Preuve de traçabilité ? | Inclusion proof + timestamp |
| Incident | Quand 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
# Installer jq si nécessaire# Debian/Ubuntusudo apt install jq
# macOSbrew install jqInstallation de rekor-cli
# Télécharger la dernière versionREKOR_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"
# Installerchmod +x rekor-cli-linux-amd64sudo mv rekor-cli-linux-amd64 /usr/local/bin/rekor-cli
# Vérifierrekor-cli versionSortie attendue :
rekor-cli: vX.Y.Z# Avec Homebrewbrew install rekor-cli
# Vérifierrekor-cli version# Si vous avez Go installégo install github.com/sigstore/rekor/cmd/rekor-cli@latest
# Vérifier (assurez-vous que $GOPATH/bin est dans votre PATH)rekor-cli versionInterroger 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 :
| Identifiant | Format | Exemple | Usage |
|---|---|---|---|
| Index | Entier séquentiel | 7403797 | Position dans le log |
| UUID | Chaîne hexadécimale | 24296fb24b8ad77a8... | Identifiant unique |
| Hash | SHA256 de l’artefact | 97fc222cee7991b5... | Recherche par artefact |
| Identité OIDC | dev@example.com | Recherche par signataire |
Informations sur le log
Commençons par vérifier que nous pouvons accéder au log et voir son état actuel :
rekor-cli loginfoSortie :
Verification Successful!Active Tree Size: 98765432Total Tree Size: 98765432Root Hash: abc123def456...Timestamp: 2025-12-29T10:30:00Z| Champ | Signification |
|---|---|
| Active Tree Size | Nombre d’entrées dans le log |
| Root Hash | Hash racine de l’arbre de Merkle |
| Timestamp | Date 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.) :
rekor-cli search --email votre@email.comSortie :
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 :
# Calculer le hash d'un fichier localsha256sum mon-fichier.txt# Sortie : 97fc222cee7991b5b061d4d4afdb5f3428fcb0c9 mon-fichier.txt
# Rechercher dans Rekorrekor-cli search --sha 97fc222cee7991b5b061d4d4afdb5f3428fcb0c9Cette 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.
# Récupérer l'entrée numéro 7403797rekor-cli get --log-index 7403797Cette 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 :
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 :
rekor-cli get --log-index 7403797Sortie typique :
LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801dIndex: 7403797IntegratedTime: 2025-06-15T14:30:00ZUUID: 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 :
# Récupérer une entrée en JSONrekor-cli get --log-index 7403797 --format json
# Extraire le hash de l'artefact avec jqrekor-cli get --log-index 7403797 --format json | jq -r '.Body.HashedRekordObj.data.hash.value'
# Extraire l'email du signatairerekor-cli get --log-index 7403797 --format json | jq -r '.Body.HashedRekordObj.signature.publicKey.content' | base64 -d | openssl x509 -noout -emailVé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.
Étapes de vérification pour une entrée B :
- Calculer
Hash(B) - Calculer
Hash(A+B)avec leHash(A)fourni dans la preuve - Calculer
Root = Hash(Hash(A+B) + Hash(C+D)) - Comparer avec le Root Hash public
- 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 :
rekor-cli verify --artifact mon-fichier.txt \ --signature signature.sig \ --public-key cle-publique.pemSortie 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 proof | L’entrée existe bien dans le log |
| Signature validity | La signature correspond à l’artefact |
| Timestamp | La 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 :
# Cosign vérifie automatiquement l'inclusion dans Rekorcosign 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.0Explorer avec l’interface web
Pour une exploration visuelle, Rekor dispose d’une interface web :
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
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.pemAudit 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 fiAlerter sur les nouvelles signatures
Créez un job qui surveille les signatures pour votre domaine :
#!/bin/bashEMAIL_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=0fi
# Récupérer la taille actuelle du logCURRENT_SIZE=$(rekor-cli loginfo --format json | jq -r '.ActiveTreeSize')
# Vérifier les nouvelles entréesfor 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.) fidone
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é ?
| Situation | Pourquoi une instance privée |
|---|---|
| Air-gapped | Pas 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 |
| Performance | Contrô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 :
Déploiement avec Docker Compose
Voici un exemple de déploiement simplifié pour tests et développement :
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
# Configurer rekor-cli pour utiliser votre serveurexport REKOR_SERVER=https://rekor.votre-entreprise.com
# Ou par commanderekor-cli --rekor_server https://rekor.votre-entreprise.com loginfoDépannage
Problèmes courants
| Symptôme | Cause probable | Solution |
|---|---|---|
connection refused | Serveur Rekor inaccessible | Vérifier la connexion Internet |
entry not found | UUID/index invalide | Vérifier le format de l’identifiant |
verification failed | Artefact modifié | L’artefact ne correspond pas à la signature |
timeout | Réseau lent | Réessayer ou augmenter le timeout |
Vérifier la connectivité
# Tester l'accès au serveur publiccurl -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
Scénarios d’attaque et protections
| Attaque | Protection Rekor | Limite |
|---|---|---|
| Usurpation d’identité | Signature visible publiquement | Si compte OIDC compromis, attaquant peut signer |
| Modification d’artefact | Hash enregistré dans le log | Détection a posteriori uniquement |
| Falsification du log | Arbre de Merkle + signatures | Requiert compromission de l’infrastructure |
| Suppression d’entrée | Structure append-only | Opérateur malveillant pourrait “fork” le log |
Bonnes pratiques
| Pratique | Pourquoi |
|---|---|
| Vérifier les signatures en CI | Détecte les artefacts non signés ou falsifiés |
| Monitorer les nouvelles signatures | Alerte immédiate si usurpation d’identité |
| Activer 2FA sur les comptes OIDC | Réduit le risque de compromission |
| Archiver les preuves d’inclusion | Audit trail pour conformité |
| Utiliser Rekor privé si confidentialité requise | Emails sont publics sinon |
Ce que Rekor ne protège pas
À retenir
Voici les 5 points essentiels à retenir sur Rekor :
-
Rekor = registre notarial numérique : chaque signature est horodatée et enregistrée dans un log public et immuable
-
Arbre de Merkle : structure cryptographique qui garantit que le log ne peut pas être modifié sans que cela soit détectable
-
Preuve temporelle : résout le problème des certificats éphémères en prouvant qu’une signature existait à un moment précis
-
Auditabilité totale : n’importe qui peut rechercher et vérifier les signatures (attention : les emails sont publics)
-
Instance privée possible : pour les environnements air-gapped ou nécessitant la confidentialité
Liens utiles
Ressources externes
- Documentation officielle Rekor ↗ — Guide complet
- Rekor sur GitHub ↗ — Code source et issues
- Rekor Search ↗ — Interface web pour explorer le log public
- Certificate Transparency ↗ — Le concept qui a inspiré Rekor