Skip to content

Sign attestation manifests #5

Closed
Closed

Description

@crazy-max

With these secure reusable workflows we want to have the ability to sign The BuildKit-generated provenance and SBOM attestations. This will be a step in our reusable workflows and not part of regular builds with BuildKit.

We want signatures pushed by digest unlike cosign that pushes a tag matching the signed manifest using the format <repo>/<image>:sha256-<manifest-digest>.sig. Verification will be done using the OCI Referrers API.

Activity

  1. added theissue type on Jul 24, 2025
  2. crazy-max commented on Jul 29, 2025

    @crazy-max
    MemberAuthor

    For this first analysis, signing this is currently based on cosign-installer. For this run it happens in: https://github.com/crazy-max/test-builder-action/actions/runs/16118017941/job/45476390557#step:7:46

    Image

    This will push the signature as a new image tagged like this: ghcr.io/crazy-max/test-builder-action:sha256-96ea495342b70f5cd197bf45d87e0a9a267ec0ce1451a0d5cffae984c9667c37.sig:

    Tag name is sha256-<image-digest>.sig where <image-digest> is the digest of the image pushed by build-push-action. See https://explore.ggcr.dev/?image=ghcr.io%2Fcrazy-max%2Ftest-builder-action%3Asha256-96ea495342b70f5cd197bf45d87e0a9a267ec0ce1451a0d5cffae984c9667c37.sig

    {
       "schemaVersion":2,
       "mediaType":"application/vnd.oci.image.manifest.v1+json",
       "config":{
          "mediaType":"application/vnd.oci.image.config.v1+json",
          "size":233,
          "digest":"sha256:6764da0ca2da928ae6e124ede512bca3d807ba4ac11a695e4092eee0f2e54615"
       },
       "layers":[
          {
             "mediaType":"application/vnd.dev.cosign.simplesigning.v1+json",
             "size":253,
             "digest":"sha256:f8c3c54e90bdfe5b0c03ebba20225128e74ea7506bde695bda4b080c7a574f7e",
             "annotations":{
                "dev.cosignproject.cosign/signature":"MEUCIDw/TKSHmrV9r6U3wFlVO2NtNB88GhpIFIE0rga/iW/sAiEA0RI8GOYkLjcTfeCrkuXaWJSB0NHBdv7FGjFn1hUtoXE=",
                "dev.sigstore.cosign/bundle":"{\"SignedEntryTimestamp\":\"MEYCIQD/ytsCY+lXnurw6e+yzKUUXsp40+t3vjSL04YcfrHVyAIhAI2SSpyUzYFNs3c+65qaNCMccoZ15/Y7ehbPyvhPiRsI\",\"Payload\":{\"body\":\"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiJmOGMzYzU0ZTkwYmRmZTViMGMwM2ViYmEyMDIyNTEyOGU3NGVhNzUwNmJkZTY5NWJkYTRiMDgwYzdhNTc0ZjdlIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRHcvVEtTSG1yVjlyNlUzd0ZsVk8yTnROQjg4R2hwSUZJRTByZ2EvaVcvc0FpRUEwUkk4R09Za0xqY1RmZUNya3VYYVdKU0IwTkhCZHY3RkdqRm4xaFV0b1hFPSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVY3hha05EUW14NVowRjNTVUpCWjBsVlVFWjZiMUZCYURnMVdqQXZOMVlyUWtoSFJsSTJTR1ZFZGpaTmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDU2UVROTlZFMTRUbXBCTWxkb1kwNU5hbFYzVG5wQk0wMVVUWGxPYWtFeVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVUzWjA5dVVsRktaM0JpWWtGNllqWjFlbEpzYmtwWVNVdHFPVWhzTVZKMFVHbHJObE1LTkZsNFpFTXlOVmhhUlZkMGJVSkhjSEVyWTBwWlkzZE9NVGhGU0RaWU1UVkVNME5uWVZGc01DOXhXRFJMV0RSYVpVdFBRMEpZYzNkbloxWXpUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlUyYlhCQkNtSkxRVU5TTXpScmFsY3lNRzEyVEVGVFNsRTBjRmM0ZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDFwUldVUldVakJTUVZGSUwwSkdjM2RYV1ZwWVlVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwVERKT2VWbFljRFZNVnpGb1pVTTVhUXBrVjJ4eldrZFdlVXhYUm1wa1IyeDJZbWs0ZFZveWJEQmhTRlpwVEROa2RtTnRkRzFpUnprelkzazVhV1JYYkhOYVF6VTFZbGQ0UVdOdFZtMWplVGx2Q2xwWFJtdGplVGwwV1Zkc2RVMUVhMGREYVhOSFFWRlJRbWMzT0hkQlVVVkZTekpvTUdSSVFucFBhVGgyWkVjNWNscFhOSFZaVjA0d1lWYzVkV041Tlc0S1lWaFNiMlJYU2pGak1sWjVXVEk1ZFdSSFZuVmtRelZxWWpJd2QwVm5XVXRMZDFsQ1FrRkhSSFo2UVVKQloxRkZZMGhXZW1GRVFUSkNaMjl5UW1kRlJRcEJXVTh2VFVGRlJFSkRaekZQVjBreVRVZEZkMWw2WTNkWlZFbDRUMVJDYVU1dFRUQlpWR3MxVDFkWk5WcEVTWGhPYlZWNVRsZFpORmw2VlhkT1ZFMHdDazFDUVVkRGFYTkhRVkZSUW1jM09IZEJVVkZGUVcxT2NFMURjMGREYVhOSFFWRlJRbWMzT0hkQlVWVkZTRmRPZVZsWWNEVk1WekZvWlVNNU1GcFlUakFLVEZkS01XRlhlR3RhV0VsMFdWZE9NR0ZYT1hWTlFqQkhRMmx6UjBGUlVVSm5OemgzUVZGWlJVUXpTbXhhYmsxMllVZFdhRnBJVFhaaVYwWndZbXBCTndwQ1oyOXlRbWRGUlVGWlR5OU5RVVZKUWtNd1RVc3lhREJrU0VKNlQyazRkbVJIT1hKYVZ6UjFXVmRPTUdGWE9YVmplVFZ1WVZoU2IyUlhTakZqTWxaNUNsa3lPWFZrUjFaMVpFTTFhbUl5TUhkYWQxbExTM2RaUWtKQlIwUjJla0ZDUTFGU1drUkdaRzlrU0ZKM1kzcHZka3d5WkhCa1IyZ3hXV2sxYW1JeU1IWUtXVE5LYUdWdWEzUmlWMFkwVERKS01XRlhlR3RhV0VsMFdWZE9NR0ZYT1hWTWVUVnVZVmhTYjJSWFNYWmtNamw1WVRKYWMySXpaSHBNTWtveFlWZDRhd3BNYm14MFlrVkNlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzVDBGWlMwdDNXVUpDUVVkRWRucEJRa05uVVhGRVEyaHRXa1JqTVZsVVZtbGFSMXBxQ2s5VWJHaE5ha1V6V1ZSV2FrNXFhRzFOYWxab1dsZEZlVmw2YUd4YVZHaHFXa1JLYlZwdFRtcE5RakJIUTJselIwRlJVVUpuTnpoM1FWRnpSVVIzZDA0S1dqSnNNR0ZJVm1sTVYyaDJZek5TYkZwRVFrRkNaMjl5UW1kRlJVRlpUeTlOUVVWTlFrUkpUVTFIYURCa1NFSjZUMms0ZGxveWJEQmhTRlpwVEcxT2RncGlVemxxWTIxR05tVlRNWFJaV0dkMlpFZFdlbVJETVdsa1YyeHpXa2RXZVV4WFJtcGtSMngyWW1wQk5FSm5iM0pDWjBWRlFWbFBMMDFCUlU1Q1EyOU5Da3RFVlRWWmFsbDNXVlJDYWs1NlFtaE5ha1UxVFVkSk1sbDZVbWhQVkdzMVdtcHNhMDFxUlRKYVZFa3hXbXBvYWs1VVFURk5lbEYzU0hkWlMwdDNXVUlLUWtGSFJIWjZRVUpFWjFGU1JFRTVlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzUjJkWlMwdDNXVUpDUVVkRWRucEJRa1IzVVUxRVFXOTRUVVJGTVFwT1JFRXdUbXBSTWsxRGQwZERhWE5IUVZGUlFtYzNPSGRCVWtGRlNHZDNZMkZJVWpCalNFMDJUSGs1Ym1GWVVtOWtWMGwxV1RJNWRFd3lUbmxaV0hBMUNreFhNV2hsUkVGWVFtZHZja0puUlVWQldVOHZUVUZGVWtKQmEwMUNla1UxVGxSRk5FNXFXWGRoVVZsTFMzZFpRa0pCUjBSMmVrRkNSV2RTWWtSR2JHOEtaRWhTZDJONmIzWk1NbVJ3WkVkb01WbHBOV3BpTWpCMldUTkthR1Z1YTNSaVYwWTBURE5TYkdNelVYUlpibFp3WWtkU2JHTnBNV2haTTFKd1lqSTBkZ3BNYldSd1pFZG9NVmxwT1ROaU0wcHlXbTE0ZG1RelRYWlpNbXQxWlZjeGMxRklTbXhhYmsxMllVZFdhRnBJVFhaaVYwWndZbXBCTkVKbmIzSkNaMFZGQ2tGWlR5OU5RVVZVUWtOdlRVdEVWVFZaYWxsM1dWUkNhazU2UW1oTmFrVTFUVWRKTWxsNlVtaFBWR3MxV21wc2EwMXFSVEphVkVreFdtcG9hazVVUVRFS1RYcFJkMFpCV1V0TGQxbENRa0ZIUkhaNlFVSkdRVkZIUkVGU2QyUllUbTlOUjFGSFEybHpSMEZSVVVKbk56aDNRVkpWUlZabmVGVmhTRkl3WTBoTk5ncE1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESk9lVmxZY0RWTVZ6Rm9aVU01TUZwWVRqQk1WMG94WVZkNGExcFlTWFJaVjA0d1lWYzVkVXd5Um1wa1IyeDJDbUp1VFhaamJsWjFZM2s0ZUU1cVJYaFBSRUY0VG5wck1FMVRPV2hrU0ZKc1lsaENNR041T0hoTlFsbEhRMmx6UjBGUlVVSm5OemgzUVZKWlJVTkJkMGNLWTBoV2FXSkhiR3BOU1VkTVFtZHZja0puUlVWQlpGbzFRV2RSUTBKSU1FVmxkMEkxUVVoalFUTlVNSGRoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLU3dwWWNtcGxVRXN6TDJnMGNIbG5Remh3TjI4MFFVRkJSMWcxVVdWTlExRkJRVUpCVFVGVFJFSkhRV2xGUVhwdVNXSm5jRlZPWWlzNVpXcFZOVmNyT1hSRUNteHlSa3B3Um1ONmJUbGthM2MxZDNCV1oxcElRMFZuUTBsUlJFTTRUM2hZZEZnM1VHZFRVbW8wT1RoU2RtVjZXRkZEWjBZM01XUjBaR1pxTUdsT1ZsWUtZWEJIYW5wVVFVdENaMmR4YUd0cVQxQlJVVVJCZDA1dlFVUkNiRUZxUWxaM05UTktTazFDTmpKUE5rNDFOM3B3VTBGNGRUaDNORzgzVERoVGRHOXVWd294VVcxaFNVOVFhSE5sWWt0V1JrNUNjVlYwZUd4T2FtZG1XRVp2UkdSQlEwMVJSRFJ2SzNsd2VtNXFheTh3U1N0RllXUTNXRkpKWTNkSGVHUnJkVTFOQ2xkT2NqWnBZbWxXYkRsU2FVdEZNSFJVYkhwaFFVNDVaR3dyV0dadlUwSjFkSFZOUFFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9fX19\",\"integratedTime\":1751894166,\"logIndex\":265358161,\"logID\":\"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d\"}}",
                "dev.sigstore.cosign/certificate":"-----BEGIN CERTIFICATE-----\nMIIG1jCCBlygAwIBAgIUPFzoQAh85Z0/7V+BHGFR6HeDv6MwCgYIKoZIzj0EAwMw\nNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl\ncm1lZGlhdGUwHhcNMjUwNzA3MTMxNjA2WhcNMjUwNzA3MTMyNjA2WjAAMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAE7gOnRQJgpbbAzb6uzRlnJXIKj9Hl1RtPik6S\n4YxdC25XZEWtmBGpq+cJYcwN18EH6X15D3CgaQl0/qX4KX4ZeKOCBXswggV3MA4G\nA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU6mpA\nbKACR34kjW20mvLASJQ4pW8wHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y\nZD8wZQYDVR0RAQH/BFswWYZXaHR0cHM6Ly9naXRodWIuY29tL2NyYXp5LW1heC9i\ndWlsZGVyLWFjdGlvbi8uZ2l0aHViL3dvcmtmbG93cy9idWlsZC55bWxAcmVmcy9o\nZWFkcy9tYWluMDkGCisGAQQBg78wAQEEK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5n\naXRodWJ1c2VyY29udGVudC5jb20wEgYKKwYBBAGDvzABAgQEcHVzaDA2BgorBgEE\nAYO/MAEDBCg1OWI2MGEwYzcwYTIxOTBiNmM0YTk5OWY5ZDIxNmUyNWY4YzUwNTM0\nMBAGCisGAQQBg78wAQQEAmNpMCsGCisGAQQBg78wAQUEHWNyYXp5LW1heC90ZXN0\nLWJ1aWxkZXItYWN0aW9uMB0GCisGAQQBg78wAQYED3JlZnMvaGVhZHMvbWFpbjA7\nBgorBgEEAYO/MAEIBC0MK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2Vy\nY29udGVudC5jb20wZwYKKwYBBAGDvzABCQRZDFdodHRwczovL2dpdGh1Yi5jb20v\nY3JhenktbWF4L2J1aWxkZXItYWN0aW9uLy5naXRodWIvd29ya2Zsb3dzL2J1aWxk\nLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDChmZDc1YTViZGZj\nOTlhMjE3YTVjNjhmMjVhZWEyYzhlZThjZDJmZmNjMB0GCisGAQQBg78wAQsEDwwN\nZ2l0aHViLWhvc3RlZDBABgorBgEEAYO/MAEMBDIMMGh0dHBzOi8vZ2l0aHViLmNv\nbS9jcmF6eS1tYXgvdGVzdC1idWlsZGVyLWFjdGlvbjA4BgorBgEEAYO/MAENBCoM\nKDU5YjYwYTBjNzBhMjE5MGI2YzRhOTk5ZjlkMjE2ZTI1ZjhjNTA1MzQwHwYKKwYB\nBAGDvzABDgQRDA9yZWZzL2hlYWRzL21haW4wGgYKKwYBBAGDvzABDwQMDAoxMDE1\nNDA0NjQ2MCwGCisGAQQBg78wARAEHgwcaHR0cHM6Ly9naXRodWIuY29tL2NyYXp5\nLW1heDAXBgorBgEEAYO/MAERBAkMBzE5NTE4NjYwaQYKKwYBBAGDvzABEgRbDFlo\ndHRwczovL2dpdGh1Yi5jb20vY3JhenktbWF4L3Rlc3QtYnVpbGRlci1hY3Rpb24v\nLmdpdGh1Yi93b3JrZmxvd3MvY2kueW1sQHJlZnMvaGVhZHMvbWFpbjA4BgorBgEE\nAYO/MAETBCoMKDU5YjYwYTBjNzBhMjE5MGI2YzRhOTk5ZjlkMjE2ZTI1ZjhjNTA1\nMzQwFAYKKwYBBAGDvzABFAQGDARwdXNoMGQGCisGAQQBg78wARUEVgxUaHR0cHM6\nLy9naXRodWIuY29tL2NyYXp5LW1heC90ZXN0LWJ1aWxkZXItYWN0aW9uL2FjdGlv\nbnMvcnVucy8xNjExODAxNzk0MS9hdHRlbXB0cy8xMBYGCisGAQQBg78wARYECAwG\ncHVibGljMIGLBgorBgEEAdZ5AgQCBH0EewB5AHcA3T0wasbHETJjGR4cmWc3AqJK\nXrjePK3/h4pygC8p7o4AAAGX5QeMCQAABAMASDBGAiEAznIbgpUNb+9ejU5W+9tD\nlrFJpFczm9dkw5wpVgZHCEgCIQDC8OxXtX7PgSRj498RvezXQCgF71dtdfj0iNVV\napGjzTAKBggqhkjOPQQDAwNoADBlAjBVw53JJMB62O6N57zpSAxu8w4o7L8StonW\n1QmaIOPhsebKVFNBqUtxlNjgfXFoDdACMQD4o+ypznjk/0I+Ead7XRIcwGxdkuMM\nWNr6ibiVl9RiKE0tTlzaAN9dl+XfoSButuM=\n-----END CERTIFICATE-----\n",
                "dev.sigstore.cosign/chain":"-----BEGIN CERTIFICATE-----\nMIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0C\nAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV7\n7LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS\n0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYB\nBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjp\nKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZI\nzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJR\nnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsP\nmygUY7Ii2zbdCdliiow=\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw\nKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y\nMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl\nLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7\nXeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex\nX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j\nYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY\nwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ\nKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM\nWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9\nTNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ\n-----END CERTIFICATE-----"
             }
          }
       ]
    }

    The application/vnd.dev.cosign.simplesigning.v1+json layer contains the image ref and digest, I guess used for verification:

    {
      "critical": {
        "identity": {
          "docker-reference":"ghcr.io/crazy-max/test-builder-action"
        },
        "image": {
          "docker-manifest-digest":"sha256:96ea495342b70f5cd197bf45d87e0a9a267ec0ce1451a0d5cffae984c9667c37"
        },
        "type":"cosign container image signature"
      },
      "optional":null
    }

    Note

    We need to check how critical.identity is used.

    In our case we want to sign attestation manifests. We would need to sign each attestation pushed as OCI artifact, hence why I push with oci-artifact=true based on moby/buildkit#5573: https://github.com/crazy-max/builder-action/blob/fd75a5bdfc99a217a5c68f25aea2c8ee8cd2ffcc/.github/workflows/build.yml#L91

    {
       "schemaVersion":2,
       "mediaType":"application/vnd.oci.image.manifest.v1+json",
       "artifactType":"application/vnd.docker.attestation.manifest.v1+json",
       "config":{
          "mediaType":"application/vnd.oci.empty.v1+json",
          "size":2,
          "digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
          "data":"e30="
       },
       "layers":[
          {
             "mediaType":"application/vnd.in-toto+json",
             "size":2511,
             "digest":"sha256:98ad44b0169a6159195083f4b58f95e6ce490dca23adcf621f122d61cde4ce2a",
             "annotations":{
                "in-toto.io/predicate-type":"https://spdx.dev/Document"
             }
          },
          {
             "mediaType":"application/vnd.in-toto+json",
             "size":3953,
             "digest":"sha256:3e6c436bfd529c08fdcb8162302d3259c1a75776e8f187f6240ee6a87949134f",
             "annotations":{
                "in-toto.io/predicate-type":"https://slsa.dev/provenance/v0.2"
             }
          }
       ],
       "subject":{
          "mediaType":"application/vnd.oci.image.manifest.v1+json",
          "size":668,
          "digest":"sha256:589c096256a826d4b036b99214b0fb081737a54c339f38d128021035d44be2e3",
          "platform":{
             "architecture":"amd64",
             "os":"linux"
          }
       }
    }
  3. crazy-max commented on Jul 29, 2025

    @crazy-max
    MemberAuthor

    It seems we could use --recursive flag from cosign sign command that would sign each manifest from manifest list / OCI index if we are not setting oci-artifact=true:

    cosign sign --recursive <image-digest>
    

    See this run: https://github.com/crazy-max/test-builder-action/actions/runs/16119677946/job/45481987397#step:7:35

    For this image https://explore.ggcr.dev/?image=ghcr.io/crazy-max/test-builder-action@sha256:f490af7ddbd8083b86187d54c453efee5e46e1974e8cc4b04ba0b58f469b1cf3&mt=application%2Fvnd.oci.image.index.v1%2Bjson&size=856

    We have 3 manifests:

    With the recursive flag we have two signatures pushed:

    But that doesn’t sign attestations from attestation manifest https://explore.ggcr.dev/?image=ghcr.io/crazy-max/test-builder-action@sha256:b0d3c998a1258e5cf557d4403c2f9de682019b4da30d4dd135c2e4e30c05186c:

    So it's only recursive at first level to handle multi-platform images.

    What we could do is getting the digest of each attestation manifest and signing each of them with:

    cosign sign <attest-sbom-digest> <attest-provenance-digest>
    
  4. crazy-max commented on Jul 29, 2025

    @crazy-max
    MemberAuthor

    Getting attestation manifests digest seems to do the trick:

    I'm still not sure why cosign would sign each tag with its digest: https://github.com/sigstore/cosign-installer/

    Image

    That doesn't make much sense as they sign by digest anyway? Maybe to set multiple refs in application/vnd.dev.cosign.simplesigning.v1+json?

  5. crazy-max commented on Jul 29, 2025

    @crazy-max
    MemberAuthor

    That doesn't make much sense as they sign by digest anyway? Maybe to set multiple refs in application/vnd.dev.cosign.simplesigning.v1+json?

    identity.dockerfile-reference is not a list so don't think this is the case. Need to check this.

    But anyway now signing only the attestation manifests we get earlier:

    We got https://github.com/crazy-max/test-builder-action/actions/runs/16474918336/job/46573777337#step:8:55

    Image

    Looking at the pushed signature: https://explore.ggcr.dev/?image=ghcr.io%2Fcrazy-max%2Ftest-builder-action%3Asha256-80acd0398bf0da327277bdbb75971d9e974ccb93613a7f70649646b65e8f5008.sig

    Image

    We have in simplesigning the attestation manifest digest signed: https://explore.ggcr.dev/?blob=ghcr.io/crazy-max/test-builder-action@sha256:f8a5d01bff6dd59a581cf7227e5203fb1c03d865a6f0893bb0667c0c642b558a&mt=application%2Fvnd.dev.cosign.simplesigning.v1%2Bjson&size=253

    Image

    So again what is the purpose of this docker-reference?

    For https://explore.ggcr.dev/?image=ghcr.io/crazy-max/test-builder-action@sha256:80acd0398bf0da327277bdbb75971d9e974ccb93613a7f70649646b65e8f5008&mt=application%2Fvnd.dev.ggcr.magic%2Fcosign-thing%2Bjson

    Image
  6. self-assigned this
    on Jul 29, 2025
  7. crazy-max commented on Aug 12, 2025

    @crazy-max
    MemberAuthor

    what is the purpose of this docker-reference?

    The cosign signature payload is actually a Simple Signing payload.

    critical.identity.docker-reference is defined here: https://github.com/containers/image/blob/898f38590573f2801232a74078f2438209d7449a/docs/containers-signature.5.md#criticalidentitydocker-reference

    Most interesting part explaining this field is:

    or they may require critical.identity.docker-reference values with a completely different namespace to the reference used to refer to/download the image (e.g. requiring a critical.identity.docker-reference value which identifies the image as coming from a supplier when fetching it from a company-internal mirror of approved images). The software performing this verification SHOULD allow the users to define such a policy using the policy.json signature verification policy file format.

    This means when for example mirrors are applied, a signature verification policy should be put in place.

    @tonistiigi With BuildKit it could probably be done using our source policy introduced in moby/buildkit#3332?

  8. crazy-max commented on Aug 12, 2025

    @crazy-max
    MemberAuthor

    Check oci-layout support in cosign

    Signing OCI artifacts/layout is not supported by cosign: sigstore/cosign#2516 but I think we could get around it using cosign as a library.

  9. added theissue type on Aug 19, 2025
  10. transferred this issue fromon Aug 19, 2025
  11. changed the title [-]Reusable workflows signing[/-] [+]Sign attestation manifests[/+] on Aug 19, 2025
  12. crazy-max commented on Aug 19, 2025

    @crazy-max
    MemberAuthor

    Now testing #4 with https://github.com/docker/github-builder-test:

    Image

    Attestations signature


    Looking at the verification pattern in cosign it doesn't seem critical.identity.docker-reference is used:

    $ cosign verify --certificate-identity https://github.com/docker/github-builder-experimental/.github/workflows/build.yml@refs/heads/build-reusable-workflow --certificate-oidc-issuer https://token.actions.githubusercontent.com ghcr.io/docker/github-builder-test@sha256:61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83
    
    Verification for ghcr.io/docker/github-builder-test@sha256:61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83 --
    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 code-signing certificate was verified using trusted certificate authority certificates
    
    [{"critical":{"identity":{"docker-reference":"ghcr.io/docker/github-builder-test"},"image":{"docker-manifest-digest":"sha256:61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83"},"type":"cosign container image signature"},"optional":{"1.3.6.1.4.1.57264.1.1":"https://token.actions.githubusercontent.com","1.3.6.1.4.1.57264.1.2":"push","1.3.6.1.4.1.57264.1.3":"9b781852ce18ef8294c317678c0f29fe748cb893","1.3.6.1.4.1.57264.1.4":"ci","1.3.6.1.4.1.57264.1.5":"docker/github-builder-test","1.3.6.1.4.1.57264.1.6":"refs/heads/main","Bundle":{"SignedEntryTimestamp":"MEYCIQCZ5cYUaXTZoZ8ssEAUs6kGSLCxN8Ri2LWmW1H5adBNvwIhALWltZzxNnO1kpKUnjkmSzJbW5v8qf6RWZdD59ZUuRjg","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NDcxNjg5OThjZTgzOWYwM2RmZjdmMTMyYzdmYTdkYWFlMTk4ODU4NGU0MzI4MTQwMTBmYjFmMmY5ODZmZmUxIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJSGZnZEZuUDJ4UHFiZVA5bDNZV2lhTlM2S0h3cWJMSlJDeGxjam5UYjVLOUFpQU9DaW04WHE1NHV1cTBPSE1QUUJhK1lmSzkyMFlxWjkvYmRCSFJXSVhkYmc9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVaENSRU5EUW05eFowRjNTVUpCWjBsVlVGbDNUMHRaU0hveFRFbFFLMHBPVDFGMGNYRnNVbFkyTnpsbmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUlRWTlJHZDZUa1JCZDFkb1kwNU5hbFYzVDBSRk5VMUVaekJPUkVGM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZZYWtsTWNXMVllRWd3VUVsR1ZYcDFVbTgxVVhWWFVuaElia0pZUzBnd1ppOXJaMndLVTFVM1QzUktiMlJvYkVObFZVSnlURmxaYVcxWlNIZHFMMUU0TDJJd1NXdFRWMFpYZFRoSWJsTTJaRlZ2V0hwNGREWlBRMEpoYTNkbloxZHNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZGTmtoSkNtMUZUVmd2VEZaNFZFeHZObTlUWTNWWlZtd3lNbXRSZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDJkWlNVZEJNVlZrUlZGRlFpOTNValJOU0dGSFpFZG9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWEySXlUbkphV0VsMldqSnNNQXBoU0ZacFRGZEtNV0ZYZUd0YVdFbDBXbGhvZDFwWVNuQmlWMVoxWkVkR2MweDVOVzVoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3eVNqRmhWM2hyQ2t4dWJIUmlSVUo1V2xkYWVrd3lhR3haVjFKNlRESktNV0ZYZUd0TVdFcHNaRmhPYUZsdGVHeE1XR1IyWTIxMGJXSkhPVE5OUkd0SFEybHpSMEZSVVVJS1p6YzRkMEZSUlVWTE1tZ3daRWhDZWs5cE9IWmtSemx5V2xjMGRWbFhUakJoVnpsMVkzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFncGlNakIzUldkWlMwdDNXVUpDUVVkRWRucEJRa0ZuVVVWalNGWjZZVVJCTWtKbmIzSkNaMFZGUVZsUEwwMUJSVVJDUTJjMVdXcGpORTFVWnpGTmJVNXNDazFVYUd4YWFtZDVUMVJTYWsxNlJUTk9hbU0wV1hwQ2JVMXFiRzFhVkdNd1QwZE9hVTlFYTNwTlFrRkhRMmx6UjBGUlVVSm5OemgzUVZGUlJVRnRUbkFLVFVOblIwTnBjMGRCVVZGQ1p6YzRkMEZSVlVWSGJWSjJXVEowYkdOcE9XNWhXRkp2WkZkSmRGbHVWbkJpUjFKc1kya3hNRnBZVGpCTlFqQkhRMmx6UndwQlVWRkNaemM0ZDBGUldVVkVNMHBzV201TmRtRkhWbWhhU0UxMllsZEdjR0pxUVRkQ1oyOXlRbWRGUlVGWlR5OU5RVVZKUWtNd1RVc3lhREJrU0VKNkNrOXBPSFprUnpseVdsYzBkVmxYVGpCaFZ6bDFZM2sxYm1GWVVtOWtWMG94WXpKV2VWa3lPWFZrUjFaMVpFTTFhbUl5TUhkbldWRkhRMmx6UjBGUlVVSUtaemM0ZDBGUmEwVmtaM2d3WVVoU01HTklUVFpNZVRsdVlWaFNiMlJYU1hWWk1qbDBUREpTZGxreWRHeGphVGx1WVZoU2IyUlhTWFJaYmxad1lrZFNiQXBqYVRGc1pVaENiR050YkhSYVZ6VXdXVmQzZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbGx1Vm5CaVIxRjFaVmN4YzFGSVNteGFiazEyQ21GSFZtaGFTRTEyV1c1V2NHSkhVWFJqYlZZeFl6SkdhV0pIVlhSa01qbDVZVEphYzJJelkzZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1EyZFJjVVJEWjNvS1RqSkpNRnBxYUcxWmFsazFXbGRTYWsxdFdteFpNa1YzV2xSWmVrNXFTWGhaVkZrd1RUSlZNMWxYVVRWTlZGRjNXVzFKZDAxQ01FZERhWE5IUVZGUlFncG5OemgzUVZGelJVUjNkMDVhTW13d1lVaFdhVXhYYUhaak0xSnNXa1JCT1VKbmIzSkNaMFZGUVZsUEwwMUJSVTFDUXpoTlRGZG9NR1JJUW5wUGFUaDJDbG95YkRCaFNGWnBURzFPZG1KVE9XdGlNazV5V2xoSmRsb3liREJoU0ZacFRGZEtNV0ZYZUd0YVdFbDBaRWRXZW1SRVFUUkNaMjl5UW1kRlJVRlpUeThLVFVGRlRrSkRiMDFMUkd4cFRucG5lRTlFVlhsWk1sVjRUMGRXYlU5RVNUVk9SMDE2VFZSak1rNTZhR3BOUjFsNVQxZGFiRTU2VVRSWk1razBUMVJOZHdwSWQxbExTM2RaUWtKQlIwUjJla0ZDUkdkUlVrUkJPWGxhVjFwNlRESm9iRmxYVW5wTU1qRm9ZVmMwZDBkbldVdExkMWxDUWtGSFJIWjZRVUpFZDFGTkNrUkJiM2hOUkZGM1RsUnJNRTFxWnpOTlEydEhRMmx6UjBGUlVVSm5OemgzUVZKQlJVZDNkMXBoU0ZJd1kwaE5Oa3g1T1c1aFdGSnZaRmRKZFZreU9YUUtUREpTZGxreWRHeGpha0ZZUW1kdmNrSm5SVVZCV1U4dlRVRkZVa0pCYTAxQ2VsVXdUV3ByTUU1NlFYZGFaMWxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXUXBFUmxwdlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyV2tjNWFtRXlWbmxNTW1Sd1pFZG9NVmxwTVdsa1YyeHpXa2RXZVV4WVVteGpNMUYyQ2t4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbGt5YTNWbFZ6RnpVVWhLYkZwdVRYWmhSMVpvV2toTmRtSlhSbkJpYWtFMFFtZHZja0puUlVVS1FWbFBMMDFCUlZSQ1EyOU5TMFJzYVU1NlozaFBSRlY1V1RKVmVFOUhWbTFQUkVrMVRrZE5lazFVWXpKT2VtaHFUVWRaZVU5WFdteE9lbEUwV1RKSk5BcFBWRTEzUmtGWlMwdDNXVUpDUVVkRWRucEJRa1pCVVVkRVFWSjNaRmhPYjAxSFJVZERhWE5IUVZGUlFtYzNPSGRCVWxWRlZYZDRVbUZJVWpCalNFMDJDa3g1T1c1aFdGSnZaRmRKZFZreU9YUk1NbEoyV1RKMGJHTnBPVzVoV0ZKdlpGZEpkRmx1Vm5CaVIxSnNZMmt4TUZwWVRqQk1Na1pxWkVkc2RtSnVUWFlLWTI1V2RXTjVPSGhPZWtFeVRrUkZlVTlVWXpOT1V6bG9aRWhTYkdKWVFqQmplVGg0VFVKblIwTnBjMGRCVVZGQ1p6YzRkMEZTV1VWRFozZEpZVmMxTUFwYVdFcDFXVmQzZDJkWmIwZERhWE5IUVZGUlFqRnVhME5DUVVsRlprRlNOa0ZJWjBGa1owUmtVRlJDY1hoelkxSk5iVTFhU0doNVdscDZZME52YTNCbENuVk9ORGh5Wml0SWFXNUxRVXg1Ym5WcVowRkJRVnBxUW1SeWVXbEJRVUZGUVhkQ1NFMUZWVU5KVVVSU05VNWFhQzkwZEdOalpEWTJRa3hsT0dwSVZHRUtjQ3RZYkhWRVVHTjVlVTFPYlhkak1EVTBPRW8yVVVsblVYQTJWbmt6ZDFoS016SlVVRTUzWVROdGMyY3JTRVJHYzBOQlNXbzVaMDFyV1UxSU1td3lVZ3BzYmpoM1EyZFpTVXR2V2tsNmFqQkZRWGROUkdGQlFYZGFVVWw0UVV0NWJFTjNlRFJJWmsxNGRIRnBiWEpPY0ZGV2MzTnpiMU5UYlhWWFl6ZFpZMEZTQ21FNFluVm5NMHBtU2pZd09GZFFNRzlqTDJ0T2FscDNVVmhTVFRCR1VVbDNTbGRrTVd0UllVUkdUV05IVWtwRk0wRjROMjV4VldOTVltaE5iRTF0VVdjS2JWUnNWbFJNVlhvck56WXdjSE4xVkM5bGNqTTBVMVZxYkdaRGNYWkxaV1FLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0=","integratedTime":1755592441,"logIndex":409441272,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}},"Issuer":"https://token.actions.githubusercontent.com","Subject":"/docker/github-builder-experimental/.github/workflows/build.yml@refs/heads/build-reusable-workflow","githubWorkflowName":"ci","githubWorkflowRef":"refs/heads/main","githubWorkflowRepository":"docker/github-builder-test","githubWorkflowSha":"9b781852ce18ef8294c317678c0f29fe748cb893","githubWorkflowTrigger":"push"}},{"critical":{"identity":{"docker-reference":"ghcr.io/docker/github-builder-test"},"image":{"docker-manifest-digest":"sha256:61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83"},"type":"cosign container image signature"},"optional":{"1.3.6.1.4.1.57264.1.1":"https://token.actions.githubusercontent.com","1.3.6.1.4.1.57264.1.2":"push","1.3.6.1.4.1.57264.1.3":"9b781852ce18ef8294c317678c0f29fe748cb893","1.3.6.1.4.1.57264.1.4":"ci","1.3.6.1.4.1.57264.1.5":"docker/github-builder-test","1.3.6.1.4.1.57264.1.6":"refs/heads/main","Bundle":{"SignedEntryTimestamp":"MEUCICXoAncyh/Th/foMukAQM52NOocKQLTk9MeowJeTx/eUAiEAgVVOx5D0jGa7i83VcVtgcTavipOdWFH9dA45ePr9ADk=","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI1NDcxNjg5OThjZTgzOWYwM2RmZjdmMTMyYzdmYTdkYWFlMTk4ODU4NGU0MzI4MTQwMTBmYjFmMmY5ODZmZmUxIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJRnA3NzRKL3F1YW80VHlyUTZ1VWgwa3NxcEpyRjNjS3ZGNVRZR1RwWWRBRUFpRUE1emVCeFJEUjFTNHNraVR4YWZnbVhQK1o1YUtsY25jMkxuR2RwWGZGdGZ3PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVaENSRU5EUW05eFowRjNTVUpCWjBsVlVGbDNUMHRaU0hveFRFbFFLMHBPVDFGMGNYRnNVbFkyTnpsbmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcFZkMDlFUlRWTlJHZDZUa1JCZDFkb1kwNU5hbFYzVDBSRk5VMUVaekJPUkVGM1YycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVZZYWtsTWNXMVllRWd3VUVsR1ZYcDFVbTgxVVhWWFVuaElia0pZUzBnd1ppOXJaMndLVTFVM1QzUktiMlJvYkVObFZVSnlURmxaYVcxWlNIZHFMMUU0TDJJd1NXdFRWMFpYZFRoSWJsTTJaRlZ2V0hwNGREWlBRMEpoYTNkbloxZHNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZGTmtoSkNtMUZUVmd2VEZaNFZFeHZObTlUWTNWWlZtd3lNbXRSZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDJkWlNVZEJNVlZrUlZGRlFpOTNValJOU0dGSFpFZG9NR1JJUW5wUGFUaDJXakpzTUdGSVZtbE1iVTUyWWxNNWEySXlUbkphV0VsMldqSnNNQXBoU0ZacFRGZEtNV0ZYZUd0YVdFbDBXbGhvZDFwWVNuQmlWMVoxWkVkR2MweDVOVzVoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3eVNqRmhWM2hyQ2t4dWJIUmlSVUo1V2xkYWVrd3lhR3haVjFKNlRESktNV0ZYZUd0TVdFcHNaRmhPYUZsdGVHeE1XR1IyWTIxMGJXSkhPVE5OUkd0SFEybHpSMEZSVVVJS1p6YzRkMEZSUlVWTE1tZ3daRWhDZWs5cE9IWmtSemx5V2xjMGRWbFhUakJoVnpsMVkzazFibUZZVW05a1Ywb3hZekpXZVZreU9YVmtSMVoxWkVNMWFncGlNakIzUldkWlMwdDNXVUpDUVVkRWRucEJRa0ZuVVVWalNGWjZZVVJCTWtKbmIzSkNaMFZGUVZsUEwwMUJSVVJDUTJjMVdXcGpORTFVWnpGTmJVNXNDazFVYUd4YWFtZDVUMVJTYWsxNlJUTk9hbU0wV1hwQ2JVMXFiRzFhVkdNd1QwZE9hVTlFYTNwTlFrRkhRMmx6UjBGUlVVSm5OemgzUVZGUlJVRnRUbkFLVFVOblIwTnBjMGRCVVZGQ1p6YzRkMEZSVlVWSGJWSjJXVEowYkdOcE9XNWhXRkp2WkZkSmRGbHVWbkJpUjFKc1kya3hNRnBZVGpCTlFqQkhRMmx6UndwQlVWRkNaemM0ZDBGUldVVkVNMHBzV201TmRtRkhWbWhhU0UxMllsZEdjR0pxUVRkQ1oyOXlRbWRGUlVGWlR5OU5RVVZKUWtNd1RVc3lhREJrU0VKNkNrOXBPSFprUnpseVdsYzBkVmxYVGpCaFZ6bDFZM2sxYm1GWVVtOWtWMG94WXpKV2VWa3lPWFZrUjFaMVpFTTFhbUl5TUhkbldWRkhRMmx6UjBGUlVVSUtaemM0ZDBGUmEwVmtaM2d3WVVoU01HTklUVFpNZVRsdVlWaFNiMlJYU1hWWk1qbDBUREpTZGxreWRHeGphVGx1WVZoU2IyUlhTWFJaYmxad1lrZFNiQXBqYVRGc1pVaENiR050YkhSYVZ6VXdXVmQzZGt4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbGx1Vm5CaVIxRjFaVmN4YzFGSVNteGFiazEyQ21GSFZtaGFTRTEyV1c1V2NHSkhVWFJqYlZZeFl6SkdhV0pIVlhSa01qbDVZVEphYzJJelkzZFBRVmxMUzNkWlFrSkJSMFIyZWtGQ1EyZFJjVVJEWjNvS1RqSkpNRnBxYUcxWmFsazFXbGRTYWsxdFdteFpNa1YzV2xSWmVrNXFTWGhaVkZrd1RUSlZNMWxYVVRWTlZGRjNXVzFKZDAxQ01FZERhWE5IUVZGUlFncG5OemgzUVZGelJVUjNkMDVhTW13d1lVaFdhVXhYYUhaak0xSnNXa1JCT1VKbmIzSkNaMFZGUVZsUEwwMUJSVTFDUXpoTlRGZG9NR1JJUW5wUGFUaDJDbG95YkRCaFNGWnBURzFPZG1KVE9XdGlNazV5V2xoSmRsb3liREJoU0ZacFRGZEtNV0ZYZUd0YVdFbDBaRWRXZW1SRVFUUkNaMjl5UW1kRlJVRlpUeThLVFVGRlRrSkRiMDFMUkd4cFRucG5lRTlFVlhsWk1sVjRUMGRXYlU5RVNUVk9SMDE2VFZSak1rNTZhR3BOUjFsNVQxZGFiRTU2VVRSWk1razBUMVJOZHdwSWQxbExTM2RaUWtKQlIwUjJla0ZDUkdkUlVrUkJPWGxhVjFwNlRESm9iRmxYVW5wTU1qRm9ZVmMwZDBkbldVdExkMWxDUWtGSFJIWjZRVUpFZDFGTkNrUkJiM2hOUkZGM1RsUnJNRTFxWnpOTlEydEhRMmx6UjBGUlVVSm5OemgzUVZKQlJVZDNkMXBoU0ZJd1kwaE5Oa3g1T1c1aFdGSnZaRmRKZFZreU9YUUtUREpTZGxreWRHeGpha0ZZUW1kdmNrSm5SVVZCV1U4dlRVRkZVa0pCYTAxQ2VsVXdUV3ByTUU1NlFYZGFaMWxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNXUXBFUmxwdlpFaFNkMk42YjNaTU1tUndaRWRvTVZscE5XcGlNakIyV2tjNWFtRXlWbmxNTW1Sd1pFZG9NVmxwTVdsa1YyeHpXa2RXZVV4WVVteGpNMUYyQ2t4dFpIQmtSMmd4V1drNU0ySXpTbkphYlhoMlpETk5kbGt5YTNWbFZ6RnpVVWhLYkZwdVRYWmhSMVpvV2toTmRtSlhSbkJpYWtFMFFtZHZja0puUlVVS1FWbFBMMDFCUlZSQ1EyOU5TMFJzYVU1NlozaFBSRlY1V1RKVmVFOUhWbTFQUkVrMVRrZE5lazFVWXpKT2VtaHFUVWRaZVU5WFdteE9lbEUwV1RKSk5BcFBWRTEzUmtGWlMwdDNXVUpDUVVkRWRucEJRa1pCVVVkRVFWSjNaRmhPYjAxSFJVZERhWE5IUVZGUlFtYzNPSGRCVWxWRlZYZDRVbUZJVWpCalNFMDJDa3g1T1c1aFdGSnZaRmRKZFZreU9YUk1NbEoyV1RKMGJHTnBPVzVoV0ZKdlpGZEpkRmx1Vm5CaVIxSnNZMmt4TUZwWVRqQk1Na1pxWkVkc2RtSnVUWFlLWTI1V2RXTjVPSGhPZWtFeVRrUkZlVTlVWXpOT1V6bG9aRWhTYkdKWVFqQmplVGg0VFVKblIwTnBjMGRCVVZGQ1p6YzRkMEZTV1VWRFozZEpZVmMxTUFwYVdFcDFXVmQzZDJkWmIwZERhWE5IUVZGUlFqRnVhME5DUVVsRlprRlNOa0ZJWjBGa1owUmtVRlJDY1hoelkxSk5iVTFhU0doNVdscDZZME52YTNCbENuVk9ORGh5Wml0SWFXNUxRVXg1Ym5WcVowRkJRVnBxUW1SeWVXbEJRVUZGUVhkQ1NFMUZWVU5KVVVSU05VNWFhQzkwZEdOalpEWTJRa3hsT0dwSVZHRUtjQ3RZYkhWRVVHTjVlVTFPYlhkak1EVTBPRW8yVVVsblVYQTJWbmt6ZDFoS016SlVVRTUzWVROdGMyY3JTRVJHYzBOQlNXbzVaMDFyV1UxSU1td3lVZ3BzYmpoM1EyZFpTVXR2V2tsNmFqQkZRWGROUkdGQlFYZGFVVWw0UVV0NWJFTjNlRFJJWmsxNGRIRnBiWEpPY0ZGV2MzTnpiMU5UYlhWWFl6ZFpZMEZTQ21FNFluVm5NMHBtU2pZd09GZFFNRzlqTDJ0T2FscDNVVmhTVFRCR1VVbDNTbGRrTVd0UllVUkdUV05IVWtwRk0wRjROMjV4VldOTVltaE5iRTF0VVdjS2JWUnNWbFJNVlhvck56WXdjSE4xVkM5bGNqTTBVMVZxYkdaRGNYWkxaV1FLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0=","integratedTime":1755592445,"logIndex":409441283,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}},"Issuer":"https://token.actions.githubusercontent.com","Subject":"/docker/github-builder-experimental/.github/workflows/build.yml@refs/heads/build-reusable-workflow","githubWorkflowName":"ci","githubWorkflowRef":"refs/heads/main","githubWorkflowRepository":"docker/github-builder-test","githubWorkflowSha":"9b781852ce18ef8294c317678c0f29fe748cb893","githubWorkflowTrigger":"push"}}]
    

    Looking at the cosign certificate: https://explore.ggcr.dev/?image=ghcr.io%2Fdocker%2Fgithub-builder-test%3Asha256-61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83.sig%40sha256%3A8c08d5bf5f3daa35c223feb962aefc66be8b43fab39997e3e93c277cf8382ec7&jq=.layers%5B0%5D.annotations%5B%22dev.sigstore.cosign%2Fcertificate%22%5D&render=x509

    For verification we need the issuer and subject as you can see in the command above:

    X509v3 Subject Alternative Name: critical
                    uri:https://github.com/docker/github-builder-experimental/.github/workflows/build.yml@refs/heads/build-reusable-workflow
                Fulcio Issuer: 
                    https://token.actions.githubusercontent.com/
    

    I pushed an extra commit in #4 to verify the signature 0527eec.

    I'm using --certificate-identity-regexp as user can pin the reusable workflow to whatever ref he wants like docker/github-builder-experimental/.github/workflows/build.yml@deadbeef. I think matching the workflow itself is enough.

  13. crazy-max commented on Aug 19, 2025

    @crazy-max
    MemberAuthor

    Looking at the cosign certificate: https://explore.ggcr.dev/?image=ghcr.io%2Fdocker%2Fgithub-builder-test%3Asha256-61be0b09ee99d79f9443b60a11a35a8d0d14dbc44050d3c096a07f8e1b76de83.sig%40sha256%3A8c08d5bf5f3daa35c223feb962aefc66be8b43fab39997e3e93c277cf8382ec7&jq=.layers%5B0%5D.annotations%5B%22dev.sigstore.cosign%2Fcertificate%22%5D&render=x509

    @tonistiigi And I looked at this certificate and some OID extensions look interesting for us: https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#directory

    Breaking it down:

    OID Meaning (Sigstore extension) Value (decoded from hex)
    1.3.6.1.4.1.57264.1.8 OIDC Issuer https://token.actions.githubusercontent.com
    1.3.6.1.4.1.57264.1.9 GitHub Workflow Reference (SAN-style) https://github.com/docker/github-builder-experimental/.github/workflows/build.yml@refs/heads/build-reusable-workflow
    1.3.6.1.4.1.57264.1.10 Git commit SHA 37b4f8fb69edc2feca0e63621a643e7ad9140bb0
    1.3.6.1.4.1.57264.1.11 Runner environment github-hosted
    1.3.6.1.4.1.57264.1.12 Repository URL https://github.com/docker/github-builder-test
    1.3.6.1.4.1.57264.1.13 Workflow SHA 9b781852ce18ef8294c317678c0f29fe748cb893
    1.3.6.1.4.1.57264.1.14 Ref (branch/tag) refs/heads/main
    1.3.6.1.4.1.57264.1.15 Run ID 1040594287
    1.3.6.1.4.1.57264.1.16 GitHub repository URL https://github.com/docker
    1.3.6.1.4.1.57264.1.17 Run Attempt 5429470
    1.3.6.1.4.1.57264.1.18 Workflow path ref https://github.com/docker/github-builder-test/.github/workflows/ci.yml@refs/heads/main
    1.3.6.1.4.1.57264.1.19 Workflow SHA (duplicate) 9b781852ce18ef8294c317678c0f29fe748cb893
    1.3.6.1.4.1.57264.1.20 Trigger event push
    1.3.6.1.4.1.57264.1.21 Workflow run URL https://github.com/docker/github-builder-test/actions/runs/17064129775/attempts/1
    1.3.6.1.4.1.57264.1.22 Runner type internal
  14. crazy-max commented on Aug 19, 2025

    @crazy-max
    MemberAuthor

    We want signatures pushed by digest unlike cosign that pushes a tag matching the signed manifest using the format <repo>/<image>:sha256-<manifest-digest>.sig. Verification will be done using the OCI Referrers API.

    So cosign verify always expects a tag matching signed manifest digest we want to verify: https://github.com/docker/github-builder-test/actions/runs/17067059102/job/48386629858#step:9:282

    Image

    Looking at cosign code base:

    But with referrers API (OCI 1.1) we would not need a tag:

    So a tag is necessary if referrers API is not supported.

    See also related thread on cosign repo: sigstore/cosign#4335

  15. removed theissue type on Aug 19, 2025
  16. 8 remaining items

  17. crazy-max commented on Oct 15, 2025

    @crazy-max
    MemberAuthor
  18. crazy-max commented on Oct 16, 2025

    @crazy-max
    MemberAuthor

    As discussed with @tonistiigi, need to check if we can change the docker-reference in simple-signing payload:

    https://oci.dag.dev/?image=public.ecr.aws%2Fq3b5f1u4%2Ftest-docker-action%40sha256%3A670d819051bdec9cb7e4789217cd2fae3e4f1359376421ada2af1e4d53f84d3e

    We can add annotations to the simple signing payload: https://docs.sigstore.dev/cosign/signing/signing_with_containers/#add-annotations-with-a-signature

    In 0c9cabc, I have added an vnd.docker.reference.origin annotation that will be added to the signature payload.

    {
      "critical":{
        "identity":{
          "docker-reference":"public.ecr.aws/q3b5f1u4/test-docker-action"
        },
        "image":{
          "docker-manifest-digest":"sha256:30c65011829bf47c847815f1133bd86992d43ee388e507a908dd0251650d4885"
        },
        "type":"cosign container image signature"
      },
      "optional":{
        "vnd.docker.reference.origin":"docker.io/github-builder/docker/github-builder-test"
      }
    }

    During signature verification we can also pass this annotation to make sure it exists in the payload otherwise verification fails.

  19. tonistiigi commented on Oct 28, 2025

    @tonistiigi
    Member

    A major difference I see is that there is no identity.docker-reference anymore. Not sure if that is a good or a bad thing.

  20. crazy-max commented on Oct 29, 2025

    @crazy-max
    MemberAuthor

    A major difference I see is that there is no identity.docker-reference anymore. Not sure if that is a good or a bad thing.

    Yeah that's what I meant by:

    Seems there is no signing payload anymore and therefore custom annotation https://github.com/docker/github-builder-experimental/pull/4/files#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721R220 is a noop 🤔

    I will take a closer look at this one.

  21. crazy-max commented on Oct 30, 2025

    @crazy-max
    MemberAuthor

    Seems there is no signing payload anymore and therefore custom annotation https://github.com/docker/github-builder-experimental/pull/4/files#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721R220 is a noop 🤔

    I will take a closer look at this one.

    @tonistiigi Ok I can confirm that since Cosign v3 with new bundle format there is no signing payload anymore and therefore no custom annotations. They switch to in-toto format: https://oci.dag.dev/?blob=public.ecr.aws%2Fq3b5f1u4%2Ftest-docker-action%40sha256%3A0182f40522b859af3f401b16a2919dc155fd8566805c114e669d829acc6d0c93&jq=.dsseEnvelope.payload&jq=base64+-d&jq=jq&mt=application%2Fvnd.dev.sigstore.bundle.v0.3%2Bjson&size=10865

    {
      "subject":[
        {
          "digest":{
            "sha256":"1e5b9f69d13910a6a363a4f3181ed344844dab923596d48f1051fa3c4ed11e5e"
          }
        }
      ],
      "_type":"https://in-toto.io/Statement/v1",
      "predicateType":"https://sigstore.dev/cosign/sign/v1"
    }

    This is the DSSE envelope payload of this signature: https://oci.dag.dev/?blob=public.ecr.aws/q3b5f1u4/test-docker-action@sha256:0182f40522b859af3f401b16a2919dc155fd8566805c114e669d829acc6d0c93&mt=application%2Fvnd.dev.sigstore.bundle.v0.3%2Bjson&size=10865

    The subject digest 1e5b9f69d13910a6a363a4f3181ed344844dab923596d48f1051fa3c4ed11e5e is the attestation manifest one: https://oci.dag.dev/?image=public.ecr.aws%2Fq3b5f1u4%2Ftest-docker-action%40sha256:1e5b9f69d13910a6a363a4f3181ed344844dab923596d48f1051fa3c4ed11e5e

    Looking at the signature manifest: https://oci.dag.dev/?image=public.ecr.aws%2Fq3b5f1u4%2Ftest-docker-action%40sha256:70ede6a5012b62444c0e396a45696697a0107945cb5ee4d90a9f332d61215d98

    {
      "schemaVersion":2,
      "mediaType":"application/vnd.oci.image.manifest.v1+json",
      "artifactType":"application/vnd.dev.sigstore.bundle.v0.3+json",
      "config":{
        "mediaType":"application/vnd.oci.empty.v1+json",
        "artifactType":"application/vnd.dev.sigstore.bundle.v0.3+json",
        "digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
        "size":2
      },
      "layers":[
        {
          "mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json",
          "digest":"sha256:0182f40522b859af3f401b16a2919dc155fd8566805c114e669d829acc6d0c93",
          "size":10865
        }
      ],
      "subject":{
        "mediaType":"application/vnd.oci.image.manifest.v1+json",
        "digest":"sha256:1e5b9f69d13910a6a363a4f3181ed344844dab923596d48f1051fa3c4ed11e5e",
        "size":1380
      },
      "annotations":{
        "dev.sigstore.bundle.content":"dsse-envelope",
        "dev.sigstore.bundle.predicateType":"https://sigstore.dev/cosign/sign/v1",
        "org.opencontainers.image.created":"2025-10-30T22:13:10Z"
      }
    }

    I think we could set an annotation along these ones?

  22. tonistiigi commented on Oct 30, 2025

    @tonistiigi
    Member

    I'm not sure we need the additional annotation. Our problem from the start was that we couldn't provide any safety guarantees that signing identity is the owner of docker-reference namespace, unless setting it to the name that is in the namespace of the builder. So maybe just skip it, and all policies need to be based on the certificate fields.

  23. crazy-max commented on Oct 30, 2025

    @crazy-max
    MemberAuthor

    Sounds good.

    Btw I have started to move the signing/verification for attestation manifests to our actions-toolkit: crazy-max/docker-actions-toolkit@d28078d#diff-2176881a803f6ad4252e5498544d8b98bd34298dca27ad666d2cf39fb0b47349R96-R116

    I think I will use the sigstore node module directly instead but still verify with Cosign. Atm Cosign v3 does not return any useful metadata with cosign sign cmd to track the signing result. Many of the flags are noop now without any hints about it. 😣

  24. crazy-max commented on Oct 31, 2025

    @crazy-max
    MemberAuthor

    I think I will use the sigstore node module directly instead but still verify with Cosign. Atm Cosign v3 does not return any useful metadata with cosign sign cmd to track the signing result. Many of the flags are noop now without any hints about it. 😣

    Started to work on it crazy-max/docker-actions-toolkit@0f8a4b1.

    Here is a run: https://github.com/docker/github-builder-test/actions/runs/18958059877

    The @sigstore/oci node module is not good (to say the least)...

    It can't authenticate to Docker Hub and assume registry is my handle: https://github.com/docker/github-builder-test/actions/runs/18958059877/job/54139278364#step:10:54

    Error: Signing BuildKit attestation manifests failed: No credentials found for registry crazymax
    

    Might just be a matter of always setting docker.io but it should default to docker registry. I think their image name parser is broken: https://github.com/sigstore/sigstore-js/blob/main/packages/oci/src/name.ts

    It also does not support credential helpers but not really an issue with GHA.

    Also found that it arbitrarily changes the registry domain to docker.io when trying to push to Docker Hub stage 😨: https://github.com/sigstore/sigstore-js/blob/cee51c0c25be1bea484129a5e9f766d08da48d88/packages/oci/src/image.ts#L233

  25. crazy-max commented on Nov 2, 2025

    @crazy-max
    MemberAuthor

    I'm not sure we need the additional annotation. Our problem from the start was that we couldn't provide any safety guarantees that signing identity is the owner of docker-reference namespace, unless setting it to the name that is in the namespace of the builder. So maybe just skip it, and all policies need to be based on the certificate fields.

    Seems they are going to fix missing annotations in new bundle: sigstore/cosign#4508

  26. crazy-max commented on Nov 4, 2025

    @crazy-max
    MemberAuthor

    Made a release of the actions-toolkit with sigstore and cosign additions so we can test it in our reusable workflow:

    Our reusable workflow now support multiple image names for both signing et create the final manifest:

    Also needed to add a new output to our metadata-action to just output tag names to be able to run imagetools create for each image name (registry): docker/metadata-action#553. Released in https://github.com/docker/metadata-action/releases/tag/v5.9.0.

  27. added theissue type on Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions