Skip to content
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

Merged
merged 8 commits into from
Jul 5, 2022

Conversation

mattmoor
Copy link
Collaborator

@mattmoor mattmoor commented Jul 1, 2022

Tweaking some things to prepare for the meat of: #655

@codecov-commenter
Copy link

codecov-commenter commented Jul 1, 2022

Codecov Report

Merging #743 (5fd12eb) into main (d17aca8) will decrease coverage by 0.25%.
The diff coverage is 27.53%.

@@            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     
Impacted Files Coverage Δ
pkg/commands/deps.go 13.08% <0.00%> (ø)
pkg/build/gobuild.go 60.10% <30.15%> (-1.35%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d17aca8...5fd12eb. Read the comment docs.

imjasonh
imjasonh previously approved these changes Jul 1, 2022
Copy link
Member

@imjasonh imjasonh left a 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

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 1, 2022

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.

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 1, 2022

Oh fun, I think there are some Go 1.18 problems :-/

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 1, 2022

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"
    }
  ]
}

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 1, 2022

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"
    }
  ]
}

@puerco
Copy link
Contributor

puerco commented Jul 1, 2022

OK, its missing the external document refs, you need to merge this patch first:

#741

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 1, 2022

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"
    }
  ]

@mattmoor mattmoor force-pushed the sbom-multi-arch-plumbing branch 3 times, most recently from fc472b5 to 64a1748 Compare July 1, 2022 23:52
@mattmoor mattmoor changed the title [WIP] Start to do some plumbing for ko multi-arch SBOMs Start emitting multi-arch SBOMs for SPDX with ko Jul 1, 2022
@puerco
Copy link
Contributor

puerco commented Jul 2, 2022

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 spdxDocument field has the purl in it. This prevents the validator from pulling the doc to complete the sbom data :(

@puerco
Copy link
Contributor

puerco commented Jul 2, 2022

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.

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

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 ko deps.

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

oh it does 😈

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

From our discussion today and what I was discussing with @jonjohnsonjr I think I'm leaning more towards defining them this way

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.

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

Ok I switched it to using Packages, lmk if there’s a better ref type

@mattmoor mattmoor force-pushed the sbom-multi-arch-plumbing branch 2 times, most recently from 1df8e75 to d19552e Compare July 2, 2022 16:11
@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

Ok, so I realized my first crack at packages lost the platform information, so I brought it back in the version field of the package: https://github.com/google/ko/runs/7163036130?check_suite_focus=true#step:7:130

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

Here's a screenshot highlighting the digest of the image
image

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 2, 2022

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.

@puerco
Copy link
Contributor

puerco commented Jul 2, 2022

The platform info can be encoded in the purl. But I'm looking and for some reason, it only has an arch field!?!?!
https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#oci

We could propose another os field or simply cram the whole linux/arm/v8 field in there. I'd like to have it there as well because the purl is that key to link elements spread across sboms in spdx and cyclonedx.

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 3, 2022

Sure, just lmk what you'd like to see here and we can adjust!

@mattmoor
Copy link
Collaborator Author

mattmoor commented Jul 4, 2022

Added the architecture to the pURLs as well.

@puerco
Copy link
Contributor

puerco commented Jul 4, 2022

I've opened package-url/purl-spec#179 to propose adding a os qualifier to the purl spec. Its the missing bit to complete the platform information.

@@ -32,3 +33,29 @@ func ParseBuildInfo(data string) (*BuildInfo, error) {
bi := BuildInfo(*dbi)
return &bi, nil
}

func modulePackageName(mod *debug.Module) string {
Copy link
Member

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?

Copy link
Collaborator Author

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 :-/

Copy link
Member

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.

Copy link
Collaborator Author

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) {
Copy link
Member

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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. 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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
	}

Copy link
Collaborator Author

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.

pkg/build/gobuild_test.go Outdated Show resolved Hide resolved
@@ -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"
Copy link
Member

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?

Copy link
Collaborator Author

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

@mattmoor mattmoor force-pushed the sbom-multi-arch-plumbing branch 2 times, most recently from 5fd12eb to db6125e Compare July 5, 2022 18:50
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
@mattmoor mattmoor merged commit 2299765 into ko-build:main Jul 5, 2022
@mattmoor mattmoor deleted the sbom-multi-arch-plumbing branch July 5, 2022 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants