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

FR: multiple artifacts, one bundle #48

Open
znewman01 opened this issue Dec 20, 2022 · 11 comments
Open

FR: multiple artifacts, one bundle #48

znewman01 opened this issue Dec 20, 2022 · 11 comments
Labels
bug Something isn't working

Comments

@znewman01
Copy link
Contributor

See sigstore/cosign#2557 and sigstore/rekor#845

@loosebazooka
Copy link
Member

loosebazooka commented Dec 20, 2022

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.

@AaronFriel
Copy link

AaronFriel commented Dec 20, 2022

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.

@woodruffw
Copy link
Member

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 🙂

@AaronFriel
Copy link

Would a wrapping format contain multiple bundles, one per file?

@woodruffw
Copy link
Member

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).

@AaronFriel
Copy link

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?

@woodruffw
Copy link
Member

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.

@haydentherapper
Copy link
Collaborator

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.

@AaronFriel
Copy link

AaronFriel commented Dec 20, 2022

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?

@AaronFriel
Copy link

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 sigstore/cosign#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.

@znewman01
Copy link
Contributor Author

Echoing @AaronFriel here: by avoiding heterogenous signatures we save ourselves a lot of design complexity. Let's move that discussion to #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:

  • an attestation
  • a single artifact
  • multiple artifacts

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants