-
Notifications
You must be signed in to change notification settings - Fork 552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I upload a detached cosign container image signature to the Rekor transparency log? #3457
Comments
Hey @paulsavoie , I looked into this. Whatever the above you tried is totally correct. You uploaded What we can do is get the Btw, i tried to get the
|
Hey @paulsavoie , on replicating your whole process with one replacement, i.e. using Process and steps will be:
$ cat rekor_bundle.json | jq
{
"SignedEntryTimestamp": "MEUCICgM9CCtcMXPKCIeyInCxRSwXfEE7p26tOsp754tNllqAiEArw8QbChGn6n15TEG4yJaBJbbugD3Fht+7V+WSNVmPe8=",
"Payload": {
"body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoicmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0ODEwZmQ5YjEzODdlNDZhZWMyM2NmNTYwNjU3OTcxOTllZmU3NzM3YmQ0NmNiMTViYzI0Y2VkMjY5MGNhYzUyIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUM0VVpIODNTY3o3d1g1dU1LR0NJU3c5SDNvRlk1R3p6b3dFY1lxTDJOSkl3SWdjT1YzaUFmd2hEL0dBMzI2a3RQRUtGYkVHVExPTlhOVDNFcGJtK1VqbHU4PSIsImZvcm1hdCI6Ing1MDkiLCJwdWJsaWNLZXkiOnsiY29udGVudCI6IkxTMHRMUzFDUlVkSlRpQlFWVUpNU1VNZ1MwVlpMUzB0TFMwS1RVWnJkMFYzV1VoTGIxcEplbW93UTBGUldVbExiMXBKZW1vd1JFRlJZMFJSWjBGRlFteFlha3hpU0c4d1dXdHROMGRaWlc4d2MzUXphbmxCSzNOS1R3b3ZVVnBMZVRkNE1WQkdTMnBJYlc1UmVVb3lTV0psVldwNU5tZEhNelpTU1dGME0xQjVjVWN3ZUZsRGNEZGtWWFZNSzBac1IwMU9la2hCUFQwS0xTMHRMUzFGVGtRZ1VGVkNURWxESUV0RldTMHRMUzB0Q2c9PSJ9fX19",
"integratedTime": 1704186031,
"logIndex": 60785227,
"logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
}
} NOTE: before running below
NEW_IMAGE=$(cosign triangulate ghcr.io/viveksahu26/hi-cosign:main)
crane manifest $NEW_IMAGE | jq ✭
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 233,
"digest": "sha256:fa861bd3364df5b2e0bee5054be12ea13fab3eb3879312945aa044600d8c0ae8"
},
"layers": [
{
"mediaType": "application/vnd.dev.cosign.simplesigning.v1+json",
"size": 246,
"digest": "sha256:4810fd9b1387e46aec23cf56065797199efe7737bd46cb15bc24ced2690cac52",
"annotations": {
"dev.cosignproject.cosign/signature": "MEUCIQC4UZH83Scz7wX5uMKGCISw9H3oFY5GzzowEcYqL2NJIwIgcOV3iAfwhD/GA326ktPEKFbEGTLONXNT3Epbm+Ujlu8=",
"dev.sigstore.cosign/bundle": "{\"SignedEntryTimestamp\":\"MEUCICgM9CCtcMXPKCIeyInCxRSwXfEE7p26tOsp754tNllqAiEArw8QbChGn6n15TEG4yJaBJbbugD3Fht+7V+WSNVmPe8=\",\"Payload\":{\"body\":\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoicmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0ODEwZmQ5YjEzODdlNDZhZWMyM2NmNTYwNjU3OTcxOTllZmU3NzM3YmQ0NmNiMTViYzI0Y2VkMjY5MGNhYzUyIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUM0VVpIODNTY3o3d1g1dU1LR0NJU3c5SDNvRlk1R3p6b3dFY1lxTDJOSkl3SWdjT1YzaUFmd2hEL0dBMzI2a3RQRUtGYkVHVExPTlhOVDNFcGJtK1VqbHU4PSIsImZvcm1hdCI6Ing1MDkiLCJwdWJsaWNLZXkiOnsiY29udGVudCI6IkxTMHRMUzFDUlVkSlRpQlFWVUpNU1VNZ1MwVlpMUzB0TFMwS1RVWnJkMFYzV1VoTGIxcEplbW93UTBGUldVbExiMXBKZW1vd1JFRlJZMFJSWjBGRlFteFlha3hpU0c4d1dXdHROMGRaWlc4d2MzUXphbmxCSzNOS1R3b3ZVVnBMZVRkNE1WQkdTMnBJYlc1UmVVb3lTV0psVldwNU5tZEhNelpTU1dGME0xQjVjVWN3ZUZsRGNEZGtWWFZNSzBac1IwMU9la2hCUFQwS0xTMHRMUzFGVGtRZ1VGVkNURWxESUV0RldTMHRMUzB0Q2c9PSJ9fX19\",\"integratedTime\":1704186031,\"logIndex\":60785227,\"logID\":\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\"}}"
}
}
]
}
cosign verify --key cosign.pub $IMAGE | jq
Verification for ghcr.io/viveksahu26/hi-cosign:main --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "ghcr.io/viveksahu26/hi-cosign"
},
"image": {
"docker-manifest-digest": "sha256:53717c8c2a95af9550d0b1cebff0e4fa357c3573d936fc42af3cb73b627969bf"
},
"type": "cosign container image signature"
},
"optional": {
"Bundle": {
"SignedEntryTimestamp": "MEUCICgM9CCtcMXPKCIeyInCxRSwXfEE7p26tOsp754tNllqAiEArw8QbChGn6n15TEG4yJaBJbbugD3Fht+7V+WSNVmPe8=",
"Payload": {
"body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoicmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI0ODEwZmQ5YjEzODdlNDZhZWMyM2NmNTYwNjU3OTcxOTllZmU3NzM3YmQ0NmNiMTViYzI0Y2VkMjY5MGNhYzUyIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUM0VVpIODNTY3o3d1g1dU1LR0NJU3c5SDNvRlk1R3p6b3dFY1lxTDJOSkl3SWdjT1YzaUFmd2hEL0dBMzI2a3RQRUtGYkVHVExPTlhOVDNFcGJtK1VqbHU4PSIsImZvcm1hdCI6Ing1MDkiLCJwdWJsaWNLZXkiOnsiY29udGVudCI6IkxTMHRMUzFDUlVkSlRpQlFWVUpNU1VNZ1MwVlpMUzB0TFMwS1RVWnJkMFYzV1VoTGIxcEplbW93UTBGUldVbExiMXBKZW1vd1JFRlJZMFJSWjBGRlFteFlha3hpU0c4d1dXdHROMGRaWlc4d2MzUXphbmxCSzNOS1R3b3ZVVnBMZVRkNE1WQkdTMnBJYlc1UmVVb3lTV0psVldwNU5tZEhNelpTU1dGME0xQjVjVWN3ZUZsRGNEZGtWWFZNSzBac1IwMU9la2hCUFQwS0xTMHRMUzFGVGtRZ1VGVkNURWxESUV0RldTMHRMUzB0Q2c9PSJ9fX19",
"integratedTime": 1704186031,
"logIndex": 60785227,
"logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
}
}
}
}
]
|
Thank you so much for the swift response! I can see that the Rekor bundle basically contains the same info as in the public URL. Is there a command to create the |
AFAIK, you need to create rekor bundle by yourself. Need confirmation from @haydentherapper . |
The Rekor bundle format is not an exact match of what's returned from the server, it's a struct. #3248 added support for outputting both the Rekor response struct and other associated verification data (signature and certificate). I think some of the confusion is that If you have fetched a response from Rekor yourself through rekor-cli, then you'll need to create the rekor struct. I'd also be open to a PR that takes in a rekor response. As an aside, we just need to be clear on when we're taking in a "bundle" vs "rekor bundle" vs "response". Unfortunately we overloaded what a bundle is in the codebase. Typically a "bundle" refers to the combination of all verification metadata (signature, certificate, Rekor proof), a "Rekor bundle" is the struct of a proof + other Rekor data, and a "response" would be whatever is returned from requests directly to Rekor. |
The In order to verify the image via rekor log, the image must contain the Just for clearity added rekor Bundle, rekor Object and rekor response:
{
"SignedEntryTimestamp": "MEQCIHEmjSp606etascUmCK/HYh7rRkyTfHVrOdzs/kxlhbzAiBJnpUjpSqh2QiW6GQjGgoSL8YN6Kgm4DY3Km1lfhlssw==",
"Payload": {
"body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoicmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjOTA5YWVlYmQ5MzU3YzA4MGE3N2VhOWQzZWVmMzU1ODMwYTMxNTRjNTJmODlhOWJlMDUyMDMxN2ZlNTQ1NjdhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRmhKSUJRdkpMOTY0cWJDQ2hENjFhWW4yYzlBMTNVNmJDNUlrY1REYmNyNUFpRUF5SWZkVWV0WGdSbDlFN3VnemdiWDlpN0VaZGw0eHdMNm9uWUtlY2JtR0xFPSIsImZvcm1hdCI6Ing1MDkiLCJwdWJsaWNLZXkiOnsiY29udGVudCI6IkxTMHRMUzFDUlVkSlRpQlFWVUpNU1VNZ1MwVlpMUzB0TFMwS1RVWnJkMFYzV1VoTGIxcEplbW93UTBGUldVbExiMXBKZW1vd1JFRlJZMFJSWjBGRlNXdzFLMDgxTjAxRmNsWkdNMnh1UzJGRGRrWjNTWGxTUkhOVmR3cFhVV1ZHVjFKdk56ZHNXVzFPWlZGdWFrVXhhVmRYYzI1WmJqVkRlVWgzVVcxdWFrWjNZMGxLVlVWdldtUXJkSGxJVVRKSk9IQnRXa2xSUFQwS0xTMHRMUzFGVGtRZ1VGVkNURWxESUV0RldTMHRMUzB0Q2c9PSJ9fX19",
"integratedTime": 1704275510,
"logIndex": 61057801,
"logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"
}
} And the body field under {
"apiVersion": "0.0.1",
"kind": "rekord",
"spec": {
"data": {
"hash": {
"algorithm": "sha256",
"value": "c909aeebd9357c080a77ea9d3eef355830a3154c52f89a9be0520317fe54567a"
}
},
"signature": {
"content": "MEUCIFhJIBQvJL964qbCChD61aYn2c9A13U6bC5IkcTDbcr5AiEAyIfdUetXgRl9E7ugzgbX9i7EZdl4xwL6onYKecbmGLE=",
"format": "x509",
"publicKey": {
"content": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFSWw1K081N01FclZGM2xuS2FDdkZ3SXlSRHNVdwpXUWVGV1JvNzdsWW1OZVFuakUxaVdXc25ZbjVDeUh3UW1uakZ3Y0lKVUVvWmQrdHlIUTJJOHBtWklRPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
}
}
}
} And rekor response will be: {
"24296fb24b8ad77a88cfe47ac0ec898992d7c352d888385572ffe428f3ceace27fb28efb8c3525ea": {
"body": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoicmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJjOTA5YWVlYmQ5MzU3YzA4MGE3N2VhOWQzZWVmMzU1ODMwYTMxNTRjNTJmODlhOWJlMDUyMDMxN2ZlNTQ1NjdhIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRmhKSUJRdkpMOTY0cWJDQ2hENjFhWW4yYzlBMTNVNmJDNUlrY1REYmNyNUFpRUF5SWZkVWV0WGdSbDlFN3VnemdiWDlpN0VaZGw0eHdMNm9uWUtlY2JtR0xFPSIsImZvcm1hdCI6Ing1MDkiLCJwdWJsaWNLZXkiOnsiY29udGVudCI6IkxTMHRMUzFDUlVkSlRpQlFWVUpNU1VNZ1MwVlpMUzB0TFMwS1RVWnJkMFYzV1VoTGIxcEplbW93UTBGUldVbExiMXBKZW1vd1JFRlJZMFJSWjBGRlNXdzFLMDgxTjAxRmNsWkdNMnh1UzJGRGRrWjNTWGxTUkhOVmR3cFhVV1ZHVjFKdk56ZHNXVzFPWlZGdWFrVXhhVmRYYzI1WmJqVkRlVWgzVVcxdWFrWjNZMGxLVlVWdldtUXJkSGxJVVRKSk9IQnRXa2xSUFQwS0xTMHRMUzFGVGtRZ1VGVkNURWxESUV0RldTMHRMUzB0Q2c9PSJ9fX19",
"integratedTime": 1704275510,
"logID": "c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d",
"logIndex": 61057801,
"verification": {
"inclusionProof": {
"checkpoint": "rekor.sigstore.dev - 2605736670972794746\n56899688\n2K8awlTbXSPXzAc5u1CVUpse38O74h0ra2Rp7xmc8W8=\nTimestamp: 1704278309483367771\n\n— rekor.sigstore.dev wNI9ajBFAiEA/+k6BRX1AjrDcDNPhOsQ2uep7oqzNRPTHFDKnz21ePwCIF6/ZMsAAwHVpBssuL4g6XcYx8IbE/pSU7Dru2RxnWET\n",
"hashes": [
"552844e8341d5f5ca35b3b5986b2844defe0cb5b3ba70463cac0a501c4116598",
"ce8ac8c1bce209194a9363cb1745a66da615e123b1d6de61030d7b6056a7acb4",
"a0d143e6cf96bce7b9650f1550cb3cc11b3f86a1cdcf6b769936f3c5998ed8e0",
"f6ddbd7786cf35f3371e88d3766b09e49d718fbf5ff74f3f99c90708f6fd4fb7",
"3d31f9e6961f61bd9631ad33ce2523d240bd34feb9c662693019168f20c616a9",
"54228e5dc4ecfd140fe299c0717138f9155108ed411ddb26e750c52943854eeb",
"03c0d114a083b63ace0a45dbf9fb93a71c1355e6ff2b843caa04ca60b3ad8630",
"dc912424fcafb9941b58d87c3c3c44e8ec82a1d5dcc7b386b498eeb14d76d484",
"05ece212ea71c71c840c01ea2c0f04d67679060c00e118d9ebf132047dd866f5",
"df4f2672db865a2583b869b285edc7318e18210bb00221e0545575e70976911a",
"60f66d91bcfd95d07d9c71ef4ca1aa0808b7fd34cf3cf050e8fac9d7eb081396",
"7f27330b3a87e8431b7530dc4582e7e339deaf6e490f1e372cb4a087a0d6d1b7",
"0f54f2c6492a507f6f121c3e7e47f1ae6fc0ca363979659af78623c66e476b69",
"d63b57eb1a8831b477e9e8f96ce4171c8bb04a4dc87eaa88c4acc3c96edb5d7f",
"b03582ce199cfd516f467cf990140df0c7709bb669d77638484d41c78cf15258",
"7940acf1d34fea9052d8af95ab3e4c0a5da981529238ad691d25800b61f210d4",
"2c4d25ba59aa573ab2c79c2d3cd9e1d74789b10632432724d63112ce50b44874",
"98c486feb5d87092a78a46c4b5be04868654900affc2e86ffb20074dc73a883a",
"6969c49bd73f19bf28a5eaeabd331ddd60502defb2cd3d96e17b741c80adec6c"
],
"logIndex": 56894370,
"rootHash": "d8af1ac254db5d23d7cc0739bb5095529b1edfc3bbe21d2b6b6469ef199cf16f",
"treeSize": 56899688
},
"signedEntryTimestamp": "MEQCIEPQJXuofj6OABnJ7pEmMn5mJR+bfYgM+U71l6a0qq20AiBTBuFdRTOdxR5lAy+2tGCHPAUZ2gnyEIhKcK1+708Zbw=="
}
}
} |
I need to create a cosign signature for a Docker container using an external system that holds the signing key. I'm following this official cosign sample and the signing works great. However, I am not able to upload the signature to the Rekor Transparency Log (using
rekor-cli
) so that it is accepted bycosign verify
. What am I doing wrong?Here's the code to reproduce the issue:
The first verification without TLOG in step 5) works as expected. However, in step 7, I get the following error message:
Is there something else I need to provide? I replayed the same scenario using the standard "keyless" method and can't see much of a difference in the generated transparency log entry (except for this one using RSA keys instead of ECDSA)
I'm using
cosign v2.2.2
andrekor-cli v1.3.4
. The transparency log entry I created for this sample has the log id60018885
in case you want to look it up.The text was updated successfully, but these errors were encountered: