Open znewman01 opened 1 year ago
I would like to at least explore the idea of multiple signatures as well. Different objects in a repository like java might come from different sources and then uploaded together, so adding a bundle to a repository might involving merging multiple signature objects?
Which is slightly different than say one person collecting all the artifacts and singing them after the fact.
I'm not sure the highly-heterogeneous signatures problem needs to be solved at the same time. If we have N objects signed by K multi-artifact signatures, under what scenarios would we expect K ~= N?
If we expect K ~= 1 or K << N, then in the worst case verifying each blob requires checking O(K) bundles for which object is verified by which file. Or if all K bundles are loaded into memory, a lookup table for digest => signature bundle could be made in memory.
My 0.02c: we should reserve the "bundle" language for "materials sufficient to perform one verification on one artifact," and work on a separate wrapping format to handle each of the suggested use cases (N:1 sig:artifact, N:N sig:artifact, M:N sig:artifact).
The distinction between the "bundle" format and its wrapping formats would then be opaque to consuming users, but saves us from having the bundle itself approach RFC 5652 levels of complexity 🙂
Would a wrapping format contain multiple bundles, one per file?
That's what I was thinking, yeah -- the wrapping format would contain one bundle for each file, with each bundle carrying its own verification materials.
That accomplishes the "N:N sig:artifact" use case, although it's not as ergonomic for the N:1 or M:N use cases (there would probably be a lot of duplication for those).
That scales pretty poorly in file size (>4KiB/file) & number of API calls to rekor, fulcio, etc.
That's part of the motivation, as it takes quite a while to negotiate a dozen or two dozen files to sign, in addition to creating a good number of intermediate artifacts in the form of those bundles and the compounding file size.
Wrapping together bundles naively also seems like it would explode verification time, making it a linear search, effectively?
I don't think a wrapping format has to imply linear behavior: clients could choose to interpret it naively (and run into the scaling issues you mentioned), or choose to batch requests to the various Sigstore services.
The main advantage to having it being a wrapper, rather than embedded in the bundle format, is minimizing format agility: it should be impossible (or as hard as possible) to misuse a cryptographic container format (like a Sigstore bundle). Limiting the number of possible interpretations of a bundle helps with that, since a user is precluded from asking questions like "should a threshold apply here?" or "how many files should I be verifying?"
I agree 100% about the compounding file size, though -- if the goal is to support dozens or even hundreds of verifications in a single file, we might want to look into support for detaching the input digest and other fixed inputs that only end up being duplicated across each verification.
One way to look at this is to think about how you want the verifier to handle multiple artifacts in one bundle. Does the verifier fail if any artifact fails to be verifiable? Does the client return a list of verified artifacts and unverifiable artifacts? This gets more complex if you also start including multiple signatures for an artifact.
I don't think a wrapping format has to imply linear behavior: clients could choose to interpret it naively (and run into the scaling issues you mentioned), or choose to batch requests to the various Sigstore services.
Emphasis mine, that sounds like another feature request, yeah?
I think discussion here should probably revolve around the use cases. The title of the PR is "multiple artifacts, one bundle", but there are a couple concrete use cases in https://github.com/sigstore/cosign/issues/2557:
Signing individual files produced by one CI step and verifying them on downloading in another, e.g.: when using GitHub Actions @actions/download-artifact and @actions/upload-artifact. Adding a step to tar/untar defeats the optimizations done to enable fast file transfers without intermediate copies on disk.
Signing multiple blobs within an OCI Artifact Manifest. This is useful in scenarios where the artifact manifest or even the OCI registry may be controlled by one party but one or more blob(s) are authored by another. Consider the scenario of a package manager: 1..N blobs may be produced by a package author, producing 1..N signatures, which are then uploaded via an API to the package manager, which distributes those back by inserting them into an OCI Registry.
Echoing @AaronFriel here: by avoiding heterogenous signatures we save ourselves a lot of design complexity. Let's move that discussion to https://github.com/sigstore/protobuf-specs/issues/53
My 0.02c: we should reserve the "bundle" language for "materials sufficient to perform one verification on one artifact,"
Hm...I'm looking at this from the opposite perspective, where we define a bundle as "materials sufficient to perform one verification on one statement."
Then, a statement could be any of:
We wouldn't have N signatures on N artifacts, we'd have 1 signature on N artifacts.
One way to look at this is to think about how you want the verifier to handle multiple artifacts in one bundle. Does the verifier fail if any artifact fails to be verifiable? Does the client return a list of verified artifacts and unverifiable artifacts?
I think it's pretty foolproof to fail if any artifact fails to verify, with the caveat that users may only want to provide a subset of the artifacts. Think sigstore verify --bundle multibundle.sigstore blob1 blob2 blob4
(note missing blob3
).
I agree that it should be hard to misuse a container format, and in principle this does add complexity making that more likely. But in practice what's being proposed here is basically just signing a checksums.txt
file instead of signing artifacts directly. (Maybe there's some risk I'm not seeing).
This gets more complex if you also start including multiple signatures for an artifact.
Agreed, let's avoid that for now.
See https://github.com/sigstore/cosign/issues/2557 and https://github.com/sigstore/rekor/issues/845