-
Notifications
You must be signed in to change notification settings - Fork 399
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
Start emitting multi-arch SBOMs for SPDX
with ko
#743
Conversation
Codecov Report
@@ Coverage Diff @@
## main #743 +/- ##
==========================================
- Coverage 51.38% 51.13% -0.26%
==========================================
Files 44 44
Lines 3295 3317 +22
==========================================
+ Hits 1693 1696 +3
- Misses 1390 1408 +18
- Partials 212 213 +1
Continue to review full report at Codecov.
|
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.
Looks good so far
cbb70cc
to
90b3ac6
Compare
Ok, I pushed what I have so far. I haven't tried things yet to make sure they work, but I'll do that now. |
90b3ac6
to
6392dcb
Compare
Oh fun, I think there are some Go 1.18 problems :-/ |
Here's an example of an image SBOM with the latest refactoring: {
"SPDXID": "SPDXRef-DOCUMENT",
"name": "sbom-sha256:8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"spdxVersion": "SPDX-2.2",
"creationInfo": {
"created": "2022-07-01T02:27:39Z",
"creators": [
"Tool: ko (devel)"
]
},
"dataLicense": "CC0-1.0",
"documentNamespace": "http://spdx.org/spdxdocs/kosha256:8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"documentDescribes": [
"SPDXRef-Package-sha256-8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85"
],
"packages": [
{
"SPDXID": "SPDXRef-Package-sha256-8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"name": "sha256:8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"versionInfo": "",
"filesAnalyzed": false,
"licenseDeclared": "NOASSERTION",
"licenseConcluded": "NOASSERTION",
"downloadLocation": "",
"copyrightText": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:oci/image@sha256:8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"referenceType": "purl"
}
]
},
{
"SPDXID": "SPDXRef-Package-github.com.google.ko-(devel)",
"name": "github.com/google/ko",
"versionInfo": "",
"filesAnalyzed": false,
"licenseDeclared": "NOASSERTION",
"licenseConcluded": "NOASSERTION",
"downloadLocation": "https://github.com/google/ko",
"copyrightText": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:golang/github.com/google/ko@(devel)?type=module",
"referenceType": "purl"
}
]
},
{
"SPDXID": "SPDXRef-Package-github.com.google.go-containerregistry-v0.10.0",
"name": "github.com/google/go-containerregistry",
"versionInfo": "v0.10.0",
"filesAnalyzed": false,
"licenseDeclared": "NOASSERTION",
"licenseConcluded": "NOASSERTION",
"downloadLocation": "https://proxy.golang.org/github.com/google/go-containerregistry/@v/v0.10.0.zip",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "a9dfdfbf69d06a319925e9da35c75a82197048f8d0d0da6137d87302baf65968"
}
],
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:golang/github.com/google/go-containerregistry@v0.10.0?type=module",
"referenceType": "purl"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relationshipType": "DESCRIBES",
"relatedSpdxElement": "SPDXRef-Package-sha256-8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85"
},
{
"spdxElementId": "SPDXRef-Package-sha256-8955c18a6362f783536ec377fa0508646102895d89c08ee9d2f186c26e949d85",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-Package-github.com.google.ko-(devel)"
},
{
"spdxElementId": "SPDXRef-Package-github.com.google.ko-(devel)",
"relationshipType": "DEPENDS_ON",
"relatedSpdxElement": "SPDXRef-Package-github.com.google.go-containerregistry-v0.10.0"
}
]
} |
Here's an example of a multi-arch SBOM with this change: {
"SPDXID": "SPDXRef-DOCUMENT",
"name": "sbom-sha256:3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6",
"spdxVersion": "SPDX-2.2",
"creationInfo": {
"created": "2022-07-01T02:27:39Z",
"creators": [
"Tool: ko (devel)"
]
},
"dataLicense": "CC0-1.0",
"documentNamespace": "http://spdx.org/spdxdocs/kosha256:3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6",
"documentDescribes": [
"SPDXRef-Package-sha256-3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6"
],
"packages": [
{
"SPDXID": "SPDXRef-Package-sha256-3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6",
"name": "sha256:3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6",
"versionInfo": "",
"filesAnalyzed": false,
"licenseDeclared": "NOASSERTION",
"licenseConcluded": "NOASSERTION",
"downloadLocation": "",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6"
}
],
"externalRefs": [
{
"referenceCategory": "PACKAGE_MANAGER",
"referenceLocator": "pkg:oci/index@sha256:3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6",
"referenceType": "purl"
}
]
}
],
"relationships": [
{
"spdxElementId": "DocumentRef-amd64-image-sbom:SPDXRef-Package-sha256-f03f678ab9cefa198a2334c4ea1e4d740c9b9686643db54b0053a80e6d5041e9",
"relationshipType": "VARIANT_OF",
"relatedSpdxElement": "SPDXRef-Package-sha256-3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6"
},
{
"spdxElementId": "DocumentRef-arm64-image-sbom:SPDXRef-Package-sha256-569a8f91aed6b872d3e0c00f339b834ba671b2d04da80a14823f0db381890928",
"relationshipType": "VARIANT_OF",
"relatedSpdxElement": "SPDXRef-Package-sha256-3b72bb7f7ce12357a17d40f5198708823333790dd20d460613a9cdaabc97bdd6"
}
],
"externalDocumentRefs": [
{
"checksum": {
"algorithm": "SHA256",
"checksumValue": "c066df5c956def2fd36a340d4dcf67a51bbaf9e31201ae43088406b5ff99681a"
},
"externalDocumentId": "DocumentRef-amd64-image-sbom",
"spdxDocument": "pkg:oci/sbom@sha256:f03f678ab9cefa198a2334c4ea1e4d740c9b9686643db54b0053a80e6d5041e9"
},
{
"checksum": {
"algorithm": "SHA256",
"checksumValue": "03789b9d525f55260ea83ee2c173a54c40fda3f99110fd328d270e8a01e8b3e1"
},
"externalDocumentId": "DocumentRef-arm64-image-sbom",
"spdxDocument": "pkg:oci/sbom@sha256:569a8f91aed6b872d3e0c00f339b834ba671b2d04da80a14823f0db381890928"
}
]
}
|
OK, its missing the external document refs, you need to merge this patch first: |
It's in there, I didn't see your PR until just now! "externalDocumentRefs": [
{
"checksum": {
"algorithm": "SHA256",
"checksumValue": "c066df5c956def2fd36a340d4dcf67a51bbaf9e31201ae43088406b5ff99681a"
},
"externalDocumentId": "DocumentRef-amd64-image-sbom",
"spdxDocument": "pkg:oci/sbom@sha256:f03f678ab9cefa198a2334c4ea1e4d740c9b9686643db54b0053a80e6d5041e9"
},
{
"checksum": {
"algorithm": "SHA256",
"checksumValue": "03789b9d525f55260ea83ee2c173a54c40fda3f99110fd328d270e8a01e8b3e1"
},
"externalDocumentId": "DocumentRef-arm64-image-sbom",
"spdxDocument": "pkg:oci/sbom@sha256:569a8f91aed6b872d3e0c00f339b834ba671b2d04da80a14823f0db381890928"
}
] |
fc472b5
to
64a1748
Compare
SPDX
with ko
Ah sorry I ran it through the validator and it failed because it could not find the ref. I assumed it was not there. But I just saw that it's failing because the |
If we cannot reliably get a link to the SBOMs of the arch images, we can simply not reference the sboms, only reference the image as a package. We can think about it semantically as having two separate SBOM as opposed to this approach which is more akin to having one single SBOM broken into different files. From our discussion today and what I was discussing with @jonjohnsonjr I think I'm leaning more towards defining them this way. |
Let me try getting the validator running against index SBOMs here. I was being a bit lazy since it doesn't have a registry and just uses |
oh it does 😈 |
Just as packages? Ok, yeah I think that makes sense, and then we have the same problem for index -> image as we do for image -> other stuff's sboms. |
Ok I switched it to using Packages, lmk if there’s a better ref type |
1df8e75
to
d19552e
Compare
Ok, so I realized my first crack at packages lost the platform information, so I brought it back in the |
Another reason I just thought of for why we need a non-native SPDX way of linking to other SBOMs is that we might have a mix of SPDX (derived) and CycloneDX (base). That's not the case here, but clearly we need to handle that for base images. |
The platform info can be encoded in the purl. But I'm looking and for some reason, it only has an We could propose another |
Sure, just lmk what you'd like to see here and we can adjust! |
Added the architecture to the pURLs as well. |
I've opened package-url/purl-spec#179 to propose adding a |
@@ -32,3 +33,29 @@ func ParseBuildInfo(data string) (*BuildInfo, error) { | |||
bi := BuildInfo(*dbi) | |||
return &bi, nil | |||
} | |||
|
|||
func modulePackageName(mod *debug.Module) string { |
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.
Should these be in some shared file that both 1.18 and pre-1.18 code can reuse?
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.
I had to move them here because I wanted to use the *debug.Module
type :-/
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.
Boooo I guess what you had was fine. I hate this pre-1.18 and count down the days until we don't have to support it.
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.
Yeah, I had no idea until CI blew up on me, and I had to contort things to be able to leverage module types.
Will be good to kill this with 🔥
@@ -125,6 +170,151 @@ func GenerateSPDX(koVersion string, date time.Time, mod []byte, imgDigest v1.Has | |||
return buf.Bytes(), nil | |||
} | |||
|
|||
func extractDate(sii oci.SignedImageIndex) (*time.Time, error) { |
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.
Instead of extracting the date from the index we just built, can we pass the created time from gobuild.go into where we generate the SBOMs?
Or is this just to support ko deps
?
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.
That's what the image SBOM logic was doing, but extracting it from the image's config, which is frankly more accessible. I'll take a quick look at how hard it would be to pass it in without diverging the source of truth logic for setting these timestamps.
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.
Looks doable, lemme plumb that through instead. 👍
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.
Done!
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.
Ugh, so it looks like we only use g.creationTime
under certain circumstances, and we let the base image's creation time through otherwise, so for the index SBOM I think we'll end up needing some sort of extraction method to make that really work.
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.
e.g.
empty := v1.Time{}
if g.creationTime != empty {
cfg.Created = g.creationTime
}
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.
I'm reverting to what I had, as I think it's cleanest modulo a bigger refactor of this code.
@@ -30,6 +30,7 @@ import ( | |||
"github.com/google/go-containerregistry/pkg/v1/mutate" | |||
"github.com/google/go-containerregistry/pkg/v1/remote" | |||
"github.com/google/ko/internal/sbom" | |||
"github.com/sigstore/cosign/pkg/oci/signed" |
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.
Is this signed
package new? Why is there oci.SignedImage
and oci/signed.Image
?
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.
No, it is a convenient way of turning a v1.Image
into an oic.SignedImage
with empty signatures et al
5fd12eb
to
db6125e
Compare
This plumbs through support for building multi-arch SPDX SBOMs largely based on Puerco's outline, but with a few adaptations. I added a few minor refactorings to try to enable consistency across the Image/Index SBOMs. Related: ko-build#655
…refactor bomRef to match goRef change.
db6125e
to
13ee953
Compare
Tweaking some things to prepare for the meat of: #655