-
Notifications
You must be signed in to change notification settings - Fork 132
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
Add support for SBOM attestations #730
Conversation
Skipping CI for Draft Pull Request. |
d58b3e6
to
2924f10
Compare
38d972f
to
61d022a
Compare
401193c
to
c8ab778
Compare
The following is the coverage report on the affected files.
|
(Mostly a drive-by comment, didn't review the code) I love it! If you're interested in getting |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
e9676f4
to
59f6a5c
Compare
It's been a while. I've re-worked this PR to address the comments and to focus more on SBOM attestations (instead of SBOM attachments). I updated the description to reflect these changes. It is now out of draft. It also now includes a tutorial, I think this PR is pretty complete right now, but let me know if there's something missing! (Apologies for the huge PR. I could not find a reasonable way to break it up.) |
The following is the coverage report on the affected files.
|
This commit teaches Chains to create SBOM attestations based on type hinting results from TaskRuns. The general idea is that a Task generates the SBOM, then uploads it as a blob to an OCI registry. Chains then downloads the blob and uses it as the payload when creating the SBOM in-toto attestation. Multiple SBOMs per image are allowed. They may be of different formats. Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
The following is the coverage report on the affected files.
|
Thanks for adding the examples and tutorials. I'm wondering if we might benefit from an e2e test here (our e2e tests are already taking ~45 mins 😅). |
Yeah, for sure! Is this something that should be part of this PR or a follow up? I'm happy with either way. Just trying to not make this PR even harder to review. |
I think it can definitely be in a follow up PR. |
@@ -33,9 +33,19 @@ The list of images can be separated by commas or by newlines. | |||
value: img1@sha256:digest1, img2@sha256:digest2 | |||
``` | |||
|
|||
When processing a `TaskRun`, Chains will parse through the list, then sign and attest each image. | |||
Chains also suports signing SBOMs. If using the `IMAGE_URL` and `IMAGE_DIGEST` combination, the | |||
`TaskRun` can also emit the `IMAGE_SBOM_URL` and the `IMAGE_SBOM_FORMAT` results. The first contains |
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.
It can be in a separate PR but we should probably also add support for Object Results, like we have for Artifact Inputs.
xxxARTIFACTS_SBOM:
url:...
format:...
@@ -44,6 +45,15 @@ type ObjectSigner struct { | |||
Backends map[string]storage.Backend | |||
SecretPath string | |||
Pipelineclientset versioned.Interface | |||
appContext context.Context |
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 don't think we want to attach contexts to the signer like this - this would prevent us from reusing the signer for multiple requests if there's a deadline attached to it. We already plumb through a context with Sign - we should reuse that if possible.
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.
The context here has a different purpose (which is probably a code smell).
The SBOM formater needs access to the OCI registry so it can read the SBOM (consider a private repo). To do this, we need a kube client to initialize the k8schain.
One way to get a kube client is to get it from the context, e.g. kubeclient.Get(ctx)
. This, however, does not work with the context given to a reconcile iteration - the one ObjectSigner.Sign
gets. It only works for the "application" context - the one NewController
gets.
Instead of storing the application context, we could store the kube client directly in the ObjectSigner. That might make things more obvious.
@wlynch, wdyt?
@@ -65,6 +68,7 @@ type TektonObject interface { | |||
SupportsTaskRunArtifact() bool | |||
SupportsPipelineRunArtifact() bool | |||
SupportsOCIArtifact() bool | |||
SupportsSBOMArtifact() bool |
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 know this is following the pattern of existing funcs, but does this make sense to add to the Object interface? 🤔
I don't know if "whether SBOM artifacts are supported" is a property of an Object we want to enforce on all implementations. Should this be broken out into its own interface?
pkg/artifacts/sbom.go
Outdated
if _, err := name.NewDigest(trimmed); err != nil { | ||
logger.Errorf("error getting digest for SBOM image %s: %v", trimmed, err) | ||
continue | ||
} |
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.
Everything until here is completely the same as the above case. Wrap it into a func?
The IMAGES type-hinting result allows a TaskRun to provide a dynamically sized list of images to be processed by Chains. In the case of SLSA Provenance, one statement is created which contains in its list of subjects all the images from the result. This makes sense as these images do share provenance. The SBOMS type-hinting result was meant to add support for SBOM when the IMAGES result is used. However, unlike SLSA Provenance, an SBOM is usually descriptive of a single image. This means that the order of the items in the SBOMS result must match the order of the images in the IMAGES result. This can be problematic. This commit drops support for the SBOMS type-hinting result, and the corresponding SBOMS_FORMAT, to avoid confusion. If we want to re-introduce it, let's make sure that Chains can provide some sort of assurance regarding the order of the SBOMs matching the order of the images. Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
The following is the coverage report on the affected files.
|
Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
@@ -33,9 +33,18 @@ The list of images can be separated by commas or by newlines. | |||
value: img1@sha256:digest1, img2@sha256:digest2 | |||
``` | |||
|
|||
When processing a `TaskRun`, Chains will parse through the list, then sign and attest each image. | |||
Chains also suports signing SBOMs. If using the `IMAGE_URL` and `IMAGE_DIGEST` combination, the |
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 am trying to consolidating type hinting docs in #913. Not sure which PR will be merged first. But this section may be better to live in the new "how to chain with pipeline" doc?
| Key | Description | Supported Values | Default | | ||
| :--- | :--- | :--- | :--- | | ||
| `artifacts.sbom.format` | The statement format to store `SBOM` payloads in. | `in-toto` | `in-toto` | | ||
| `artifacts.sbom.storage` | The storage backend to store `SBOM` payloads in. Multiple backends can be specified with comma-separated list ("oci,tekton"). To disable the `OCI` artifact input an empty string ("").| `tekton`, `oci`, `gcs`, `docdb`, `grafeas` | `oci` | |
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.
Do we support all the storage backend for sbom currently? If not, should we limit this list to what we currently support?
- name: IMAGE_URL | ||
description: Reference to the image the SBOM will be generated for. | ||
- name: IMAGE_DIGEST | ||
description: Digest of the image the SBOM will be generated for. | ||
- name: IMAGE_SBOM_URL | ||
description: Reference, including digest, to the SBOM blob. | ||
- name: IMAGE_SBOM_FORMAT | ||
description: The SBOM format. | ||
type: 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.
If Chains takes this approach, I am curious if we should work with catalog team to make sure the syft task can produce right results so that chains can sign? https://github.com/tektoncd/catalog/tree/main/task/syft/0.1
@@ -33,9 +33,18 @@ The list of images can be separated by commas or by newlines. | |||
value: img1@sha256:digest1, img2@sha256:digest2 | |||
``` | |||
|
|||
When processing a `TaskRun`, Chains will parse through the list, then sign and attest each image. | |||
Chains also suports signing SBOMs. If using the `IMAGE_URL` and `IMAGE_DIGEST` combination, the |
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.
Chains supports multiple images type hinting by just appending a prefix before IMAGE_URL
and IMAGE_DIGEST
. Does SBOM generation support this? If so, can we mention this in the doc as well?
"k8s.io/client-go/kubernetes" | ||
) | ||
|
||
func GenerateAttestation(ctx context.Context, kc kubernetes.Interface, builderID string, maxBytes int64, sbom *objects.SBOMObject) (interface{}, 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.
shouldn't this sbom formatter implement the Payloader interface?
func (b *structuredSignableExtractor) extract(ctx context.Context, obj objects.TektonObject) []StructuredSignable { | ||
logger := logging.FromContext(ctx) |
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.
Great refactor. Thanks Luiz. 2 things
- Could we possibly do the refactor in another PR instead of overloading this sbom PR?
- Could we extend this refactor to object param/results also? related to this comment Add support for SBOM attestations #730 (comment)
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.
Extracted the StructuredSignable piece to #924. Hopefully, this will make it easier to also do this for the object param/results.
@lcarva: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
@lcarva: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
The changes in this PR means that Chains would sign any SBOM mentioned in the results of a TaskRun. In a system where users are able to run their own Tasks, this can be easily abused. It turns out that that's the use case I was trying to address. Thus, I have been struggling in accepting this is a good approach. After some further reflection, I'm going to abandon this PR. I don't plan on removing the branch nor my fork, so if you want to take a shot at this and address the security concerns, you are welcome to do so. If you're curious, for my particular case, I'm going with an approach that relies on the information from the SLSA Provenance since that's already signed (and generated!) by Chains. A task that produces the sbom will use something like oras to push the SBOM to the registry as an OCI blob and record the digest reference as a Task result. On the verification side, we can assert that the task that produced the SBOM is trusted, fetch the SBOM given the reference, and process it as needed. |
Changes
The idea is a TaskRun produces an unsigned SBOM and pushes it to the OCI registry. The reference to the SBOM is then added to the result IMAGE_SBOM_URL. When Chains sees this result, it downloads the SBOM from the OCI registry, signs it, then adds to the image attestations with an SBOM-specific predicate.This is also possible when using the IMAGES result, and the corresponding SBOMS result. Both must have the exact number of items.It's a draft because it's still missing important things like unit tests and documentation. Some of the TODOs also need to be addressed. Looking for early feedback on the overall approach.This commit teaches Chains to create SBOM attestations based on type hinting results from TaskRuns.
The general idea is that a Task generates the SBOM, then uploads it as a blob to an OCI registry. Chains then downloads the blob and uses it as the payload when creating the SBOM in-toto attestation.
Multiple SBOMs per image are allowed. They may be of different formats.
Submitter Checklist
As the author of this PR, please check off the items in this checklist:
functionality, content, code)
Release Notes