Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Rekor : le log de transparence de Sigstore

Par mis à jour le

Améliorer cette page

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.

Cette leçon s'adresse à un DevOps qui a lu la vue d'ensemble de Sigstore et la leçon sur Fulcio, l'autorité qui délivre le certificat éphémère. Rekor est la pièce qui garde la trace de ce que Cosign (images) et gitsign (commits) signent avec ce certificat. Cosign est détaillé dans la leçon suivante : ici, vous n'en retenez que ce qui touche au log.

Cette leçon part du problème que Rekor résout, puis passe à la pratique avec rekor-cli, jusqu'à la surveillance de vos signatures. Vous apprendrez à :

  • expliquer pourquoi la signature keyless a besoin d'un log de transparence ;
  • interroger le log public par email, hash, index ou UUID ;
  • vérifier une preuve d'inclusion, avec rekor-cli ou avec Cosign ;
  • surveiller les signatures de votre identité depuis un pipeline CI/CD ;
  • décider si une instance privée de Rekor se justifie, et en comprendre l'architecture ;
  • situer ce que Rekor garantit et ce qu'il ne protège pas ;
  • produire la preuve de SOCLE-REL-VER-2, le journal de transparence des signatures, et contribuer à SOCLE-REL-VER-1, la vérification avant usage.

Avec la signature keyless de Sigstore (sans clé privée à conserver), 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 : quand on vérifie, le certificat est déjà expiré. La leçon Sigstore montre ce problème sur une chronologie.

Rekor le résout en enregistrant la signature au moment de sa création avec un horodatage cryptographique :

La solution Rekor : la signature créée à T=5 min est enregistrée dans Rekor avec un horodatage signé par Rekor (le SET, *signed entry timestamp*), une preuve d'inclusion et le hash de l'artefact ; à T=15 min, la vérification réussit car la preuve montre que la signature date de la validité du certificat.T=0 mincertificat éphémère émisT=5 minsignature crééeRekor : enregistrement à T=5 minhorodatage signé (SET), preuve d'inclusion, hashT=10 mincertificat expiréT=15 minvérification : OK
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

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 : chacun peut vérifier
HorodatéHorodatage signé par Rekor (SET) sur chaque entrée ; un horodatage RFC 3161 vient d'une autorité d'horodatage (TSA), que le signing config public référence (timestamp.sigstore.dev, octobre 2026) et que Cosign utilise par défaut quand c'est approprié ; à configurer explicitement en instance privéePreuve temporelle vérifiable

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. Le principe vient de Certificate Transparency, le système public qui journalise les certificats TLS émis par les autorités de certification.

Arbre de Merkle : les entrées A à D sont hachées, les hachages combinés deux à deux en Hash(A+B) et Hash(C+D), puis en un Root Hash ; modifier une entrée change toute la branche jusqu'à la racine.Entry A(sign 1)Entry B(sign 2)Entry C(sign 3)Entry D(sign 4)Hash(A)Hash(B)Hash(C)Hash(D)Hash(A+B)(def456)Hash(C+D)(ghi789)Root Hash(abc123...)
Si l'entrée B est modifiée, Hash(B), puis Hash(A+B), puis le Root Hash changent : la falsification est immédiatement détectable. Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

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 de l'entrée B : avec Entry B, Hash(A) et Hash(C+D) fournis comme preuve, on recalcule Hash(B), Hash(A+B) puis le Root Hash, et on le compare au Root Hash public.Entry Bl'entrée à prouverHash(B)à vérifierHash(A)(preuve fournie)Hash(A+B)Hash(C+D)(preuve fournie)Root Hash (abc123...)connu publiquement
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Votre entreprise veut auditer les signatures effectuées par ses développeurs. La recherche par email attend une adresse complète, pas un domaine : on interroge donc chaque adresse de l'équipe, l'une après l'autre.

Fenêtre de terminal
# Lister les entrées associées à une adresse de l'équipe
rekor-cli search --email alice@votre-entreprise.com

La commande ne filtre pas par date. Pour borner l'audit à une période, lisez le champ IntegratedTime de chaque entrée avec rekor-cli get (voir plus bas).

Vous configurez une alerte qui vous notifie dès qu'une signature est créée avec votre identité (le script se trouve dans la section « Alerter sur les nouvelles signatures »). 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 et les référentiels comme SLSA demandent de pouvoir justifier l'origine des artefacts livrés. Rekor ne remplace ni le SBOM ni la documentation technique que le CRA impose, mais il fournit une preuve cryptographique de qui a signé quoi et quand, que vous pouvez verser à un dossier de conformité.

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

Les sections qui suivent utilisent la ligne de commande. 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 (dépôt sigstore/rekor), 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. D'après la documentation officielle, elle offre un SLO de 99,5 % de disponibilité (un objectif de niveau de service, sans engagement contractuel) et elle est surveillée par une équipe d'astreinte. L'état en direct est publié sur status.sigstore.dev. Une version 2 de Rekor (projet rekor-tiles, log à base de tuiles) est en disponibilité générale depuis le 10 octobre 2025, mais l'instance publique continue de servir la v1 par défaut pour la signature (état au 16 octobre 2026, d'après le billet Sigstore) ; cette page décrit la v1. En v2, la date n'est plus attestée par le SET du journal mais par une autorité d'horodatage (TSA) séparée.

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

IdentifiantFormatExempleUsage
IndexEntier séquentiel7403797Position dans le log
UUIDChaîne hexadécimale de 80 caractères24296fb24b8ad77a3d22...Identifiant unique
HashSHA256 de l'artefactd1bf68416e025fa0...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 relevée le 16 octobre 2026 (les valeurs changent à chaque appel, et rekor-cli affiche avant ce bloc des messages de validation des arbres archivés) :

Verification Successful!
Active Tree Size: 3161031609
Total Tree Size: 3282935871
Root Hash: 9edf75837e8ec7c457f9e00022bd2dd5e664f3b643028d2aa6963ae59047f166
TreeID: 1193050959916656506

Le log public est découpé en plusieurs arbres de Merkle : des arbres archivés, figés, et un arbre actif, qui reçoit les nouvelles signatures. Le tableau distingue donc ce qui concerne l'arbre actif de ce qui concerne l'ensemble.

ChampSignification
Active Tree SizeNombre d'entrées de l'arbre actif
Total Tree SizeNombre d'entrées de tous les arbres, archivés compris
Root HashHash racine de l'arbre de Merkle actif
TreeIDIdentifiant de l'arbre actif

Le Root Hash est la donnée la plus importante : c'est le hash qui "résume" tout le contenu de l'arbre actif. 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 (un UUID complet par ligne ; sans résultat, la commande affiche no matching entries found et sort avec un code d'erreur) :

Found matching entries (listed by UUID):
24296fb24b8ad77a05565a4436ef17cadb26307217f7c1907a700923d6d2ad611a81a56a81ed6038
24296fb24b8ad77a3d228fca35e4f9f32d582a2cb0391ca72ae73357a447a057fc0cafa50f86129d

Si vous avez un fichier et que vous voulez savoir s'il a été signé (par exemple avec cosign sign-blob), utilisez son hash SHA256 :

Fenêtre de terminal
# Calculer le hash d'un fichier local
sha256sum mon-fichier.txt
# Exemple de sortie (le hash dépend du contenu de votre fichier) :
# d1bf68416e025fa0e0a5a54c5dd650c4121f41414cae9c5c167c0f3d653734a8 mon-fichier.txt
# Rechercher dans Rekor (ce hash d'exemple figure réellement dans le log public)
rekor-cli search --sha d1bf68416e025fa0e0a5a54c5dd650c4121f41414cae9c5c167c0f3d653734a8

Cette recherche est utile pour vérifier la provenance d'un artefact : a-t-il été signé ? Par qui ? Quand ? Avec votre propre fichier, le hash diffère et la commande ne trouve une entrée que si ce fichier a été signé puis journalisé ; sinon elle répond no matching entries found.

Cette méthode ne vaut pas pour une image conteneur signée par Cosign. Cosign ne signe pas l'image elle-même mais un petit document JSON (le payload), qui contient le digest de l'image. L'entrée Rekor indexe le hash de ce document, pas le digest de l'image : rekor-cli search --sha avec le digest de l'image ne la retrouve donc pas. Pour une image, utilisez cosign verify, qui reconstruit le payload, retrouve l'entrée Rekor et vérifie sa preuve d'inclusion, ou cherchez par identité avec --email.

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 l'entrée complète : hash de l'artefact, signature, certificat utilisé, heure d'intégration. La section « Récupérer les détails d'une entrée » en détaille la sortie.

L'UUID est l'identifiant unique d'une entrée. Contrairement à l'index, qui n'est qu'une position dans le log, il est dérivé du contenu de l'entrée : ses 16 premiers caractères hexadécimaux désignent l'arbre (shard Trillian) qui la contient, les 64 suivants sont le hash de feuille Merkle de l'entrée dans cet arbre.

Fenêtre de terminal
rekor-cli get --uuid 24296fb24b8ad77a3d228fca35e4f9f32d582a2cb0391ca72ae73357a447a057fc0cafa50f86129d

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 (entrée réelle du log public, champs longs tronqués) :

LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
Index: 7403797
IntegratedTime: 2022-11-19T07:58:34Z
UUID: 24296fb24b8ad77a3d228fca35e4f9f32d582a2cb0391ca72ae73357a447a057fc0cafa50f86129d
Body: {
"HashedRekordObj": {
"data": {
"hash": {
"algorithm": "sha256",
"value": "d1bf68416e025fa0e0a5a54c5dd650c4121f41414cae9c5c167c0f3d653734a8"
}
},
"signature": {
"content": "MEUCIQDk3shE3zCvSfxvMWMs...",
"publicKey": {
"content": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
}
}
}
}

IntegratedTime est l'heure à laquelle l'entrée a été intégrée au log. Le champ publicKey.content contient, encodé en base64, le certificat du signataire (le préfixe LS0tLS1CRUdJTi correspond à -----BEGIN) : décodé, il révèle l'email de l'identité, ce que fait la dernière commande ci-dessous.

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 (le certificat est en base64)
rekor-cli get --log-index 7403797 --format json | jq -r '.Body.HashedRekordObj.signature.publicKey.content' | base64 -d | openssl x509 -noout -email
# testinguser883@gmail.com

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.

Le schéma de la section « Preuve d'inclusion » montre ce calcul pour l'entrée B, avec Hash(A) et Hash(C+D) comme preuve.

É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

Le plus simple pour voir une preuve d'inclusion en action est de demander à rekor-cli de recalculer le Root Hash d'une entrée existante, par exemple l'entrée d'index 7403797 utilisée plus haut :

Fenêtre de terminal
rekor-cli verify --log-index 7403797

La sortie affiche d'abord le Root Hash courant, puis chaque calcul SHA256(0x01 | hash gauche | hash droit) de la preuve, et se termine par deux lignes Computed Root Hash et Expected Root Hash. Si les deux valeurs sont identiques, l'entrée appartient bien au log. Si elles diffèrent, la preuve ne tient pas.

Pour vérifier qu'une signature précise est dans le log, il faut réunir l'artefact, sa signature détachée et la clé publique correspondante, qui doivent déjà avoir été enregistrés ensemble dans le log :

Fenêtre de terminal
rekor-cli verify --artifact mon-fichier.txt \
--signature signature.sig \
--public-key cle-publique.pem \
--pki-format x509

L'option --pki-format indique le format de la clé et de la signature : sa valeur par défaut est pgp, d'où le x509 pour une clé publique PEM. Si l'entrée figure dans le log, la commande affiche la preuve d'inclusion (index, hashs intermédiaires, taille de l'arbre) ; sinon elle sort en erreur.

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, l'outil qui signe et vérifie les images (leçon suivante), vérifie automatiquement les preuves Rekor lors de la vérification d'une signature. En mode keyless, vous lui indiquez l'identité attendue et son fournisseur OIDC :

Fenêtre de terminal
# Cosign vérifie automatiquement l'inclusion dans Rekor ; en mode keyless,
# l'identité attendue et son fournisseur OIDC sont obligatoires
cosign verify mon-registry/mon-image:v1.0.0 \
--certificate-identity alice@votre-entreprise.com \
--certificate-oidc-issuer https://accounts.google.com
# Pour désactiver la vérification Rekor (non recommandé)
cosign verify --insecure-ignore-tlog mon-registry/mon-image:v1.0.0 \
--certificate-identity alice@votre-entreprise.com \
--certificate-oidc-issuer https://accounts.google.com

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.

Rekor dans un pipeline : build, signature keyless avec Cosign (enregistrée automatiquement dans Rekor), push vers le registre, puis vérification de la signature et de l'inclusion Rekor, qui aboutit à Verified ou Fail.ouinonBuildSign(Cosign)PushRegistryVerify(Rekor)Rekor(enregistrement)VerifiedFail
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Ce workflow suppose que mon-artefact, signature.sig et public-key.pem sont disponibles dans le dépôt ou téléchargés par une étape précédente : ce sont les trois pièces de la vérification décrite plus haut.

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 la signature d'un fichier (cosign sign-blob)
HASH="$(sha256sum mon-artefact | cut -d ' ' -f 1)"
rekor-cli search --sha "${HASH}"
- name: Verify inclusion proof
run: |
rekor-cli verify --artifact mon-artefact \
--signature signature.sig \
--public-key public-key.pem \
--pki-format x509

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
packages: read
steps:
- name: Get latest release
id: release
run: |
LATEST_TAG=$(gh api "repos/${GITHUB_REPOSITORY}/releases/latest" --jq '.tag_name')
echo "tag=${LATEST_TAG}" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get image digest
id: digest
env:
RELEASE_TAG: ${{ steps.release.outputs.tag }}
GH_ACTOR: ${{ github.actor }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "${GH_TOKEN}" | docker login ghcr.io -u "${GH_ACTOR}" --password-stdin
IMAGE="ghcr.io/${GITHUB_REPOSITORY}:${RELEASE_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}@${IMAGE_DIGEST}" \
--owner "${GITHUB_REPOSITORY_OWNER}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
IMAGE_DIGEST: ${{ steps.digest.outputs.digest }}
- name: Check Rekor entries
env:
IMAGE_DIGEST: ${{ steps.digest.outputs.digest }}
run: |
# Installer cosign avec vérification d'empreinte
COSIGN_VERSION=v3.1.3
BASE="https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}"
curl -LO "${BASE}/cosign-linux-amd64"
curl -LO "${BASE}/cosign_checksums.txt"
sha256sum --check --ignore-missing cosign_checksums.txt
chmod +x cosign-linux-amd64
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
# cosign contrôle lui-même la preuve Rekor jointe à la signature
# (vérification hors ligne, sans appel à rekor-cli)
cosign verify \
"ghcr.io/${GITHUB_REPOSITORY}@${IMAGE_DIGEST}" \
--certificate-identity-regexp "^https://github.com/${GITHUB_REPOSITORY}/" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
- name: Report audit results
if: always()
env:
JOB_STATUS: ${{ job.status }}
RELEASE_TAG: ${{ steps.release.outputs.tag }}
run: |
if [ "${JOB_STATUS}" == "success" ]; then
echo "Audit passed for ${RELEASE_TAG}"
echo "- SLSA attestation: verified"
echo "- Rekor entries: found"
else
echo "Audit failed for ${RELEASE_TAG}"
exit 1
fi

Deux détails du workflow comptent. La dernière release vient de l'endpoint releases/latest, car le premier élément de la liste des tags n'est pas forcément la plus récente. Et le téléchargement depuis GHCR exige une authentification : le job reçoit la permission packages: read et se connecte avec docker login, le jeton transitant par une variable d'environnement et non par une expression dans la commande.

L'étape Check Rekor entries utilise cosign verify plutôt que rekor-cli search --sha : une signature Cosign d'image est journalisée sous le hash de son payload, pas sous le digest de l'image, et la recherche par digest ne la retrouverait pas. cosign verify échoue si la signature est absente, si l'identité ne correspond pas ou si l'entrée Rekor est introuvable, ce qui fait échouer le job comme attendu. Le workflow suppose que l'image est signée en keyless par un workflow de ce même dépôt.

La recherche par email n'accepte pas de domaine : le script ci-dessous prend une liste d'adresses, retient les UUID déjà vus pour chacune dans un dossier d'état, et signale toute entrée nouvelle au passage suivant. Le premier passage sert de référence et n'alerte pas. Lancez-le à intervalle régulier (cron ou job planifié).

#!/usr/bin/env bash
# monitor-signatures.sh : signale les nouvelles entrées Rekor des identités surveillées
set -euo pipefail
EMAILS=("alice@votre-entreprise.com" "bob@votre-entreprise.com")
STATE_DIR="${HOME}/.rekor-monitor"
mkdir -p "${STATE_DIR}"
for email in "${EMAILS[@]}"; do
known="${STATE_DIR}/${email}.uuids"
# Une recherche par adresse complète. Sans résultat (ou serveur injoignable),
# rekor-cli sort en erreur : on passe à l'adresse suivante sans toucher à l'état.
if ! result="$(rekor-cli search --email "${email}" --format json 2>/dev/null)"; then
continue
fi
current="$(mktemp)"
echo "${result}" | jq -r '.UUIDs[]' | sort > "${current}"
if [ -f "${known}" ]; then
# comm -13 : lignes présentes uniquement dans la liste actuelle
comm -13 "${known}" "${current}" | while read -r uuid; do
echo "Nouvelle signature pour ${email} : ${uuid}"
# Envoyer une alerte (Slack, e-mail, etc.)
done
fi
mv "${current}" "${known}"
done

comm -13 n'affiche que les UUID présents dans la liste actuelle et absents de la précédente, c'est-à-dire les nouvelles signatures. Remplacez le commentaire par l'appel à votre outil d'alerte.

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 la communauté l'audite.

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.

Rekor privé : les clients rekor-cli passent par un load balancer TLS vers le serveur Rekor (API REST), qui s'appuie sur Redis en cache et sur Trillian (log server et log signer) adossé à MySQL ou MariaDB.rekor-cli(clients)Load Balancer(TLS/HTTPS)Rekor Server(API REST)Redis(cache)TrillianLog ServerTrillianLog SignerMySQL / MariaDB
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Voici un schéma de principe pour comprendre les briques, pas un déploiement prêt à démarrer : il manque le schéma SQL de Trillian (que l'image mariadb ne contient pas), la création de l'arbre (createtree) et son identifiant à passer à rekor-server. Pour une instance qui démarre vraiment, partez du docker-compose.yml officiel du dépôt Rekor au tag v1.5.3 :

docker-compose.yml
services:
mysql:
image: mariadb:10.11@sha256:7f22313fc130a377a44999965bcb0a08dd5b21e8502824c1b864f792f9bc66ab
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
no matching entries foundAucune entrée pour cette adresse ou ce hashVérifier l'adresse complète (pas de domaine) et le hash SHA256
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 '{treeSize, rootHash, treeID}'
# Sortie attendue (valeurs du 16 octobre 2026, elles changent en continu) :
# {
# "treeSize": 3161030760,
# "rootHash": "719aa3ac258908a5e1eff1ddc94deead07f72d169a75f3b0b0761ef9a79d2ffc",
# "treeID": "1193050959916656506"
# }

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.

Rekor garantit l'existence de l'entrée, l'authenticité de l'horodatage, l'intégrité et la non-modification du log et son auditabilité ; il ne garantit ni la qualité du code signé, ni l'absence de vulnérabilités, ni la légitimité du signataire, ni la disponibilité, ni la confidentialité.Rekor garantitRekor ne garantit pasL'entrée existe dans le logL'horodatage est authentiqueL'intégrité du logLa non-modification du logL'auditabilité publiqueLa qualité du code signéL'absence de vulnérabilitésLa légitimité du signataireLa disponibilité du serviceLa confidentialité (log public)
En résumé : Rekor prouve qui a signé quoi et quand, mais pas si c'était une bonne idée de signer. Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

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 rapide 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 7 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é ouverte : 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é

  6. Détecter, pas empêcher : Rekor rend une signature frauduleuse visible mais n'empêche ni la signature d'un compte OIDC compromis ni celle d'un code malveillant ; vérifiez en CI et surveillez vos identités

  7. Preuve attendue (SOCLE-REL-VER-2) : un journal de transparence des signatures et attestations, ici Rekor, où chaque signature publiée a une entrée retrouvable et dont la preuve d'inclusion est vérifiée par les consommateurs

Résumé Rekor : en signature keyless, Fulcio fournit le certificat, Cosign signe et Rekor journalise ; chaque entrée porte UUID, horodatage, preuve d'inclusion, hash et certificat ; rekor-cli search et rekor-cli get retrouvent les signatures ; bénéfices : non-répudiation, horodatage et auditabilité.Signature keylessFulcio(certificat)Cosign(signer)Rekor(log public)Entrée dans le logCommandes clésBénéfices clésUUID, timestampInclusion proofHash artefact, certificatrekor-cli search --email ...trouver les signaturesrekor-cli get --log-index ...voir les détailsNon-répudiationprouve l'existence d'une signatureHorodatagepreuve temporelle immuableAuditabilitélog public et vérifiable
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn