-
Notifications
You must be signed in to change notification settings - Fork 547
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
Sigstore Bundle as OCI Artifact #3577
Comments
Hi folks, the proposal looks great so far! For example, if I create a trivy scan report and push it to the registry without using in-toto (trivy docs use intoto) , will I be able to sign them with Cosign? |
@vishal-chdhry This proposal is really only focused on how we would store a Sigstore bundle in an OCI registry. It will apply regardless of what is contained in the bundle itself (image signature, SBOM, scan report, etc.). I can't speak to what support may be added to cosign for specific artifact types, but the bundle format itself is flexible enough to encapsulate pretty much any artifact you'd like to attest. |
Thanks so much for exploring this and starting the conversation, I'm very excited to see this kick off. I'm not very familiar with OCI, so some of these questions will be a bit high level and won't get into the nitty gritty details of implementation. I'd love for @hectorj2f @vaikas @jonjohnsonjr @dlorenc @priyawadhwa to take a look at this too. Have we confirmed that the major registries (namely the ones listed in https://github.com/sigstore/cosign?tab=readme-ov-file#registry-support) support OCI v1.1, particularly the referring API? Or do we expect that most will rely on the fallback Referrers Tag Schema? Have we also explored the use of annotations rather than the reference types, attached to the For bundle identification, could we also have different artifact types for each use case, something like How to implement this is the next question. It seems like there is experimental support for OCI v1.1 added in #2684. Have you looked into this? I'd like to gauge how much work and changes to Cosign this proposal will involve. Considering breaking changes: Bundle usage is the direction we want to go, but even with a major revision of Cosign, I don't want to drop support for verifying signed containers that leverage tags/annotations. Maybe in another major revision, but even then, I'm apprehensive to break verification for everything that's been signed before this release. If there's already experimental support for OCI v1.1 in the codebase, then maybe this isn't an issue and it'll be straightforward to continue to support both. |
I've done testing with a bunch of these registries to check compatibility with the proposed scheme. Here are all of the registries I've found to have full OCI Image Manifest v1.1 support (including the
The following registries have some compatibility issues:
|
Beyond propagating this non-standard solution, the other thing which concerns me here is possibility of bumping into size constraints imposed on the image manifest. SBOM attestations can easily result in multi-megabyte bundles. The OCI spec has the following to say:
I haven't tested any of the registries to see what the various limits may be, but given that the blob-upload endpoints are already designed to accept arbitrarily large payloads (with support for things like chunked upload), this seems like the safer approach. |
Another thing to note is that going with a standards-based approach like this (as opposed to the annotations or custom tags) also gives us the ability to use 3rd-party tooling like the If I have already assembled a Sigstore Bundle ("bundle.json") I can associate it with the image "bdehamer/foo" with the following:
Similarly, I can see what artifacts are attached to my image with the following:
The |
That's pretty decent support. I do wonder if we should first focus on using the referrers tag and skip the referring api work since there is little support for the latter.
We'll also run into the size issue if we attach multiple SBOM attestations to a single tag, which I believe we do now when re-signing the same container. Also cc @imjasonh too to take a look |
The incremental work to support the the referrers API on top of the referrers tag scheme is minimal so there's not much to be saved by supporting one but not the other. On the publishing side, there's really no extra work at all -- if you see the right HTTP header returned when uploading the artifact manifest, you know you're done (no need to create/update the index). |
This is great work @bdehamer ✨ , based on my knowledge of OCI this is a very solid approach. |
I like what @haydentherapper mentioned here. Definitely I wouldn't rely on having to download all the bundles to know what contains each one :/.
It sounds good to me as long as we are not locked to a single one approach. |
Strong work in getting all this written down. Everything else is solid, and I'd like to sort the how to easily figure out which bundle to pull during verification which is certainly the most common use case. You attest once and verify multiple times, so just to overstate the obvious, we don't want to have to pull all the bundles before verification. Baking it into the mediaType seems little wrong to me because it's starting to leak a bit what's in the attestation. I don't really feel strongly against it, just a gut says it's a slippery slope. Also using the annotations would be more flexible in a sense that I'd reckon there's going to be more stuff there later on. |
So, we have two proposals for differentiating between bundles in the referrers index:
I'd be interested in any other proposals people may have or endorsements for one of the two options above. |
I have a slight preference in favor of using an annotation to specify the predicate type. It seems cleaner not to mash more metadata into the |
I'm supportive of using the annotation. Anyone else have any suggestions? Overall, LGTM on this proposal. Thanks so much for getting this started! Do you want to submit this as a spec in the cosign/specs folder? |
This looks like a good high level approach from the view of what we were intending from OCI. We were considering what annotations consumers might want to include for filtering a list of results, and a common idea was the identity of the signer, along with the creation date, so that tooling could quickly locate the most recent signature from a security team. I'd consider it from the perspective of the consumer tooling, what they need to quickly find what they need.
This may not technically be correct in the spec. The field needs to follow the naming requirements in RFC 6838 Section 4.2, and parameters are an addition that isn't part of the media type itself. Registries that validate the field may reject the manifest. The way OCI has done this in other places is to include the version in the media type, e.g. something like:
The suggestion is to keep manifests below 4MiB. Since the referrers response is a collection of descriptors with the annotations and artifactType values pulled up, and registries want to avoid too much pagination on the API (pagination that isn't supported with the fallback tag), I'm hearing a rough limit of 40kb of annotation content before some registries may start to reject the manifest push. That allows 100 descriptors to be included per page of the referrers response without exceeding the 4MiB limit.
This was an approach used by another project and they are now stuck creating the fallback tag on registries that support the referrers API to avoid breaking older clients. They'll see compatibility issues with other referrers aware tooling that may copy content across registries without the fallback tag. So I agree with the suggestion to use the API as the spec recommends. There's already going to be one transition for tooling from the existing |
Many of the Sigstore clients already have support for generating/verifying the protobuf bundle, but adding this support to tools like cosign and the policy-controller requires that we standardize on an approach for storing bundles in an OCI registry.
Proposal
The proposed approach for storing Sigstore bundles in an OCI registry is to follow the guidelines for artifact usage in the OCI image spec.
Publishing
First, the bundle itself is stored in it's JSON-serialized form as a blob in the registry
In this example “foo” is the name of the repository within the registry to which the artifact is being uploaded. The digest included as part of the POST is the hex-encoded SHA-256 digest of the raw bytes of the bundle itself.
Once the blob has been created, the next step is to create a manifest that associates the bundle blob with the image it describes:
The manifest has an
artifactType
field which identifies the type of the artifact being referenced -- in this case, it's the Sigstore bundle media type.The
layers
point to one or more blobs that comprise the artifact itself. In this example there is a single layer which points to the blob containing the bundle itself (note that the referenced digest is the same used during the blob upload).The
subject
field associates this artifact with some other artifact which already exists in this repository (in this case, an image with the digestc00010ff
)Since Sigstore bundles don't require any additional configuration data, the
config
field references the empty descriptor.At this point, any registry which supports the referrers API will automatically associate this manifest with the listed subject and make it available in the referrers index for that subject.
If the registry DOES NOT support the referrers API, a referrers list will need to be manually created/updated using the referrers tag scheme.
This index is uploaded with a tag that references the digest of the image to which all of the listed artifacts are associated. Each of the items in the
manifests
collection points to some other related artifact.Retrieval
When a client wants to locate Sigstore bundles which may be associated with a given image, they would first make a request to referrers API with the image's digest:
A
404 Not Found
response indicates that the registry does not support the referrers API and the referrers tag scheme should be used as a fallback:A
404
here would indicate that there are no artifacts associated with the image.Assuming there are artifacts present, one of the two above calls will return an image index listing the artifacts which have been associated with the specified image:
From this the client can identify any Sigstore bundles by looking at the
artifactType
field.Using the
digest
listed in the image index, the next step is to retrieve the manifest for the bundle:The final step is to use the
digest
from the first of thelayers
to retrieve the bundle blob:Bundle Identification
For any given image, there may be any number of referring artifacts. If there are multiple Sigstore bundles associated with an image (say a build provenance bundle and a signed SBOM bundle) it may be difficult to identify which artifact is which in the image index:
In the example above there are two Sigstore bundles associated with some image but there is no way to distinguish between them without going through the process of downloading each one and inspecting the contents.
One approach we might employ to help disambiguate bundles is the use of annotations to surface additional information about the contents of the bundle. In situations where Sigstore is being used to sign an in-toto statement we could surface the statement predicate type as an annotation:
Now the purpose of each of the bundles listed in the image index is clear.
Related Issues
The text was updated successfully, but these errors were encountered: