Dans le billet précédent, j’avais introduit la notion de sécurisation de la
chaine d’approvisionnement logiciel et surtout pourquoi il est important de la
mettre en place. Ce billet parle d’une première solution permettant de signer
des conteneurs OCI
avec Cosign
. L’objectif est d’intégrer ces outils dans
une CI Gitlab.
Introduction
Soutenu par le l’OpenSSF ↗ (Open Source Security
Foundation), le projet Sigstore
fonctionne comme un service de bien public à but
non lucratif.
L’objectif de Sigstore
est de fournir aux développeurs les moyens de valider que
les logiciels qu’ils utilisent sont exactement ceux attendus. Cette validation se
fait via l’utilisation de signatures numériques codées et des technologies de
journal de transparence.
Sigstore
fournit donc une suite d’outils dont :
Cosign
pour la signature d’artefacts logiciels,
l’autorité de certification Fulcio
,
le journal de confiance (ou transparence) Rekor
,
Gitsign
pour la signature des Git commits.
Ces outils peuvent être utilisés indépendamment ! Dans ce billet, nous
utiliserons seulement Cosign
. Dans un prochain billet, nous verrons comment
héberger un service de signature.
Installation de Cosign
Comme d’habitude, nous allons utiliser asdf
pour
installer Cosign
.
asdf install cosign latest
asdf global cosign latest
Dans le cas de l’utilisation de cet outil dans une CI je vous conseille
d’utiliser l’image fournie par Chainguard
.
docker run --rm cgr.dev/chainguard/cosign version
Signatures de nos artefacts
Maintenant que nous avons installé Cosign
, je vais vous montrer comment
l’utiliser conjointement avec trivy
pour stocker et signer la SBOM, le scan de
vulnérabilité et toutes autres informations dans la registry OCI
.
Création des clés
Comme dit plus ce n’est pas la meilleure des pratiques, mais tant que nous
n’aurons pas installé Fulcio
nous l’utiliserons.
Enter password for private key:
Enter password for private key again:
Private key written to cosign.key
Public key written to cosign.pub
Je n’ai pas mis de paraphrase, ce n’est pas bien ! Mais c’est pour simplifier la
démo.
Création de l’image
Je vais construire une image utilisant une image wolfi
nginx dans lequel je copie un simple fichier index.html
. Je vais utiliser la
container registry
de Gitlab qui est compatible OCI
.
J’ai créé un projet sur gitlab
et je clone le projet :
git clone git@gitlab.com:dockerfiles6/images/demo-cosign.git
Le fichier index.html
:
Le Dockerfile :
FROM cgr.dev/chainguard/nginx as deploy
# Copy what we've installed/built from production
COPY index.html /usr/share/nginx/html/
On construit, puis on pousse l’image dans la registry Gitlab. On récupère le SHA
pour le stocker dans une variable $IMAGE
(nécessaire aux commandes cosign
):
docker build -t registry.gitlab.com/dockerfiles6/images/demo-cosign:latest .
docker push registry.gitlab.com/dockerfiles6/images/demo-cosign:latest .
docker login registry.gitlab.com -u xxxxxx -p xxxxxx
export IMAGE = ` docker inspect --format= ' {{index .RepoDigests 0}} ' registry.gitlab.com/dockerfiles6/images/demo-cosign:latest`
Signature de l’image
Maintenant que notre image est stockée dans la registry, nous allons la signer
en ne stockant rien dans rekor
.
cosign sign --key cosign.key --tlog-upload=false $IMAGE
Enter password for private key:
Pushing signature to: registry.gitlab.com/dockerfiles6/images/demo-cosign
Vous avez remarqué la signature est poussée directement dans la registry. Une
petite vérification sur le site gitlab.
Et oui, nous avons bien stocké la signature.
La commande triangulate
permet d’obtenir l’adresse de l’image contentant la
signature :
cosign triangulate registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42
registry.gitlab.com/dockerfiles6/images/demo-cosign:sha256-708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42.sig
Pour en afficher le contenu je vous conseille d’utiliser crane (installé avec asdf) :
crane manifest registry.gitlab.com/dockerfiles6/images/demo-cosign:sha256-708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42.sig | jq -r .
"mediaType" : " application/vnd.oci.image.manifest.v1+json " ,
"mediaType" : " application/vnd.oci.image.config.v1+json " ,
"digest" : " sha256:c7b780b59727e119501961e1b36bb8c4f8886055a9cbfccb2f02eb43dac7e48d "
"mediaType" : " application/vnd.dev.cosign.simplesigning.v1+json " ,
"digest" : " sha256:70b7b4faa03fa820f8411fe34bd3da5421b97dc3ef0aa469f70f5a769716dfb9 " ,
"dev.cosignproject.cosign/signature" : " MEUCIFMBHH8o0EWNXEqLey4CeuJFQaUozrul6OE2zNjmTT3UAiEA9yBL38wkB5VHWeBeYxz4//0kNLUZay3vEG3PIZzuPeg= " ,
"dev.sigstore.cosign/bundle" : " { \" SignedEntryTimestamp \" : \" MEYCIQDhKL3G5/B2J9kEEOM3SNB0/hPAxaU+v16wj2k3et8arwIhAO47k68xkb/AE7E1ARISv7jbeYw771weQlyJDk5KlpUl \" , \" Payload \" :{ \" body \" : \" eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI3MGI3YjRmYWEwM2ZhODIwZjg0MTFmZTM0YmQzZGE1NDIxYjk3ZGMzZWYwYWE0NjlmNzBmNWE3Njk3MTZkZmI5In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRk1CSEg4bzBFV05YRXFMZXk0Q2V1SkZRYVVvenJ1bDZPRTJ6TmptVFQzVUFpRUE5eUJMMzh3a0I1VkhXZUJlWXh6NC8vMGtOTFVaYXkzdkVHM1BJWnp1UGVnPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGVlV0SWRXNXNTR015YTFOeFIyOVpNalJMZG1kWGVFbENNVUZYY1FwV2JFUk1kMnRQV2pZeGEyY3laVW92ZEU1cWRGZFZiVkJzTlc1TlJsRlZaeTlxWkdOdGNDODNTbHB2Y1VGMWNVMVJlVGt3T0dNeU56bFJQVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0= \" , \" integratedTime \" :1692622355, \" logIndex \" :32118650, \" logID \" : \" c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d \" }} "
Vérification de la signature de l’image
Nous allons demander si l’image stockée dans la registry est bien celle qui a
été signée.
cosign verify --key cosign.pub --insecure-ignore-tlog=true $IMAGE
WARNING: Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the signature.
Verification for registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[{ " critical " :{ " identity " :{ " docker-reference " : " registry.gitlab.com/dockerfiles6/images/demo-cosign " }, " image " :{ " docker-manifest-digest " : " sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 " }, " type " : " cosign container image signature " }, " optional " :{ " Bundle " :{ " SignedEntryTimestamp " : " MEYCIQDhKL3G5/B2J9kEEOM3SNB0/hPAxaU+v16wj2k3et8arwIhAO47k68xkb/AE7E1ARISv7jbeYw771weQlyJDk5KlpUl " , " Payload " :{ " body " : " eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI3MGI3YjRmYWEwM2ZhODIwZjg0MTFmZTM0YmQzZGE1NDIxYjk3ZGMzZWYwYWE0NjlmNzBmNWE3Njk3MTZkZmI5In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRk1CSEg4bzBFV05YRXFMZXk0Q2V1SkZRYVVvenJ1bDZPRTJ6TmptVFQzVUFpRUE5eUJMMzh3a0I1VkhXZUJlWXh6NC8vMGtOTFVaYXkzdkVHM1BJWnp1UGVnPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCUVZVSk1TVU1nUzBWWkxTMHRMUzBLVFVacmQwVjNXVWhMYjFwSmVtb3dRMEZSV1VsTGIxcEplbW93UkVGUlkwUlJaMEZGVlV0SWRXNXNTR015YTFOeFIyOVpNalJMZG1kWGVFbENNVUZYY1FwV2JFUk1kMnRQV2pZeGEyY3laVW92ZEU1cWRGZFZiVkJzTlc1TlJsRlZaeTlxWkdOdGNDODNTbHB2Y1VGMWNVMVJlVGt3T0dNeU56bFJQVDBLTFMwdExTMUZUa1FnVUZWQ1RFbERJRXRGV1MwdExTMHRDZz09In19fX0= " , " integratedTime " :1692622355, " logIndex " :32118650, " logID " : " c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d " }}}}]
Cela fonctionne ! En testant avec une autre clé publique :
Enter password for private key:
Enter password for private key again:
Private key written to cosign.key
Public key written to cosign.pub
cosign verify --key cosign.pub --insecure-ignore-tlog=true $IMAGE
WARNING: Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the signature.
Error: no matching signatures: invalid signature when validating ASN.1 encoded signature
main.go:69: error during command execution: no matching signatures: invalid signature when validating ASN.1 encoded signature
Attachement de la SBOM
Nous allons générer la nomenclature de l’image pour la stocker avec trivy
:
trivy i --format cosign-vuln $IMAGE > image.sbom
2023-08-21T15:10:19.697+0200 INFO Need to update DB
2023-08-21T15:10:19.697+0200 INFO DB Repository: ghcr.io/aquasecurity/trivy-db
2023-08-21T15:10:19.697+0200 INFO Downloading DB...
39.00 MiB / 39.00 MiB [-----------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 13.24 MiB p/s 3.1s
2023-08-21T15:10:23.811+0200 INFO Vulnerability scanning is enabled
2023-08-21T15:10:23.811+0200 INFO Secret scanning is enabled
2023-08-21T15:10:23.811+0200 INFO If your scanning is slow, please try ' --scanners vuln ' to disable secret scanning
2023-08-21T15:10:23.811+0200 INFO Please see also https://aquasecurity.github.io/trivy/v0.43/docs/scanner/secret/#recommendation for faster secret detection
2023-08-21T15:10:24.036+0200 INFO Detected OS: wolfi
2023-08-21T15:10:24.036+0200 INFO Detecting Wolfi vulnerabilities...
2023-08-21T15:10:24.037+0200 INFO Number of language-specific files: 0
Reste plus qu’à la joindre à notre image dans la registry avec cosign
:
cosign attach sbom --sbom image.sbom $IMAGE
Enter password for private key:
Using payload from: image.sbom
Un petit tout sur le site de Gitlab.
On retrouve bien l’attestation.
Vérification de l’attestation
On va utiliser la commande verify-attestion
:
cosign verify-attestation --key cosign.pub --insecure-ignore-tlog=true $IMAGE
WARNING: Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the attestation.
Verification for registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
{"payloadType":"application/vnd.in-toto+json","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2Nvc2lnbi5zaWdzdG9yZS5kZXYvYXR0ZXN0YXRpb24vdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoicmVnaXN0cnkuZ2l0bGFiLmNvbS9kb2NrZXJmaWxlczYvaW1hZ2VzL2RlbW8tY29zaWduIiwiZGlnZXN0Ijp7InNoYTI1NiI6IjcwOGU0ZTdhMjljMzE2ZmM1MTY1MDQzN2IzNjRiOTMyYjMwZjUwMGM5MDE0ZDU4NjA3M2VhMjZmODE5YjRlNDIifX1dLCJwcmVkaWNhdGUiOnsiRGF0YSI6IntcbiAgXCJpbnZvY2F0aW9uXCI6IHtcbiAgICBcInBhcmFtZXRlcnNcIjogbnVsbCxcbiAgICBcInVyaVwiOiBcIlwiLFxuICAgIFwiZXZlbnRfaWRcIjogXCJcIixcbiAgICBcImJ1aWxkZXIuaWRcIjogXCJcIlxuICB9LFxuICBcInNjYW5uZXJcIjoge1xuICAgIFwidXJpXCI6IFwicGtnOmdpdGh1Yi9hcXVhc2VjdXJpdHkvdHJpdnlAMC40My4xXCIsXG4gICAgXCJ2ZXJzaW9uXCI6IFwiMC40My4xXCIsXG4gICAgXCJkYlwiOiB7XG4gICAgICBcInVyaVwiOiBcIlwiLFxuICAgICAgXCJ2ZXJzaW9uXCI6IFwiXCJcbiAgICB9LFxuICAgIFwicmVzdWx0XCI6IHtcbiAgICAgIFwiU2NoZW1hVmVyc2lvblwiOiAyLFxuICAgICAgXCJBcnRpZmFjdE5hbWVcIjogXCJyZWdpc3RyeS5naXRsYWIuY29tL2RvY2tlcmZpbGVzNi9pbWFnZXMvZGVtby1jb3NpZ25Ac2hhMjU2OjcwOGU0ZTdhMjljMzE2ZmM1MTY1MDQzN2IzNjRiOTMyYjMwZjUwMGM5MDE0ZDU4NjA3M2VhMjZmODE5YjRlNDJcIixcbiAgICAgIFwiQXJ0aWZhY3RUeXBlXCI6IFwiY29udGFpbmVyX2ltYWdlXCIsXG4gICAgICBcIk1ldGFkYXRhXCI6IHtcbiAgICAgICAgXCJPU1wiOiB7XG4gICAgICAgICAgXCJGYW1pbHlcIjogXCJ3b2xmaVwiLFxuICAgICAgICAgIFwiTmFtZVwiOiBcIjIwMjMwMjAxXCJcbiAgICAgICAgfSxcbiAgICAgICAgXCJJbWFnZUlEXCI6IFwic2hhMjU2OjdiMWY2MjllN2E2YzM0OGE5Njc2Y2Q3ZWJlYmI4MDU2NzRkYjMyYjgwNTQ5NGZjMDM3ZWUzZWM3ZWY2OWEwNWJcIixcbiAgICAgICAgXCJEaWZmSURzXCI6IFtcbiAgICAgICAgICBcInNoYTI1Njo0YmQ3NGM0NmJlYmFhOGJkZWEyZmY0NDQ3Yjc0YmJkODI5NDQ3MTFhZWRiOGZiZGE4Yjc0YzE3NzIxN2RiODcwXCIsXG4gICAgICAgICAgXCJzaGEyNTY6YzBjMjdmNWFkOTQzMjRiNzc4NWYxMjAzMzQ2NDQ5MDBlMDc2ZmE4NjEwNTExYzBjMzk3ZGMyNGNiMjU2YjIwYVwiXG4gICAgICAgIF0sXG4gICAgICAgIFwiUmVwb1RhZ3NcIjogW1xuICAgICAgICAgIFwicmVnaXN0cnkuZ2l0bGFiLmNvbS9kb2NrZXJmaWxlczYvaW1hZ2VzL2RlbW8tY29zaWduOmxhdGVzdFwiXG4gICAgICAgIF0sXG4gICAgICAgIFwiUmVwb0RpZ2VzdHNcIjogW1xuICAgICAgICAgIFwicmVnaXN0cnkuZ2l0bGFiLmNvbS9kb2NrZXJmaWxlczYvaW1hZ2VzL2RlbW8tY29zaWduQHNoYTI1Njo3MDhlNGU3YTI5YzMxNmZjNTE2NTA0MzdiMzY0YjkzMmIzMGY1MDBjOTAxNGQ1ODYwNzNlYTI2ZjgxOWI0ZTQyXCJcbiAgICAgICAgXSxcbiAgICAgICAgXCJJbWFnZUNvbmZpZ1wiOiB7XG4gICAgICAgICAgXCJhcmNoaXRlY3R1cmVcIjogXCJhbWQ2NFwiLFxuICAgICAgICAgIFwiYXV0aG9yXCI6IFwiZ2l0aHViLmNvbS9jaGFpbmd1YXJkLWRldi9hcGtvXCIsXG4gICAgICAgICAgXCJjcmVhdGVkXCI6IFwiMjAyMy0wOC0yMVQxNDozNjo0OS42NTE1MTkxNiswMjowMFwiLFxuICAgICAgICAgIFwiaGlzdG9yeVwiOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFwiY3JlYXRlZFwiOiBcIjIwMjMtMDgtMDNUMDY6MjM6MjlaXCIsXG4gICAgICAgICAgICAgIFwiY3JlYXRlZF9ieVwiOiBcImFwa29cIixcbiAgICAgICAgICAgICAgXCJjb21tZW50XCI6IFwiVGhpcyBpcyBhbiBhcGtvIHNpbmdsZS1sYXllciBpbWFnZVwiXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBcImNyZWF0ZWRcIjogXCIyMDIzLTA4LTIxVDEyOjM2OjQ5WlwiLFxuICAgICAgICAgICAgICBcImNyZWF0ZWRfYnlcIjogXCJDT1BZIGluZGV4Lmh0bWwgL3Vzci9zaGFyZS9uZ2lueC9odG1sLyAjIGJ1aWxka2l0XCIsXG4gICAgICAgICAgICAgIFwiY29tbWVudFwiOiBcImJ1aWxka2l0LmRvY2tlcmZpbGUudjBcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgIF0sXG4gICAgICAgICAgXCJvc1wiOiBcImxpbnV4XCIsXG4gICAgICAgICAgXCJyb290ZnNcIjoge1xuICAgICAgICAgICAgXCJ0eXBlXCI6IFwibGF5ZXJzXCIsXG4gICAgICAgICAgICBcImRpZmZfaWRzXCI6IFtcbiAgICAgICAgICAgICAgXCJzaGEyNTY6NGJkNzRjNDZiZWJhYThiZGVhMmZmNDQ0N2I3NGJiZDgyOTQ0NzExYWVkYjhmYmRhOGI3NGMxNzcyMTdkYjg3MFwiLFxuICAgICAgICAgICAgICBcInNoYTI1NjpjMGMyN2Y1YWQ5NDMyNGI3Nzg1ZjEyMDMzNDY0NDkwMGUwNzZmYTg2MTA1MTFjMGMzOTdkYzI0Y2IyNTZiMjBhXCJcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9LFxuICAgICAgICAgIFwiY29uZmlnXCI6IHtcbiAgICAgICAgICAgIFwiQ21kXCI6IFtcbiAgICAgICAgICAgICAgXCItY1wiLFxuICAgICAgICAgICAgICBcIi9ldGMvbmdpbngvbmdpbnguY29uZlwiLFxuICAgICAgICAgICAgICBcIi1lXCIsXG4gICAgICAgICAgICAgIFwiL2Rldi9zdGRlcnJcIixcbiAgICAgICAgICAgICAgXCItZ1wiLFxuICAgICAgICAgICAgICBcImRhZW1vbiBvZmY7XCJcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIkVudHJ5cG9pbnRcIjogW1xuICAgICAgICAgICAgICBcIi91c3Ivc2Jpbi9uZ2lueFwiXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgXCJFbnZcIjogW1xuICAgICAgICAgICAgICBcIlBBVEg9L3Vzci9sb2NhbC9zYmluOi91c3IvbG9jYWwvYmluOi91c3Ivc2JpbjovdXNyL2Jpbjovc2JpbjovYmluXCIsXG4gICAgICAgICAgICAgIFwiU1NMX0NFUlRfRklMRT0vZXRjL3NzbC9jZXJ0cy9jYS1jZXJ0aWZpY2F0ZXMuY3J0XCJcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIlVzZXJcIjogXCI2NTUzMlwiLFxuICAgICAgICAgICAgXCJTdG9wU2lnbmFsXCI6IFwiU0lHUVVJVFwiXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgXCJSZXN1bHRzXCI6IFtcbiAgICAgICAge1xuICAgICAgICAgIFwiVGFyZ2V0XCI6IFwicmVnaXN0cnkuZ2l0bGFiLmNvbS9kb2NrZXJmaWxlczYvaW1hZ2VzL2RlbW8tY29zaWduQHNoYTI1Njo3MDhlNGU3YTI5YzMxNmZjNTE2NTA0MzdiMzY0YjkzMmIzMGY1MDBjOTAxNGQ1ODYwNzNlYTI2ZjgxOWI0ZTQyICh3b2xmaSAyMDIzMDIwMSlcIixcbiAgICAgICAgICBcIkNsYXNzXCI6IFwib3MtcGtnc1wiLFxuICAgICAgICAgIFwiVHlwZVwiOiBcIndvbGZpXCJcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH1cbiAgfSxcbiAgXCJtZXRhZGF0YVwiOiB7XG4gICAgXCJzY2FuU3RhcnRlZE9uXCI6IFwiMjAyMy0wOC0yMVQxNToyMDowNi45MzE4MDI3NjErMDI6MDBcIixcbiAgICBcInNjYW5GaW5pc2hlZE9uXCI6IFwiMjAyMy0wOC0yMVQxNToyMDowNi45MzE4MDI3NjErMDI6MDBcIlxuICB9XG59IiwiVGltZXN0YW1wIjoiMjAyMy0wOC0yMVQxMzoyMDo1OVoifX0=","signatures":[{"keyid":"","sig":"MEUCIChqDJdq7epCXd7kpeFwefRJkxZXF3tbc5aLxWUl286mAiEAzAh871hfGDNuaEQAMI5rydgLP0lss50dhmAcbHld4J8="}]}
Pour visualiser le contenu de la payload un petit coup de jq
:
cosign verify-attestation --key cosign.pub --insecure-ignore-tlog=true $IMAGE | jq -r .payload | base64 -d | jq .
WARNING: Skipping tlog verification is an insecure practice that lacks of transparency and auditability verification for the attestation.
Verification for registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
"_type" : " https://in-toto.io/Statement/v0.1 " ,
"predicateType" : " https://cosign.sigstore.dev/attestation/v1 " ,
"name" : " registry.gitlab.com/dockerfiles6/images/demo-cosign " ,
"sha256" : " 708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 "
"Data" : " {\n \" invocation \" : {\n \" parameters \" : null,\n \" uri \" : \"\" ,\n \" event_id \" : \"\" ,\n \" builder.id \" : \"\" \n },\n \" scanner \" : {\n \" uri \" : \" pkg:github/aquasecurity/trivy@0.43.1 \" ,\n \" version \" : \" 0.43.1 \" ,\n \" db \" : {\n \" uri \" : \"\" ,\n \" version \" : \"\" \n },\n \" result \" : {\n \" SchemaVersion \" : 2,\n \" ArtifactName \" : \" registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 \" ,\n \" ArtifactType \" : \" container_image \" ,\n \" Metadata \" : {\n \" OS \" : {\n \" Family \" : \" wolfi \" ,\n \" Name \" : \" 20230201 \" \n },\n \" ImageID \" : \" sha256:7b1f629e7a6c348a9676cd7ebebb805674db32b805494fc037ee3ec7ef69a05b \" ,\n \" DiffIDs \" : [\n \" sha256:4bd74c46bebaa8bdea2ff4447b74bbd82944711aedb8fbda8b74c177217db870 \" ,\n \" sha256:c0c27f5ad94324b7785f120334644900e076fa8610511c0c397dc24cb256b20a \" \n ],\n \" RepoTags \" : [\n \" registry.gitlab.com/dockerfiles6/images/demo-cosign:latest \" \n ],\n \" RepoDigests \" : [\n \" registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 \" \n ],\n \" ImageConfig \" : {\n \" architecture \" : \" amd64 \" ,\n \" author \" : \" github.com/chainguard-dev/apko \" ,\n \" created \" : \" 2023-08-21T14:36:49.65151916+02:00 \" ,\n \" history \" : [\n {\n \" created \" : \" 2023-08-03T06:23:29Z \" ,\n \" created_by \" : \" apko \" ,\n \" comment \" : \" This is an apko single-layer image \" \n },\n {\n \" created \" : \" 2023-08-21T12:36:49Z \" ,\n \" created_by \" : \" COPY index.html /usr/share/nginx/html/ # buildkit \" ,\n \" comment \" : \" buildkit.dockerfile.v0 \" \n }\n ],\n \" os \" : \" linux \" ,\n \" rootfs \" : {\n \" type \" : \" layers \" ,\n \" diff_ids \" : [\n \" sha256:4bd74c46bebaa8bdea2ff4447b74bbd82944711aedb8fbda8b74c177217db870 \" ,\n \" sha256:c0c27f5ad94324b7785f120334644900e076fa8610511c0c397dc24cb256b20a \" \n ]\n },\n \" config \" : {\n \" Cmd \" : [\n \" -c \" ,\n \" /etc/nginx/nginx.conf \" ,\n \" -e \" ,\n \" /dev/stderr \" ,\n \" -g \" ,\n \" daemon off; \" \n ],\n \" Entrypoint \" : [\n \" /usr/sbin/nginx \" \n ],\n \" Env \" : [\n \" PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \" ,\n \" SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \" \n ],\n \" User \" : \" 65532 \" ,\n \" StopSignal \" : \" SIGQUIT \" \n }\n }\n },\n \" Results \" : [\n {\n \" Target \" : \" registry.gitlab.com/dockerfiles6/images/demo-cosign@sha256:708e4e7a29c316fc51650437b364b932b30f500c9014d586073ea26f819b4e42 (wolfi 20230201) \" ,\n \" Class \" : \" os-pkgs \" ,\n \" Type \" : \" wolfi \" \n }\n ]\n }\n },\n \" metadata \" : {\n \" scanStartedOn \" : \" 2023-08-21T15:20:06.931802761+02:00 \" ,\n \" scanFinishedOn \" : \" 2023-08-21T15:20:06.931802761+02:00 \" \n }\n} " ,
"Timestamp" : " 2023-08-21T13:20:59Z "
Plus loin
Avant tout, je tiens à remercier
leila ↗ qui m’a fourni pas mal
d’informations pour élaborer ce billet. Comme dit plus haut cette solution est
incomplète sans les autres outils. Nous verrons donc dans un prochain billet
comment installer et utiliser rekor
,
puis fulcio
.
Par la suite, nous verrons aussi comment contrôler les images avec kyverno
avant
qu’elles soient déployées dans un cluster kubernetes
.