Cosign signature and verification
- Cosign Signature Verification
- Deterministic container hashes and container signing using Cosign, Kaniko and Google Cloud Build
export IMAGE_DIGEST=docker.io/salrashid123/myimage@sha256:9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049
$ cosign generate-key-pair
this sample uses the private key showed at the end
with fingerprint
$ openssl ec -pubin -inform PEM -in cosign.pub -outform DER | openssl dgst -sha256 | cut -d" " -f2
read EC key
writing EC key
2b20bfe7bb76a7405dfcc75193e7768c41c1fffa28aeabc15e7ad21b0fdc9a89
## get public key to attach to annotation
$ PUB=$(cat cosign.pub | openssl base64)
$ PUB=$(echo $PUB | tr -d '[:space:]' | sed 's/[=]*$//')
$ echo $PUB
$ COSIGN_REPOSITORY=docker.io/salrashid123/myimage
$ cosign sign --key cosign.key \
-a dev.cosignproject.cosign/sigalg=ECDSA_P256_SHA256 \
-a dev.cosignproject.cosign/pub=$PUB --tlog-upload=false --upload=true $IMAGE_DIGEST
### (passphrase `123456`)
$ cosign verify --insecure-ignore-tlog=true --key=cosign.pub $IMAGE_DIGEST | jq '.'
Verification for index.docker.io/salrashid123/myimage@sha256:9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049 --
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": "index.docker.io/salrashid123/myimage"
},
"image": {
"docker-manifest-digest": "sha256:9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049"
},
"type": "cosign container image signature"
},
"optional": {
"dev.cosignproject.cosign/pub": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFMXY3UXFmcGlsVzdNMGhQS2g5QnJjd1NjT05OMQo5cm1IaDR5QVJVV2t4V0s0T3NOZ1FHZlErMTVTYnJrMHRsc1I0c2cyNmdhTHVIZ1A4S0ZzWEJIN0R3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg",
"dev.cosignproject.cosign/sigalg": "ECDSA_P256_SHA256"
}
}
]
## use skopeo to inspect the signature
$ skopeo inspect --raw docker://$(cosign triangulate --type=signature $IMAGE_DIGEST) | jq -r
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 233,
"digest": "sha256:5da2a409c793152d0c60272c212ba07d3e26b269745035265523bffe15042ad5"
},
"layers": [
{
"mediaType": "application/vnd.dev.cosign.simplesigning.v1+json",
"size": 575,
"digest": "sha256:c4b23792287419c78695c260c7a17f1c8ec5f661b16be14ce8e696398073beac",
"annotations": {
"dev.cosignproject.cosign/signature": "MEUCIAoXDplWGo0Tn2K1E/Ny2kiTHhdN1+i06d7Pu/FVN1EkAiEA2ggnIc7AVnPcmM5R/7w1hNshpOfpY0d7GJ3+bJJwcSA="
}
}
]
}
use predicates values to set
$ cat predicates.json
{ "foo":"bar"}
and a rego (to validate with)
$ cat policy.rego
package signature
import data.signature.verified
default allow = false
allow {
input.predicateType == "https://cosign.sigstore.dev/attestation/v1"
predicates := json.unmarshal(input.predicate.Data)
predicates.foo == "bar"
}
Now attest
$ cosign attest --tlog-upload=false --key cosign.key --predicate=predicates.json $IMAGE_DIGEST
## use skopeo to inspect the attestation
$ skopeo inspect --raw docker://$(cosign triangulate --type=attestation $IMAGE_DIGEST) | jq -r
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 233,
"digest": "sha256:dda6106d75509a5296c3c1e89e49c5b6c5f94322be4d8336e8ed8813bd0ca8a8"
},
"layers": [
{
"mediaType": "application/vnd.dsse.envelope.v1+json",
"size": 632,
"digest": "sha256:d98b12f07edd80f40eb67be2235b42d94bc759f1ed98023d19595031dc6c1543",
"annotations": {
"dev.cosignproject.cosign/signature": "",
"predicateType": "https://cosign.sigstore.dev/attestation/v1"
}
}
]
}
## now verify the attestation using policy.rego
$ cosign verify-attestation --insecure-ignore-tlog=true --key cosign.pub --policy policy.rego $IMAGE_DIGEST
Verification for docker.io/salrashid123/myimage@sha256:9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049 --
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": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2Nvc2lnbi5zaWdzdG9yZS5kZXYvYXR0ZXN0YXRpb24vdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiaW5kZXguZG9ja2VyLmlvL3NhbHJhc2hpZDEyMy9teWltYWdlIiwiZGlnZXN0Ijp7InNoYTI1NiI6IjllYzA2NTY5ZjFjMTY5ZDRjNWIzODBjNjRiODAzZDI4NzQ2OGQ5NTQyOWRhYjRlNDQ0OTg0MmY5M2EyNTIwNDkifX1dLCJwcmVkaWNhdGUiOnsiRGF0YSI6InsgXCJmb29cIjpcImJhclwifSIsIlRpbWVzdGFtcCI6IjIwMjMtMTAtMTBUMTM6MzA6NTFaIn19",
"signatures": [
{
"keyid": "",
"sig": "MEQCIGy+iCUUBTYJOMD54G0fuxnObrE7vbmxKOOLzbd4YVUVAiBWZvCO3sa5jOlu1c6wxNOFYqkkWo2ASbZl42LSWYIshg=="
}
]
}
finally, expanding the payload shows the predicates are included
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://cosign.sigstore.dev/attestation/v1",
"subject": [
{
"name": "index.docker.io/salrashid123/myimage",
"digest": {
"sha256": "9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049"
}
}
],
"predicate": {
"Data": "{ \"foo\":\"bar\"}",
"Timestamp": "2023-10-10T13:30:51Z"
}
}
cosign sign --key cosign.key \
-a dev.cosignproject.cosign/sigalg=ECDSA_P256_SHA256 \
-a dev.cosignproject.cosign/pub=$PUB --tlog-upload=false \
--upload=false --output-signature=signature.dat --output-payload=payload.dat --upload=false $IMAGE_DIGEST
$ cat signature.dat
MEUCIQCyv9LMBeJEg636DLIL3cc23WRFOClmYH3ykxSCz4UjDAIgZto0uV0Jy55ZTIFoGcKf3YRqgjhWsORvjo6AeLK17ZE
$ cat payload.dat | jq '.'
{
"critical": {
"identity": {
"docker-reference": "index.docker.io/salrashid123/myimage"
},
"image": {
"docker-manifest-digest": "sha256:9ec06569f1c169d4c5b380c64b803d287468d95429dab4e4449842f93a252049"
},
"type": "cosign container image signature"
},
"optional": {
"dev.cosignproject.cosign/pub": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFMXY3UXFmcGlsVzdNMGhQS2g5QnJjd1NjT05OMQo5cm1IaDR5QVJVV2t4V0s0T3NOZ1FHZlErMTVTYnJrMHRsc1I0c2cyNmdhTHVIZ1A4S0ZzWEJIN0R3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg",
"dev.cosignproject.cosign/sigalg": "ECDSA_P256_SHA256"
}
}
cosign.pub
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1v7QqfpilW7M0hPKh9BrcwScONN1
9rmHh4yARUWkxWK4OsNgQGfQ+15Sbrk0tlsR4sg26gaLuHgP8KFsXBH7Dw==
-----END PUBLIC KEY-----
cosign.key
(passphrase123456
)
-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
eyJrZGYiOnsibmFtZSI6InNjcnlwdCIsInBhcmFtcyI6eyJOIjo2NTUzNiwiciI6
OCwicCI6MX0sInNhbHQiOiIyL2tOZlAxSXFVMEszNndTZEg4b2hnUHBkUWV0YllD
c0hxT0VoaGd5SmhZPSJ9LCJjaXBoZXIiOnsibmFtZSI6Im5hY2wvc2VjcmV0Ym94
Iiwibm9uY2UiOiJYZEpQdEZPYytrMDE5MDcvTEVQZmJ1U0t2ZkR0TG4rTyJ9LCJj
aXBoZXJ0ZXh0IjoiODMrYXlIRHozcDNQTldyTG5aTFRXRnNnZFowa2gzVE9HY0RG
V0FXUU1HbWZ0WmMzaEtjejlHMlViTjB3Ry90OXVWUlNOL0VTMkhDcm9MTWdTd3A4
Tk5QZnRGWmlBZGhLZWVOWlM0MjBMa3VSSzdVZ0N1U010NUtiVDU2cnpFTkhVcnNJ
eFd2MjV2eVJpUEpYN3NVVEdyQUl0aGRuUkdpcEgwaGdPQmpaUGZKN01MSnFBUjFk
LzhqK0ErN2ExSGdsdnpGY3FDWTgwY0FHcVE9PSJ9
-----END ENCRYPTED SIGSTORE PRIVATE KEY-----