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

Sigstore bundle #2204

Closed
wants to merge 41 commits into from
Closed

Conversation

kommendorkapten
Copy link
Member

@kommendorkapten kommendorkapten commented Aug 26, 2022

Closes #2131

Authored by @kommendorkapten and @patflynn

Summary

First iteration of the proposed new bundle format for cosign. See README.md for more details. The intent for this PR is not to be merged in this state, it is to start the discussion as decided on the design review meeting at 2022-08-22.

Before accepting, make sure these tasks are done:

Release Note

N/A as of now.

Documentation

N/A as of now.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
…fields.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@kommendorkapten
Copy link
Member Author

@kommendorkapten
Copy link
Member Author

Rendered README.md
Rendered verification_flows.md

Copy link
Contributor

@znewman01 znewman01 left a comment

Choose a reason for hiding this comment

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

Thanks for doing this! It's a lot easier to hash out the important details in this format.

Sorry for the million nitpicks, on the whole I think it's looking good 😄

}
}

if b.rekorEntry != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

is it correct that you must also enter this path if/when a certificate (if used) is expired?

Copy link
Contributor

Choose a reason for hiding this comment

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

likewise, does the final cert validation wrt to timestamp need to occur here or in the outer loop?

Copy link
Member Author

Choose a reason for hiding this comment

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

This will be addressed in an updated coming soon, have it locally but need to run it through once more before pushing. Will add explicit logic for cert validation wrt to timestamp in verifyRekor.

@patflynn
Copy link

Fredrik is out for a couple of weeks, one approach to iterating on this would be to merge as is, and then we can work through all the comments on this PR, generating new PRs as we go. It's going into a temporary spot anyway, WDYAT?

@znewman01
Copy link
Contributor

I think I'd prefer to work on a branch/fork, I don't think the diff between "original pass" and "latest pass" is meaningful in this case. Then we don't have to worry about tests etc.

…osed

during review.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@znewman01
Copy link
Contributor

Verifiers should only reconstruct the Rekor entry when there is at least one Rekor entry in the bundle, as there is no requirement that the entry was ever put on any Rekor instance.

I think this is main point of disagreement. I was imagining TSAs signing off on Rekor entries, not just the signature bytes.

This just feels more consistent to me. If there are multiple TransparencyLogEntrys from multiple Rekors, I'd expect that they signed the exact same Rekor entry. Why would the thing that the TSA signs be any different?

Maybe relevant, maybe not: there are [subtle crypto attacks](https://www.bolet.org/~pornin/2005-acns-pornin+stern.pdf](can work backwards) to create a new public key that a fixed signature validates against. I don't think this is actually exploitable in our setting, but IMO the more context in the data that gets countersigned the better.

Currently there are sufficient information in the bundle to reconstruct the entry iff the Rekor kind is either intoto or hashedrecord, as those two was the only one being discussed initially. The conent in the bundle is a oneof, this can be extended if we need to capture more types.

So, to clarify the plan is "each Rekor kind/version has a corresponding content type"? For instance, for Alpine we would add a new one that included the PKGINFO data.

If that's the case, I think I'd want to be more explicit about the mapping. So the doc for content would say: "hashedrekord 0.0.1 => MessageSignature, intoto 0.0.1 => ...".

But then why not just use the Rekor types directly?

Also, what about downstream users who might want to verify other Rekor types? They're supposed to be pluggable, the bundle format should be too IMO.

This will of course make the M x N verification flow grow in each client library. But I don't see this as a huge issue, it's only a mapping from the data in the bundle to the correct entry in Rekor that can be properly canonicalized so the verification can happen. It's still code, but not that complex, it must only be written once, and is easy to test for correctness.

I would be very worried if client libraries needed to reconstruct the entry by e.g. parsing an Alpine ".apk" file (which is what we'd have to do if we weren't adding another content value). If it's just canonicalizing data, I can live with that (though if we can avoid it, we should IMO).

The reason each Rekor entry contains a KindVersion is to make the structure align better with the response from Rekor,

IMO alignment with Rekor's response as it exists today should be a non-goal; I think there are several proposals floating around right now to improve it.

Alignment with Rekor's eventual response is a good idea. However, I think the bundle format should inform the Rekor API, not the other way around.

and as I would guess the most common scenario (at least initially) is to only have a single entry, I would argue this is a bit more developer friendly, and would prefer a bit of duplication to simplify the data structure.

I don't actually think this is more dev friendly. This means that my function to reconstruct the entry for verification needs to access both the TransparencyLogEntry which may or may not exist and the content. If you stuck all the information in content, that function is much simpler.

Yes, you are correct that if no Rekor entry exist in the bundle, there is no KindVersion, so this mean that the verifier can not verify it agains any Rekor instance, and have to resort to the signed RFC3161 timestamp during verification, which would be primarily to verify that it was signed during the time the certificate was valid.

To me, this complicates the verification flow unnecessarily. "If timestamp, check that the TSA signed X, otherwise, check that Rekor signed Y" seems more complicated than "filter the entries in TimestampVerificationData to find which ones signed X."

Copy link
Contributor

@znewman01 znewman01 left a comment

Choose a reason for hiding this comment

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

Thanks for the comments, super helpful context

// policies.
// When using RFC3161 timestamps together with DSSE envelopes, the message
// imprint (message digest) MUST be computed over the payload (octets).
message TimestampVerificationData {
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO this is not a real concern, today the bundle is only possible to map to two Rekor types: inoto and hashedrecord.

How deliberate is that? I think we should try to support all of them.

For the verification to succeed an asset in the bundle must be able to correctly be put on different logs with different types, which I would say is not possible. [...]

I worry a little about different versions of the same kind in this context. Not sure whether that's a big deal or not.

But I think you're right overall.

So this is now implicitly verified, but when talking about verification flows, we can make this explicit, that the verifier MUST verify that all entries are of the same type. How about same type with different versions? I think we should start with require the same version too, until we know of any concrete use-case where it may make sense to allow that.

+1

int64 log_index = 1;
// The hash digest stored at the root of the merkle tree at the time
// the proof was generated.
bytes root_hash = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

Personal bias here: I want as many types as possible always.

Specifically, every time I see a bytes I have to think "what format is that?" If I see HashOutput I think "that's the output of a hash algorithm, I don't care what format it is."

Agreed that it feels wonky to duplicate the algorithm. So maybe there's room for three (!!) types: HashOutput { bytes }, HashAlgorithm = enum and HashData = (HashOutput, HashAlgorithm). I understand if that seems like too much.

some out-of-band data is already needed, like the public key (which may include parameters/what hash function to use). So there is already a need for certain knowledge of the transparency log, and also sharing what hash function is used for computing the Merkle tree is IMHO not a problem.

I buy that. Should we try to enumerate all these parameters in a new type? That feels like a useful exercise. It would allow creating a cross-language test suite!

(Okay if that's a TODO and we don't do it in this PR)

@patflynn
Copy link

could we lean into this comment: "Could we push something marked experimental pretty soon (with a self-destruct clock, to prevent it from being entrenched), then try to build client libraries with it? I think that will help us shake out the rought edges."? Feels like we're never going to merge :). We can get this in, start implementation in the various clients, and iterate on the format.

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@znewman01
Copy link
Contributor

could we lean into this comment: "Could we push something marked experimental pretty soon (with a self-destruct clock, to prevent it from being entrenched), then try to build client libraries with it? I think that will help us shake out the rought edges."? Feels like we're never going to merge :). We can get this in, start implementation in the various clients, and iterate on the format.

FWIW I'm pretty happy with this as-is. I still have one high-level concern (articulated in my last comment) but doesn't need to block the PR.

That said—what's the benefit of merging the experimental version to the Cosign repo? I think we decided it makes more sense in a new repo long-term anyway. So what if we just made that (even if it's just on a personal GH account for now), then we could merge whatever we want and do some more formal process to pull it back into the sigstore/ universe.

@kommendorkapten
Copy link
Member Author

That said—what's the benefit of merging the experimental version to the Cosign repo? I think we decided it makes more sense in a new repo long-term anyway.

This is my preference to, like a repo namedsigstore/protobuf, or sigstore/protobuf-experimental.

@kommendorkapten
Copy link
Member Author

kommendorkapten commented Oct 17, 2022

@znewman01

I think this is main point of disagreement. ...

There are a few important topics in that comment, and this PR is already getting quite large. When we get a new repo where the bundle goes, how about I open up some issues with your different questions as I think they can be more efficiently covered separately?

edit: s/you/your

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@znewman01
Copy link
Contributor

There are a few important topics in that comment, and this PR is already getting quite large. When we get a new repo where the bundle goes, how about I open up some issues with your different questions as I think they can be more efficiently covered separately?

Works for me!

@haydentherapper
Copy link
Contributor

Meta comment - It seems like a lot has changed since the last time I looked at it, so I'll need to do another pass. Can we avoid any more significant changes before it's checked in, as it's hard to know what's changing between each pass?

…tion data'

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
@znewman01
Copy link
Contributor

A use case for key IDs: #1351

Some KMSes support key rotation, and the same key has different "versions." When we use KMS, we should stick the key version as a hint in the bundle.

@bobcallaway
Copy link
Member

https://github.com/sigstore/protobuf-specs is ready whenever this can be moved over.

@kommendorkapten
Copy link
Member Author

Thanks @bobcallaway, I'll move and close this PR today.

@kommendorkapten
Copy link
Member Author

Closing this PR in favour of sigstore/protobuf-specs#1

znewman01 added a commit to znewman01/cosign that referenced this pull request Dec 22, 2022
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) sigstore#2296 and sigstore#2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
znewman01 added a commit to znewman01/cosign that referenced this pull request Dec 22, 2022
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) sigstore#2296 and sigstore#2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
znewman01 added a commit to znewman01/cosign that referenced this pull request Dec 23, 2022
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) sigstore#2296 and sigstore#2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
znewman01 added a commit to znewman01/cosign that referenced this pull request Dec 23, 2022
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) sigstore#2296 and sigstore#2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
znewman01 added a commit to znewman01/cosign that referenced this pull request Jan 2, 2023
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) sigstore#2296 and sigstore#2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
znewman01 added a commit that referenced this pull request Jan 2, 2023
This library:

- Is testable.
- Is consistent across the CLI.

Related to (does not fix) #2296 and #2204.

Signed-off-by: Zachary Newman <zjn@chainguard.dev>

Signed-off-by: Zachary Newman <zjn@chainguard.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cosign signing bundles
9 participants