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

SBOM attestations generation #2983

Merged
merged 8 commits into from
Oct 13, 2022
Merged

Conversation

jedevc
Copy link
Member

@jedevc jedevc commented Jul 26, 2022

Follow up to #2935, and part 2 of #2773 (comment).

This PR adds support for scanning the resulting image to easily generate SBOMs. For example, using my example scanner at jedevc/buildkit-syft-scanner:

$ buildctl ... build --frontend=dockerfile.v0 --output type=image,name=<image>,push=true --opt attest=sbom=jedevc/buildkit-syft-scanner:latest

This generates SPDX attestations according to the In Toto SPDX attestation.

The jedevc/buildkit-syft-scanner image follows a simple scanning protocol:

  • The default cmd should contain the scanning command
  • On run, the image should scan the root filesystem located at BUILDKIT_SCAN_SOURCE, and output an SPDX document to BUILDKIT_SCAN_DESTINATION.

The details of this protocol will likely change, however, we need to ensure that anyone interested in producing an SBOM scanner can easily create an image to slot into the build process. Ideally, we'd also be able to provide a default, however, we should do this as a later follow-up, once the overall design is stabilized.

The scanner is integrated into the dockerfile frontend natively, and, if a frontend does not produce an SBOM when specified, the solver will fallback to this same scanner.

Still to-do:

  • Write a test suite, using a basic testing scanner.
  • Determine the user interface. We will aim to support an --attest flag for buildx, however, how this option is passed to buildkit (part of the frontend attributes, or part of the exporter attributes) is up for debate.
  • Define the minimal scanning protocol (documentation for the protocol should be added to our docs)

Note to reviewers: this PR shares many commits with #2935, see the comparison here to see only commits that are different.

@jedevc jedevc marked this pull request as draft July 26, 2022 15:23
@jedevc jedevc requested a review from tonistiigi July 26, 2022 15:27
@jedevc jedevc force-pushed the attestations-sbom branch 2 times, most recently from 1455aa5 to 4299dff Compare August 4, 2022 12:06
@jedevc
Copy link
Member Author

jedevc commented Aug 8, 2022

To test locally, you can use justinchadwell050/buildkit:sbom-attestations and justinchadwell050/dockerfile:sbom-attestations:

$ docker buildx create --driver docker-container --name sbom-builder --driver-opt image=justinchadwell050/buildkit:sbom-attestations
$ docker buildx build --driver sbom-builder --build-arg BUILDKIT_SYNTAX=justinchadwell050/dockerfile:sbom-attestations ...

@tonistiigi tonistiigi force-pushed the attestations-sbom branch 5 times, most recently from f875447 to 852605e Compare August 24, 2022 06:01
@jedevc jedevc marked this pull request as ready for review August 24, 2022 15:11
@jedevc
Copy link
Member Author

jedevc commented Aug 24, 2022

The one major remaining thing still missing from this is the ability to bundle attestations internally, which will allow the sbom scanning protocol to output sboms in different formats, which will be picked up by the exporter.

client/client_test.go Outdated Show resolved Hide resolved
@jedevc jedevc force-pushed the attestations-sbom branch 3 times, most recently from 1478cda to 0933e00 Compare August 31, 2022 10:58
Copy link
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

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

Looking at my local branch, this PR used to have some dockerfile tests. Did something get deleted?

@jedevc
Copy link
Member Author

jedevc commented Sep 15, 2022

Have pushed functionality to do attestation bundling to let a generator produce multiple outputs per input. This requires a new version of jedevc/buildkit-syft-scanner.

@jedevc
Copy link
Member Author

jedevc commented Sep 23, 2022

Have enhanced the scanning protocol to clarify how multiple refs are scanned at a time. A scan has one "primary" ref to scan (the runtime rootfs), but may contain multiple "extra" refs which could be used in the future to attach SBOMs of build contexts or of previous build stages.

Otherwise, I'm reasonably happy with the state of this, though we'd need a follow-up to introduce documentation for creating custom scanners.

@jedevc jedevc force-pushed the attestations-sbom branch 2 times, most recently from 4bdb500 to bb144fc Compare September 28, 2022 10:43
@jedevc
Copy link
Member Author

jedevc commented Sep 28, 2022

Have rebased, should be ready to review/merge.

I did draft a new commit to maybe pull on top of this: d4ced27 (with the corresponding change jedevc/buildkit-syft-scanner@e6fa1e1).

This would change the structure of the bundle fairly significantly - but the idea would be that instead of having an index.json that contains all the attestation metadata, each individual file in the bundle would be a full in-toto statement, so we no longer need a metadata file - this means we could use directory traversal to extract all the files in the bundle. I'd like to have this instead of a index file, since it's easier to integrate with (buildkit-syft-scanner is a lot simpler) - additionally, it would make building a dockerfile syntax with attestation mounts as in #2773 (comment).

frontend/attestations/parse.go Outdated Show resolved Hide resolved
frontend/sbom/sbom.go Outdated Show resolved Hide resolved
frontend/sbom/sbom.go Outdated Show resolved Hide resolved
frontend/sbom/sbom.go Outdated Show resolved Hide resolved
frontend/sbom/sbom.go Outdated Show resolved Hide resolved
exporter/containerimage/writer.go Show resolved Hide resolved
exporter/containerimage/writer.go Outdated Show resolved Hide resolved
frontend/attest/sbom.go Outdated Show resolved Hide resolved
frontend/attest/sbom.go Outdated Show resolved Hide resolved
return nil, err
}

att, st, err := scanner(ctx, p.ID, st, nil)
Copy link
Member

Choose a reason for hiding this comment

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

wdyt of controlling the extras here with defining ARG SBOM_SCAN_STAGE=true and global ARG SBOM_SCAN_CONTEXT=true (in addition to allowing it to be set in attestation attrs).

Copy link
Member Author

@jedevc jedevc Oct 13, 2022

Choose a reason for hiding this comment

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

So a stage that wants to be a scan point has a command for that ARG? That sounds ok, but I think it would be good to expose some level of control to the user somehow.

Maybe:

  • mode=min = scan only the final stage, regardless of ARGs
  • mode=max = scan the final stage, and also all the scan points (that are declared on the ARGs), maybe with a warning if no additional scan points have been point?

I'm not sure, what we would do if a user overrode those ARGs using build --arg? I think the user's choice is taken into account and we override the values in the Dockerfile.

Let's do this in a follow-up ↪️

Signed-off-by: Justin Chadwell <me@jedevc.com>
Additionally, propogate attestations through to the buildkit server when
using client.Build.

Signed-off-by: Justin Chadwell <me@jedevc.com>
An attestation bundle is a directory containing attestations.

It uses the same Ref and Path properites as an InToto Attestation, but
looks up the files inside the Ref+Path to process as raw InToto
statements. This allows flexibility for generating more complex
combinations of attestations, where all the details may not be known
ahead of time, and unlazying the reference is not desired.

Signed-off-by: Justin Chadwell <me@jedevc.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
These can be added by calls to Solve to modify the result before
exporting it. These can add additional metadata, insert new references,
or create new attestations, essentially any way that the caller wants to
modify the result.

Signed-off-by: Justin Chadwell <me@jedevc.com>
This adds a new processor to pass to Solve that converts a result's unit Ref
output to a simple Refs map type, which is required to be able to add
attestations at this point.

All metadata is appropriately converted, so that the new result should
have the same semantics as the old one.

Signed-off-by: Justin Chadwell <me@jedevc.com>
This adds functionality to perform an SBOM scan if the frontend did not
produce a valid SBOM.

Signed-off-by: Justin Chadwell <me@jedevc.com>
This includes both a dockerfile test to test the builtin dockerfile
scanner, as well as a more complex client test to test the interaction
between frontends and the fallback scanner.

Signed-off-by: Justin Chadwell <me@jedevc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants