-
Notifications
You must be signed in to change notification settings - Fork 50
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
gcb: add gcb compatibility for provenance formats and buckets #292
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
{ | ||
"image_summary": { | ||
"digest": "sha256:71efcbb3f03f5914dcde87e38d3813f63982b475f76887babf25f76fff760d3c", | ||
"fully_qualified_digest": "us-west2-docker.pkg.dev/slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3@sha256:71efcbb3f03f5914dcde87e38d3813f63982b475f76887babf25f76fff760d3c", | ||
"registry": "us-west2-docker.pkg.dev", | ||
"repository": "example-package-repo" | ||
}, | ||
"provenance_summary": { | ||
"provenance": [ | ||
{ | ||
"build": { | ||
"intotoStatement": { | ||
"_type": "https://in-toto.io/Statement/v0.1", | ||
"predicateType": "https://slsa.dev/provenance/v0.1", | ||
"slsaProvenance": { | ||
"builder": { | ||
"id": "https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.3" | ||
}, | ||
"materials": [ | ||
{ | ||
"digest": { | ||
"md5": "7d4467b5b74959c39c08b3c8545ffac1", | ||
"sha256": "9c4e7e28bef5c9ffabea170a40bfb6e286e170100c0eb02d7e06c7dd8c2238e4" | ||
}, | ||
"uri": "gs://slsa-tooling_cloudbuild/source/1663616632.078353-fc7db143dcc64b5f9fe71d0497125ca1.tgz#1663616635134845" | ||
} | ||
], | ||
"metadata": { | ||
"buildFinishedOn": "2022-09-19T19:44:34.152421Z", | ||
"buildInvocationId": "393794dc-82ec-495b-8f84-659dec87d381", | ||
"buildStartedOn": "2022-09-19T19:43:56.076114651Z" | ||
}, | ||
"recipe": { | ||
"arguments": { | ||
"@type": "type.googleapis.com/google.devtools.cloudbuild.v1.Build", | ||
"id": "393794dc-82ec-495b-8f84-659dec87d381", | ||
"name": "projects/819720953812/locations/us-west2/builds/393794dc-82ec-495b-8f84-659dec87d381", | ||
"options": { | ||
"logging": "CLOUD_LOGGING_ONLY", | ||
"pool": {}, | ||
"requestedVerifyOption": "VERIFIED", | ||
"sourceProvenanceHash": [ | ||
"SHA256" | ||
] | ||
}, | ||
"sourceProvenance": { | ||
"fileHashes": { | ||
"gs://slsa-tooling_cloudbuild/source/1663616632.078353-fc7db143dcc64b5f9fe71d0497125ca1.tgz#1663616635134845": { | ||
"fileHash": [ | ||
{ | ||
"type": "SHA256", | ||
"value": "nE5+KL71yf+r6hcKQL+24obhcBAMDrAtfgbH3YwiOOQ=" | ||
}, | ||
{ | ||
"type": "MD5", | ||
"value": "fURntbdJWcOcCLPIVF/6wQ==" | ||
} | ||
] | ||
} | ||
}, | ||
"resolvedStorageSource": { | ||
"bucket": "slsa-tooling_cloudbuild", | ||
"generation": "1663616635134845", | ||
"object": "source/1663616632.078353-fc7db143dcc64b5f9fe71d0497125ca1.tgz" | ||
} | ||
}, | ||
"steps": [ | ||
{ | ||
"args": [ | ||
"build", | ||
"-t", | ||
"us-west2-docker.pkg.dev/slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3", | ||
"." | ||
], | ||
"name": "gcr.io/cloud-builders/docker", | ||
"pullTiming": { | ||
"endTime": "2022-09-19T19:44:02.300470459Z", | ||
"startTime": "2022-09-19T19:44:02.296558439Z" | ||
}, | ||
"status": "SUCCESS", | ||
"timing": { | ||
"endTime": "2022-09-19T19:44:32.329696525Z", | ||
"startTime": "2022-09-19T19:44:02.296558439Z" | ||
} | ||
} | ||
], | ||
"substitutions": { | ||
"_IMAGE_NAME": "slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3" | ||
} | ||
}, | ||
"definedInMaterial": "-1", | ||
"type": "https://cloudbuild.googleapis.com/CloudBuildSteps@v0.1" | ||
} | ||
}, | ||
"subject": [ | ||
{ | ||
"digest": { | ||
"sha256": "71efcbb3f03f5914dcde87e38d3813f63982b475f76887babf25f76fff760d3c" | ||
}, | ||
"name": "https://us-west2-docker.pkg.dev/slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3" | ||
}, | ||
{ | ||
"digest": { | ||
"sha256": "71efcbb3f03f5914dcde87e38d3813f63982b475f76887babf25f76fff760d3c" | ||
}, | ||
"name": "https://us-west2-docker.pkg.dev/slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3:latest" | ||
} | ||
] | ||
} | ||
}, | ||
"createTime": "2022-09-19T19:44:35.879537Z", | ||
"envelope": { | ||
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZSI6eyJidWlsZGVyIjp7ImlkIjoiaHR0cHM6Ly9jbG91ZGJ1aWxkLmdvb2dsZWFwaXMuY29tL0dvb2dsZUhvc3RlZFdvcmtlckB2MC4zIn0sIm1hdGVyaWFscyI6W3siZGlnZXN0Ijp7Im1kNSI6IjdkNDQ2N2I1Yjc0OTU5YzM5YzA4YjNjODU0NWZmYWMxIiwic2hhMjU2IjoiOWM0ZTdlMjhiZWY1YzlmZmFiZWExNzBhNDBiZmI2ZTI4NmUxNzAxMDBjMGViMDJkN2UwNmM3ZGQ4YzIyMzhlNCJ9LCJ1cmkiOiJnczovL3Nsc2EtdG9vbGluZ19jbG91ZGJ1aWxkL3NvdXJjZS8xNjYzNjE2NjMyLjA3ODM1My1mYzdkYjE0M2RjYzY0YjVmOWZlNzFkMDQ5NzEyNWNhMS50Z3ojMTY2MzYxNjYzNTEzNDg0NSJ9XSwibWV0YWRhdGEiOnsiYnVpbGRGaW5pc2hlZE9uIjoiMjAyMi0wOS0xOVQxOTo0NDozNC4xNTI0MjFaIiwiYnVpbGRJbnZvY2F0aW9uSWQiOiIzOTM3OTRkYy04MmVjLTQ5NWItOGY4NC02NTlkZWM4N2QzODEiLCJidWlsZFN0YXJ0ZWRPbiI6IjIwMjItMDktMTlUMTk6NDM6NTYuMDc2MTE0NjUxWiJ9LCJyZWNpcGUiOnsiYXJndW1lbnRzIjp7IkB0eXBlIjoidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuZGV2dG9vbHMuY2xvdWRidWlsZC52MS5CdWlsZCIsImlkIjoiMzkzNzk0ZGMtODJlYy00OTViLThmODQtNjU5ZGVjODdkMzgxIiwibmFtZSI6InByb2plY3RzLzgxOTcyMDk1MzgxMi9sb2NhdGlvbnMvdXMtd2VzdDIvYnVpbGRzLzM5Mzc5NGRjLTgyZWMtNDk1Yi04Zjg0LTY1OWRlYzg3ZDM4MSIsIm9wdGlvbnMiOnsibG9nZ2luZyI6IkNMT1VEX0xPR0dJTkdfT05MWSIsInBvb2wiOnt9LCJyZXF1ZXN0ZWRWZXJpZnlPcHRpb24iOiJWRVJJRklFRCIsInNvdXJjZVByb3ZlbmFuY2VIYXNoIjpbIlNIQTI1NiJdfSwic291cmNlUHJvdmVuYW5jZSI6eyJmaWxlSGFzaGVzIjp7ImdzOi8vc2xzYS10b29saW5nX2Nsb3VkYnVpbGQvc291cmNlLzE2NjM2MTY2MzIuMDc4MzUzLWZjN2RiMTQzZGNjNjRiNWY5ZmU3MWQwNDk3MTI1Y2ExLnRneiMxNjYzNjE2NjM1MTM0ODQ1Ijp7ImZpbGVIYXNoIjpbeyJ0eXBlIjoiU0hBMjU2IiwidmFsdWUiOiJuRTUrS0w3MXlmK3I2aGNLUUwrMjRvYmhjQkFNRHJBdGZnYkgzWXdpT09RPSJ9LHsidHlwZSI6Ik1ENSIsInZhbHVlIjoiZlVSbnRiZEpXY09jQ0xQSVZGLzZ3UT09In1dfX0sInJlc29sdmVkU3RvcmFnZVNvdXJjZSI6eyJidWNrZXQiOiJzbHNhLXRvb2xpbmdfY2xvdWRidWlsZCIsImdlbmVyYXRpb24iOiIxNjYzNjE2NjM1MTM0ODQ1Iiwib2JqZWN0Ijoic291cmNlLzE2NjM2MTY2MzIuMDc4MzUzLWZjN2RiMTQzZGNjNjRiNWY5ZmU3MWQwNDk3MTI1Y2ExLnRneiJ9fSwic3RlcHMiOlt7ImFyZ3MiOlsiYnVpbGQiLCItdCIsInVzLXdlc3QyLWRvY2tlci5wa2cuZGV2L3Nsc2EtdG9vbGluZy9leGFtcGxlLXBhY2thZ2UtcmVwby9lMmUtZ2NiLXdvcmtmbG93X2Rpc3BhdGNoLW1haW4tY2xvdWRidWlsZC1zbHNhMyIsIi4iXSwibmFtZSI6Imdjci5pby9jbG91ZC1idWlsZGVycy9kb2NrZXIiLCJwdWxsVGltaW5nIjp7ImVuZFRpbWUiOiIyMDIyLTA5LTE5VDE5OjQ0OjAyLjMwMDQ3MDQ1OVoiLCJzdGFydFRpbWUiOiIyMDIyLTA5LTE5VDE5OjQ0OjAyLjI5NjU1ODQzOVoifSwic3RhdHVzIjoiU1VDQ0VTUyIsInRpbWluZyI6eyJlbmRUaW1lIjoiMjAyMi0wOS0xOVQxOTo0NDozMi4zMjk2OTY1MjVaIiwic3RhcnRUaW1lIjoiMjAyMi0wOS0xOVQxOTo0NDowMi4yOTY1NTg0MzlaIn19XSwic3Vic3RpdHV0aW9ucyI6eyJfSU1BR0VfTkFNRSI6InNsc2EtdG9vbGluZy9leGFtcGxlLXBhY2thZ2UtcmVwby9lMmUtZ2NiLXdvcmtmbG93X2Rpc3BhdGNoLW1haW4tY2xvdWRidWlsZC1zbHNhMyJ9fSwiZGVmaW5lZEluTWF0ZXJpYWwiOiItMSIsInR5cGUiOiJodHRwczovL2Nsb3VkYnVpbGQuZ29vZ2xlYXBpcy5jb20vQ2xvdWRCdWlsZFN0ZXBzQHYwLjEifX0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjAuMSIsInNsc2FQcm92ZW5hbmNlIjp7ImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL2Nsb3VkYnVpbGQuZ29vZ2xlYXBpcy5jb20vR29vZ2xlSG9zdGVkV29ya2VyQHYwLjMifSwibWF0ZXJpYWxzIjpbeyJkaWdlc3QiOnsibWQ1IjoiN2Q0NDY3YjViNzQ5NTljMzljMDhiM2M4NTQ1ZmZhYzEiLCJzaGEyNTYiOiI5YzRlN2UyOGJlZjVjOWZmYWJlYTE3MGE0MGJmYjZlMjg2ZTE3MDEwMGMwZWIwMmQ3ZTA2YzdkZDhjMjIzOGU0In0sInVyaSI6ImdzOi8vc2xzYS10b29saW5nX2Nsb3VkYnVpbGQvc291cmNlLzE2NjM2MTY2MzIuMDc4MzUzLWZjN2RiMTQzZGNjNjRiNWY5ZmU3MWQwNDk3MTI1Y2ExLnRneiMxNjYzNjE2NjM1MTM0ODQ1In1dLCJtZXRhZGF0YSI6eyJidWlsZEZpbmlzaGVkT24iOiIyMDIyLTA5LTE5VDE5OjQ0OjM0LjE1MjQyMVoiLCJidWlsZEludm9jYXRpb25JZCI6IjM5Mzc5NGRjLTgyZWMtNDk1Yi04Zjg0LTY1OWRlYzg3ZDM4MSIsImJ1aWxkU3RhcnRlZE9uIjoiMjAyMi0wOS0xOVQxOTo0Mzo1Ni4wNzYxMTQ2NTFaIn0sInJlY2lwZSI6eyJhcmd1bWVudHMiOnsiQHR5cGUiOiJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5kZXZ0b29scy5jbG91ZGJ1aWxkLnYxLkJ1aWxkIiwiaWQiOiIzOTM3OTRkYy04MmVjLTQ5NWItOGY4NC02NTlkZWM4N2QzODEiLCJuYW1lIjoicHJvamVjdHMvODE5NzIwOTUzODEyL2xvY2F0aW9ucy91cy13ZXN0Mi9idWlsZHMvMzkzNzk0ZGMtODJlYy00OTViLThmODQtNjU5ZGVjODdkMzgxIiwib3B0aW9ucyI6eyJsb2dnaW5nIjoiQ0xPVURfTE9HR0lOR19PTkxZIiwicG9vbCI6e30sInJlcXVlc3RlZFZlcmlmeU9wdGlvbiI6IlZFUklGSUVEIiwic291cmNlUHJvdmVuYW5jZUhhc2giOlsiU0hBMjU2Il19LCJzb3VyY2VQcm92ZW5hbmNlIjp7ImZpbGVIYXNoZXMiOnsiZ3M6Ly9zbHNhLXRvb2xpbmdfY2xvdWRidWlsZC9zb3VyY2UvMTY2MzYxNjYzMi4wNzgzNTMtZmM3ZGIxNDNkY2M2NGI1ZjlmZTcxZDA0OTcxMjVjYTEudGd6IzE2NjM2MTY2MzUxMzQ4NDUiOnsiZmlsZUhhc2giOlt7InR5cGUiOiJTSEEyNTYiLCJ2YWx1ZSI6Im5FNStLTDcxeWYrcjZoY0tRTCsyNG9iaGNCQU1EckF0ZmdiSDNZd2lPT1E9In0seyJ0eXBlIjoiTUQ1IiwidmFsdWUiOiJmVVJudGJkSldjT2NDTFBJVkYvNndRPT0ifV19fSwicmVzb2x2ZWRTdG9yYWdlU291cmNlIjp7ImJ1Y2tldCI6InNsc2EtdG9vbGluZ19jbG91ZGJ1aWxkIiwiZ2VuZXJhdGlvbiI6IjE2NjM2MTY2MzUxMzQ4NDUiLCJvYmplY3QiOiJzb3VyY2UvMTY2MzYxNjYzMi4wNzgzNTMtZmM3ZGIxNDNkY2M2NGI1ZjlmZTcxZDA0OTcxMjVjYTEudGd6In19LCJzdGVwcyI6W3siYXJncyI6WyJidWlsZCIsIi10IiwidXMtd2VzdDItZG9ja2VyLnBrZy5kZXYvc2xzYS10b29saW5nL2V4YW1wbGUtcGFja2FnZS1yZXBvL2UyZS1nY2Itd29ya2Zsb3dfZGlzcGF0Y2gtbWFpbi1jbG91ZGJ1aWxkLXNsc2EzIiwiLiJdLCJuYW1lIjoiZ2NyLmlvL2Nsb3VkLWJ1aWxkZXJzL2RvY2tlciIsInB1bGxUaW1pbmciOnsiZW5kVGltZSI6IjIwMjItMDktMTlUMTk6NDQ6MDIuMzAwNDcwNDU5WiIsInN0YXJ0VGltZSI6IjIwMjItMDktMTlUMTk6NDQ6MDIuMjk2NTU4NDM5WiJ9LCJzdGF0dXMiOiJTVUNDRVNTIiwidGltaW5nIjp7ImVuZFRpbWUiOiIyMDIyLTA5LTE5VDE5OjQ0OjMyLjMyOTY5NjUyNVoiLCJzdGFydFRpbWUiOiIyMDIyLTA5LTE5VDE5OjQ0OjAyLjI5NjU1ODQzOVoifX1dLCJzdWJzdGl0dXRpb25zIjp7Il9JTUFHRV9OQU1FIjoic2xzYS10b29saW5nL2V4YW1wbGUtcGFja2FnZS1yZXBvL2UyZS1nY2Itd29ya2Zsb3dfZGlzcGF0Y2gtbWFpbi1jbG91ZGJ1aWxkLXNsc2EzIn19LCJkZWZpbmVkSW5NYXRlcmlhbCI6Ii0xIiwidHlwZSI6Imh0dHBzOi8vY2xvdWRidWlsZC5nb29nbGVhcGlzLmNvbS9DbG91ZEJ1aWxkU3RlcHNAdjAuMSJ9fSwic3ViamVjdCI6W3siZGlnZXN0Ijp7InNoYTI1NiI6IjcxZWZjYmIzZjAzZjU5MTRkY2RlODdlMzhkMzgxM2Y2Mzk4MmI0NzVmNzY4ODdiYWJmMjVmNzZmZmY3NjBkM2MifSwibmFtZSI6Imh0dHBzOi8vdXMtd2VzdDItZG9ja2VyLnBrZy5kZXYvc2xzYS10b29saW5nL2V4YW1wbGUtcGFja2FnZS1yZXBvL2UyZS1nY2Itd29ya2Zsb3dfZGlzcGF0Y2gtbWFpbi1jbG91ZGJ1aWxkLXNsc2EzIn0seyJkaWdlc3QiOnsic2hhMjU2IjoiNzFlZmNiYjNmMDNmNTkxNGRjZGU4N2UzOGQzODEzZjYzOTgyYjQ3NWY3Njg4N2JhYmYyNWY3NmZmZjc2MGQzYyJ9LCJuYW1lIjoiaHR0cHM6Ly91cy13ZXN0Mi1kb2NrZXIucGtnLmRldi9zbHNhLXRvb2xpbmcvZXhhbXBsZS1wYWNrYWdlLXJlcG8vZTJlLWdjYi13b3JrZmxvd19kaXNwYXRjaC1tYWluLWNsb3VkYnVpbGQtc2xzYTM6bGF0ZXN0In1dfQ==", | ||
"payloadType": "application/vnd.in-toto+json", | ||
"signatures": [ | ||
{ | ||
"keyid": "projects/verified-builder/locations/us-west2/keyRings/attestor/cryptoKeys/builtByGCB/cryptoKeyVersions/1", | ||
"sig": "MEYCIQDRCd9adBP6_ze18NxtlZ8yVqcETUGdpYQ8C1MKFEYNMAIhAMMFKpKDVbbUpxIcf_5vHUnuXEOMSybG9IS_43Glp6zH" | ||
} | ||
] | ||
}, | ||
"kind": "BUILD", | ||
"name": "projects/slsa-tooling/occurrences/970d284c-ab7a-4121-9a0e-52812595263b", | ||
"noteName": "projects/verified-builder/notes/intoto_393794dc-82ec-495b-8f84-659dec87d381", | ||
"resourceUri": "https://us-west2-docker.pkg.dev/slsa-tooling/example-package-repo/e2e-gcb-workflow_dispatch-main-cloudbuild-slsa3@sha256:71efcbb3f03f5914dcde87e38d3813f63982b475f76887babf25f76fff760d3c", | ||
"updateTime": "2022-09-19T19:44:35.879537Z" | ||
} | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"schemaVersion": 2, | ||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json", | ||
"config": { | ||
"mediaType": "application/vnd.docker.container.image.v1+json", | ||
"size": 1748, | ||
"digest": "sha256:40391da7d19c1900fc744f227bdcb229f9a14ce6390c1e76337361e2b7c7cc60" | ||
}, | ||
"layers": [ | ||
{ | ||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
"size": 804101, | ||
"digest": "sha256:b9f88661235d25835ef747dab426861d51c4e9923b92623d422d7ac58eb123e9" | ||
}, | ||
{ | ||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", | ||
"size": 608694, | ||
"digest": "sha256:753a0c6a100dcd1b6ad628933020e3a9d388d7c05aa3f2dd8795196dd40f2a2e" | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package gcb | ||
|
||
// Copy of github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1 | ||
// This holds an internal copy of in-toto-golang's structs for | ||
// SLSA predicates to handle GCB's incompatibility with the | ||
// published specification. Specifically, GCB provenance currently | ||
// produces a string for ProvenancePredicate.Recipe.DefinedInMaterial | ||
// rather than the compliant signed integer. | ||
|
||
import "time" | ||
|
||
const ( | ||
// PredicateSLSAProvenance represents a build provenance for an artifact. | ||
PredicateSLSAProvenance = "https://slsa.dev/provenance/v0.1" | ||
) | ||
|
||
// ProvenancePredicate is the provenance predicate definition. | ||
type ProvenancePredicate struct { | ||
Builder ProvenanceBuilder `json:"builder"` | ||
Recipe ProvenanceRecipe `json:"recipe"` | ||
Metadata *ProvenanceMetadata `json:"metadata,omitempty"` | ||
Materials []ProvenanceMaterial `json:"materials,omitempty"` | ||
} | ||
|
||
// ProvenanceBuilder idenfifies the entity that executed the build steps. | ||
type ProvenanceBuilder struct { | ||
ID string `json:"id"` | ||
} | ||
|
||
// ProvenanceRecipe describes the actions performed by the builder. | ||
type ProvenanceRecipe struct { | ||
Type string `json:"type"` | ||
// DefinedInMaterial can be sent as the null pointer to indicate that | ||
// the value is not present. | ||
// DefinedInMaterial *int `json:"definedInMaterial,omitempty"` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: add a short local comment as to why this is commented out. Maybe point to comment at top of file. |
||
EntryPoint string `json:"entryPoint"` | ||
Arguments interface{} `json:"arguments,omitempty"` | ||
Environment interface{} `json:"environment,omitempty"` | ||
} | ||
|
||
// ProvenanceMetadata contains metadata for the built artifact. | ||
type ProvenanceMetadata struct { | ||
// Use pointer to make sure that the abscense of a time is not | ||
// encoded as the Epoch time. | ||
BuildStartedOn *time.Time `json:"buildStartedOn,omitempty"` | ||
BuildFinishedOn *time.Time `json:"buildFinishedOn,omitempty"` | ||
Completeness ProvenanceComplete `json:"completeness"` | ||
Reproducible bool `json:"reproducible"` | ||
} | ||
|
||
// ProvenanceMaterial defines the materials used to build an artifact. | ||
type ProvenanceMaterial struct { | ||
URI string `json:"uri"` | ||
Digest DigestSet `json:"digest,omitempty"` | ||
} | ||
|
||
// ProvenanceComplete indicates wheter the claims in build/recipe are complete. | ||
// For in depth information refer to the specifictaion: | ||
// https://github.com/in-toto/attestation/blob/v0.1.0/spec/predicates/provenance.md | ||
type ProvenanceComplete struct { | ||
Arguments bool `json:"arguments"` | ||
Environment bool `json:"environment"` | ||
Materials bool `json:"materials"` | ||
} | ||
|
||
// DigestSet contains a set of digests. It is represented as a map from | ||
// algorithm name to lowercase hex-encoded value. | ||
type DigestSet map[string]string |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -13,7 +13,6 @@ import ( | |||||
"github.com/google/go-cmp/cmp" | ||||||
|
||||||
intoto "github.com/in-toto/in-toto-golang/in_toto" | ||||||
slsa01 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.1" | ||||||
dsselib "github.com/secure-systems-lab/go-securesystemslib/dsse" | ||||||
|
||||||
serrors "github.com/slsa-framework/slsa-verifier/errors" | ||||||
|
@@ -29,7 +28,7 @@ var GCBBuilderIDs = []string{ | |||||
|
||||||
type v01IntotoStatement struct { | ||||||
intoto.StatementHeader | ||||||
Predicate slsa01.ProvenancePredicate `json:"predicate"` | ||||||
Predicate ProvenancePredicate `json:"predicate"` | ||||||
} | ||||||
|
||||||
// The GCB provenance contains a human-readable version of the intoto | ||||||
|
@@ -38,7 +37,7 @@ type v01IntotoStatement struct { | |||||
// by the GCB team. | ||||||
type v01GCBIntotoStatement struct { | ||||||
intoto.StatementHeader | ||||||
SlsaProvenance slsa01.ProvenancePredicate `json:"slsaProvenance"` | ||||||
SlsaProvenance ProvenancePredicate `json:"slsaProvenance"` | ||||||
} | ||||||
|
||||||
type provenance struct { | ||||||
|
@@ -72,7 +71,7 @@ func ProvenanceFromBytes(payload []byte) (*Provenance, error) { | |||||
var prov gloudProvenance | ||||||
err := json.Unmarshal(payload, &prov) | ||||||
if err != nil { | ||||||
return nil, fmt.Errorf("json.Unmarshal: %w", err) | ||||||
return nil, fmt.Errorf("json.Unmarshal gcloud provenance: %w", err) | ||||||
} | ||||||
|
||||||
return &Provenance{ | ||||||
|
@@ -205,9 +204,9 @@ func (self *Provenance) VerifyIntotoHeaders() error { | |||||
} | ||||||
|
||||||
// https://slsa.dev/provenance/v0.1 | ||||||
if statement.StatementHeader.PredicateType != slsa01.PredicateSLSAProvenance { | ||||||
if statement.StatementHeader.PredicateType != PredicateSLSAProvenance { | ||||||
return fmt.Errorf("%w: expected statement predicate type '%s', got '%s'", | ||||||
serrors.ErrorInvalidDssePayload, slsa01.PredicateSLSAProvenance, statement.StatementHeader.PredicateType) | ||||||
serrors.ErrorInvalidDssePayload, PredicateSLSAProvenance, statement.StatementHeader.PredicateType) | ||||||
} | ||||||
|
||||||
return nil | ||||||
|
@@ -357,7 +356,9 @@ func (self *Provenance) VerifySourceURI(expectedSourceURI string, builderID util | |||||
return fmt.Errorf("%w: no materials", serrors.ErrorInvalidDssePayload) | ||||||
} | ||||||
uri := materials[0].URI | ||||||
if !strings.HasPrefix(expectedSourceURI, "https://") { | ||||||
|
||||||
// It is possible that GCS builds at level 2 use GCS sources, prefixed by gs://. | ||||||
if strings.HasPrefix(uri, "https://") && !strings.HasPrefix(expectedSourceURI, "https://") { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: You might also leave a note as to why this is necessary in the first place. It's not necessarily obvious why "https://" might need to be prefixed at the beginning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, consider checking for any URI scheme rather than "https://" specifically. So you don't end up with strange URIs like "https://http://example.com/..." if the user enters "--source http://example.com"
Suggested change
|
||||||
expectedSourceURI = "https://" + expectedSourceURI | ||||||
} | ||||||
|
||||||
|
@@ -367,14 +368,17 @@ func (self *Provenance) VerifySourceURI(expectedSourceURI string, builderID util | |||||
case "v0.2": | ||||||
// In v0.2, it uses format | ||||||
// `https://github.com/laurentsimon/gcb-tests/commit/01ce393d04eb6df2a7b2b3e95d4126e687afb7ae`. | ||||||
if !strings.HasPrefix(uri, expectedSourceURI+"/commit/") { | ||||||
if !strings.HasPrefix(uri, expectedSourceURI+"/commit/") && | ||||||
!strings.HasPrefix(uri, expectedSourceURI+"#") { | ||||||
return fmt.Errorf("%w: expected '%s', got '%s'", | ||||||
serrors.ErrorMismatchSource, expectedSourceURI, uri) | ||||||
} | ||||||
// In v0.3, it uses the standard intoto and has the commit sha in its own | ||||||
// `digest.sha1` field. | ||||||
case "v0.3": | ||||||
if uri != expectedSourceURI { | ||||||
// The latter case is a versioned GCS source. | ||||||
if uri != expectedSourceURI && | ||||||
!strings.HasPrefix(uri, expectedSourceURI+"#") { | ||||||
return fmt.Errorf("%w: expected '%s', got '%s'", | ||||||
serrors.ErrorMismatchSource, expectedSourceURI, uri) | ||||||
} | ||||||
|
@@ -418,7 +422,7 @@ func decodeSignature(s string) ([]byte, []error) { | |||||
} | ||||||
|
||||||
// verifySignatures iterates over all the signatures in the DSSE and verifies them. | ||||||
// It succeeds if one of them can ne verified. | ||||||
// It succeeds if one of them can be verified. | ||||||
func (self *Provenance) verifySignatures(prov *provenance) error { | ||||||
// Verify the envelope type. It should be an intoto type. | ||||||
if prov.Envelope.PayloadType != intoto.PayloadType { | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add a "NOTE: " prefix to the comment.