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.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Signer un artefact OCI avec une paire de clés Cosign
- Exiger la signature avec
spec.verifysur une OCIRepository - Vérifier une signature sans clé par l'identité OIDC du signataire
- Lire la condition
SourceVerifiedet ses messages d'échec - Comprendre ce que Flux continue de servir quand la vérification échoue
Prérequis
Section intitulée « Prérequis »Cette leçon prolonge la publication d'artefacts. Cosign lui-même est présenté dans un guide dédié du site.
- La leçon Artefacts OCI
- Les bases de la signature : Cosign
Pourquoi vérifier une signature ?
Section intitulée « Pourquoi vérifier une signature ? »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 quoi | Ce que ça prouve |
|---|---|---|
| Signature par clé publique | Un Secret contenant les clés .pub | Le signataire détient la clé privée correspondante |
| Signature sans clé (keyless) | L'émetteur et le sujet OIDC attendus | Le signataire est un workflow ou une personne précise |
Signer et exiger la signature par clé
Section intitulée « Signer et exiger la signature par clé »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 :
cosign generate-key-pair # cosign.key et cosign.pubDIG=$(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 :
kubectl -n flux-system create secret generic cosign-pub --from-file=cosign.pub=cosign.pubapiVersion: source.toolkit.fluxcd.io/v1kind: OCIRepositorymetadata: name: shop-manifests namespace: flux-systemspec: interval: 1m url: oci://registry-flux:5000/manifests/shop insecure: true ref: semver: ">=1.0.0" verify: provider: cosign secretRef: name: cosign-pubSourceVerified=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.
| Tentative | Message | Artefact servi ensuite |
|---|---|---|
| Avant toute signature | no 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 contenu | no 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/v1kind: OCIRepositorymetadata: name: podinfo-signe namespace: sourcesspec: 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é.
À retenir
Section intitulée « À retenir »- Un digest prouve qu'un contenu n'a pas changé ; une signature prouve qui l'a publié.
spec.verifyavecprovider: cosignet un Secret de clés.pubexige une signature par clé ; la conditionSourceVerifieden 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.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »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
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
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Durcir Flux
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications