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

Flux CD, Vérifier la signature des artefacts avec Cosign

Par mis à jour le

Améliorer cette page

Un registre peut servir un artefact altéré : un tag repoussé avec un autre contenu, un compte de publication compromis, un artefact poussé par erreur. Flux sait refuser tout ce qui n'est pas signé par une source de confiance : une OCIRepository dotée de spec.verify vérifie la signature Cosign de chaque artefact avant de le transmettre aux contrôleurs qui l'appliquent. Cette leçon signe les manifestes du fil rouge, puis tente de faire passer un artefact signé par une autre clé, un tag réécrit et une mauvaise identité. Chaque refus a été observé sur le cluster de test en Flux 2.9.6, avec Cosign 3.1.1.

  • Signer un artefact OCI avec une paire de clés Cosign
  • Exiger la signature avec spec.verify sur une OCIRepository
  • Vérifier une signature sans clé par l'identité OIDC du signataire
  • Lire la condition SourceVerified et ses messages d'échec
  • Comprendre ce que Flux continue de servir quand la vérification échoue

Cette leçon prolonge la publication d'artefacts. Cosign lui-même est présenté dans un guide dédié du site.

Un digest garantit qu'un contenu n'a pas changé, mais pas qui l'a publié : quiconque peut pousser dans le registre peut publier un artefact avec son propre digest. La signature ajoute la preuve d'origine. Avec spec.verify, Flux ne transmet aux consommateurs qu'un artefact signé par une clé ou une identité que vous avez déclarée de confiance.

Ce qui est vérifiéAvec quoiCe que ça prouve
Signature par clé publiqueUn Secret contenant les clés .pubLe signataire détient la clé privée correspondante
Signature sans clé (keyless)L'émetteur et le sujet OIDC attendusLe signataire est un workflow ou une personne précise

Une paire de clés Cosign se génère une fois. La clé privée, protégée par une phrase de passe, reste dans la CI ; la clé publique va dans le cluster. La signature vise toujours un digest, jamais un tag :

Fenêtre de terminal
cosign generate-key-pair # cosign.key et cosign.pub
DIG=$(crane digest localhost:5000/manifests/shop:1.1.0)
cosign sign --key cosign.key --use-signing-config=false --tlog-upload=false \
"localhost:5000/manifests/shop@${DIG}"

Les deux options finales désactivent l'envoi au journal de transparence public Rekor, inutile sur un registre de lab privé ; en production avec des artefacts publics, on les retire. La signature est rangée dans le même dépôt du registre, sous un tag sha256-<digest> : ce sont les tags que l'on voit apparaître à côté des versions dans un registre qui signe.

Côté cluster, la clé publique entre dans un Secret dont chaque clé porte l'extension .pub, et l'OCIRepository l'exige avec spec.verify :

Fenêtre de terminal
kubectl -n flux-system create secret generic cosign-pub --from-file=cosign.pub=cosign.pub
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: shop-manifests
namespace: flux-system
spec:
interval: 1m
url: oci://registry-flux:5000/manifests/shop
insecure: true
ref:
semver: ">=1.0.0"
verify:
provider: cosign
secretRef:
name: cosign-pub
SourceVerified=True Succeeded: verified signature of revision 1.1.0@sha256:ee0ad3617d4b…

La condition SourceVerified s'ajoute aux conditions habituelles de la source. Plusieurs clés .pub dans le Secret sont toutes essayées : c'est ce qui permet une rotation de clé sans invalider les artefacts déjà signés.

Que se passe-t-il quand la vérification échoue ?

Section intitulée « Que se passe-t-il quand la vérification échoue ? »

Trois tentatives ont été menées contre cette source. Le point important n'est pas le message, mais l'artefact servi ensuite : la dernière révision vérifiée, jamais la nouvelle.

TentativeMessageArtefact servi ensuite
Avant toute signatureno matching signatures were found for '…@sha256:ee0ad3…'aucun nouveau
1.2.0 signé par une autre cléno matching signatures were found for '…@sha256:b59c19…'1.1.0@sha256:ee0ad3…
1.1.0 repoussé avec un autre contenuno matching signatures were found for '…@sha256:8bfc94…'1.1.0@sha256:ee0ad3…

Le troisième cas est celui qu'un épinglage par tag ne voit pas : le tag 1.1.0 désigne désormais un autre contenu, que personne n'a signé. Flux le refuse, et la Kustomization continue d'appliquer l'artefact signé d'origine. La source passe READY: False, ce qui déclenche une alerte si elle est configurée : le refus est visible, pas silencieux.

Vérifier sans clé, par l'identité du signataire

Section intitulée « Vérifier sans clé, par l'identité du signataire »

Avec la signature sans clé de Sigstore, le signataire n'a pas de clé longue durée : la CI obtient un certificat éphémère lié à son identité OIDC, par exemple le workflow GitHub qui publie la release. Flux vérifie alors l'émetteur et le sujet du certificat avec matchOIDCIdentity, deux expressions régulières :

apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: podinfo-signe
namespace: sources
spec:
interval: 10m
url: oci://ghcr.io/stefanprodan/manifests/podinfo
ref:
tag: 6.15.0
verify:
provider: cosign
matchOIDCIdentity:
- issuer: "^https://token.actions.githubusercontent.com$"
subject: "^https://github.com/stefanprodan/podinfo.*$"
SourceVerified=True Succeeded: verified signature of revision 6.15.0@sha256:87815bbd58f5…

Avec un sujet qui ne correspond pas, la vérification échoue, et le message nomme l'identité réelle du signataire :

failed to verify the signature using provider 'cosign keyless': no matching attestations:
failed to verify certificate identity: no matching CertificateIdentity found,
last error: expected SAN value to match regex "^https://github.com/mon-org/.*$",
got "https://github.com/stefanprodan/podinfo/.github/workflows/release.yml@refs/tags/6.15.0"

Ce message est une bonne façon de découvrir l'identité à déclarer : un workflow précis, à un tag précis. Restreindre le sujet au workflow de release, plutôt qu'à tout le dépôt, empêche qu'un autre workflow du même dépôt puisse publier un artefact accepté.

  • Un digest prouve qu'un contenu n'a pas changé ; une signature prouve qui l'a publié.
  • spec.verify avec provider: cosign et un Secret de clés .pub exige une signature par clé ; la condition SourceVerified en rend compte.
  • Un artefact non signé, signé par une autre clé ou repoussé sous un tag existant est refusé, et Flux continue de servir la dernière révision vérifiée.
  • La vérification sans clé contrôle l'émetteur et le sujet OIDC du signataire avec matchOIDCIdentity.
  • En cas d'échec, le message donne l'identité réelle : restreignez le sujet au workflow de release.

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