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

spdx: initial sbom framwork + spdx encoder #1468

Merged
merged 2 commits into from
Feb 7, 2025

Conversation

BradLugo
Copy link
Contributor

@BradLugo BradLugo commented Jan 14, 2025

Description

These changes introduce the initial SBOM framework into claircore, generating an SPDX 2.3 JSON document from a claircore.IndexReport.

Design

Design doc: https://docs.google.com/document/d/1dRKMWjmkpYO5oN_Y-S_0R2vwyvcdXHCNejM3C-F2DIc/edit?tab=t.0

@BradLugo BradLugo changed the title spdx: implement initial sbom framwork + spdx encoder spdx: initial sbom framwork + spdx encoder Jan 14, 2025
@hdonnay
Copy link
Member

hdonnay commented Jan 14, 2025

Should be moved out of the pkg directory.

Rambling on why

The pkg in a package name is just line noise: we all know it's a go package. Marking something for "external" use is done in the opposite direction: internal is actually enforced by the compiler. If the API for use is squishier than that, it's on humans to observe it anyway.

@BradLugo BradLugo force-pushed the add-spdx-converter branch 3 times, most recently from 11f31ac to be73a74 Compare January 14, 2025 19:28
@BradLugo
Copy link
Contributor Author

If anyone has a suggestion on testing something that bakes in time.Now() the output, please let me know. Example of the problem in my current unit test:

            - 		"created":  string("2025-01-14T21:48:35Z"),
            + 		"created":  string("2025-01-14T09:51:40Z"),

@hdonnay
Copy link
Member

hdonnay commented Jan 15, 2025

If anyone has a suggestion on testing something that bakes in time.Now() the output, please let me know.

You can put together a cmp.Option for cmp that turns these back into time.Time and allows some delta, or just ignores them.

@BradLugo
Copy link
Contributor Author

I'll start using fixup commits from this point on to help reviewers until I get approvals, then I'll rebase all the fixup commits.

@BradLugo BradLugo marked this pull request as ready for review January 16, 2025 22:49
@BradLugo BradLugo requested a review from a team as a code owner January 16, 2025 22:49
@BradLugo BradLugo requested review from hdonnay, dcaravel and crozzy and removed request for a team January 16, 2025 22:49
dcaravel
dcaravel previously approved these changes Jan 16, 2025
Copy link

@dcaravel dcaravel left a comment

Choose a reason for hiding this comment

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

LGTM

@BradLugo BradLugo marked this pull request as draft January 21, 2025 19:09
@BradLugo BradLugo force-pushed the add-spdx-converter branch 3 times, most recently from 29c8071 to f8bb863 Compare January 23, 2025 21:27
@BradLugo BradLugo marked this pull request as ready for review January 23, 2025 21:27
@BradLugo BradLugo requested review from RTann and hdonnay January 28, 2025 21:40
sbom/sbom.go Outdated
"io"
)

// Encoder is an interface to convert a claircore.IndexReport into an io.Reader
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Encoder is an interface to convert a claircore.IndexReport into an io.Reader
// Encoder is an interface to write a Software Bill of Materials (SBOM) representation of a [claircore.IndexReport] to an output stream.

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget about this one ^ :)

dcaravel
dcaravel previously approved these changes Feb 4, 2025
Copy link

@dcaravel dcaravel left a comment

Choose a reason for hiding this comment

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

LGTM, tested on a few images (namely nginx:1.24.0 and quay.io/rhacs-eng/main:4.6.2) comparing the v4.IndexReport from stackrox to the produced SBOMs, and the output was as expected / explainable.

@BradLugo BradLugo requested a review from RTann February 4, 2025 23:49
RTann
RTann previously approved these changes Feb 5, 2025
Copy link
Contributor

@RTann RTann left a comment

Choose a reason for hiding this comment

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

Approving to ensure this can move along. No true blockers from me, though perhaps the import ordering may be one? I also ask for consideration of the strconv.Atoi comments (do we need these calls?) and the comment about breaking out of the loop

sbom/sbom.go Outdated
"io"
)

// Encoder is an interface to convert a claircore.IndexReport into an io.Reader
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget about this one ^ :)


// Record Distributions for this package.
if r.Distribution != nil {
rDistId, err := strconv.Atoi(r.Distribution.ID)
Copy link
Contributor

Choose a reason for hiding this comment

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

just realized, do we use the IDs for anything other than converting them into ints? If not, then can we just keep them as strings and make the map key string instead of int? Same idea for the slices. Not sure if we have to keep doing this conversion

Copy link
Contributor Author

@BradLugo BradLugo Feb 5, 2025

Choose a reason for hiding this comment

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

We convert them to ints to sort them. The return from IndexReport.IndexRecords() is non-deterministic because it iterates over IndexReport.Packages, which is a map. In order to have a deterministic output, both to test against and for users to be able to run a diff between reports, we need to have some sort of ordering structuring. This is what I came up with, but I'm happy to revisit how we do it (perhaps in a follow up PR 🙂)

Some of this context is captured in a comment here: Some context here: https://github.com/quay/claircore/pull/1468/files#diff-9730b2b5baa2c38c549f0b3c1077fddf654896f316b79c2c8f3f77d5fb7ccd1cR273-R276

Copy link
Contributor

Choose a reason for hiding this comment

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

so if we just cared about sorting for determinism, then I think we can keep it as strings. If we also want to have the IDs in increasing order, then converting to int makes sense. Feel free to change in a followup if you decide to change it

return nil, err
}

srcPkg, ok := pkgs[rSrcPkgId]
Copy link
Contributor

Choose a reason for hiding this comment

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

won't block the PR over this, but wondering why we add the source here instead of just waiting until we see it? Do we not always see it? In the case we add it here and then see it again later, do we risk potentially duplicating data?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@crozzy will likely be able to explain this better, but my understanding is that source packages aren't always recorded as root-level packages. In fact, I think rhcc source packages are the only ones that are also recorded as root-level packages.
For clarity, when I say "root-level packages" here, I'm referring to IndexReport.Packages as opposed to IndexReport.Packages.Source.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think it depends on what the Scan() method kicks back. If the indexer reports something as a source I think we should add it as a source package in the SBOM.

@RTann
Copy link
Contributor

RTann commented Feb 5, 2025

don't forget to sign your commits :) Also looks like there are still a bunch. Seems like you are on top of that, though, with the fixup! prefixes

@BradLugo
Copy link
Contributor Author

BradLugo commented Feb 5, 2025

don't forget to sign your commits :) Also looks like there are still a bunch. Seems like you are on top of that, though, with the fixup! prefixes

Yup, thank you! It's a new thing I'm trying. The fixup commits have a message body detailing more about the commit and giving reviewers an easier history to work with. Then, when I get approvals from all participating reviewers, I rebase --autosquash at the end to clean up the history and pass CI. Not sure if this is helpful or not. Would love yall's feedback on it!

@BradLugo BradLugo dismissed stale reviews from RTann and dcaravel via 9fcd250 February 5, 2025 21:16
@BradLugo BradLugo requested a review from RTann February 6, 2025 18:05
Copy link
Contributor

@crozzy crozzy left a comment

Choose a reason for hiding this comment

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

LGTM, nice work

Adding a function to be able to convert index reports
into SPDX documents and SPDX documents into index reports.

Signed-off-by: crozzy <[email protected]>
Signed-off-by: Brad Lugo <[email protected]>
@BradLugo
Copy link
Contributor Author

BradLugo commented Feb 6, 2025

autosquashing commits; no changes.

@BradLugo BradLugo dismissed hdonnay’s stale review February 7, 2025 18:29

Unavailable for follow up review

@BradLugo BradLugo merged commit 79e0035 into quay:main Feb 7, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants