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

Support in-toto attestations #259

Closed
MarkLodato opened this issue Apr 15, 2021 · 12 comments
Closed

Support in-toto attestations #259

MarkLodato opened this issue Apr 15, 2021 · 12 comments

Comments

@MarkLodato
Copy link
Contributor

It would be great if cosign could switch to using in-toto attestation, which is a new standard for authenticated metadata about software artifacts as part of SLSA.

The advantage of attestations over the current "Simple Signing" format is that (1) it is not container specific, so that it fits into the SLSA framework, and (2) it natively supports "predicates", which are arbitrary, structured metadata about the software artifact. For example, one can add provenance explaining not just who produced the artifact but how it was produced (source repo, build script, arguments, timestamp, etc.)

Notes:

  • This uses the SSL Signing Spec under the hood.
  • The spec is not yet finalized, so we'd need to figure out how stable you want it to be before adoption.

(Should this be merged with issue #228?)

@MarkLodato MarkLodato mentioned this issue Apr 15, 2021
5 tasks
@dlorenc
Copy link
Member

dlorenc commented Apr 15, 2021

I think you're right, the #228 issue is probably how we'll cover compatibility with things like the SSL signing spec. Last I looked they were "compatible" with the way we store the signature components today, so we'd probably add an output/input converter rather than actually switch the way signatures are stored in the registry.

I'd have to think about the other signed provenance aspects more, I can't think of anything that would make sense here off the top of my head. We can sign and upload them with cosign today using something like:

cosign sign -payload <provenance> -key <blah> <image to attach the provenance to>

I can't think of anything that would make sense to include by default in a "cosign sign" invocation though. I also imagine most of the provenance and signatures would come from CI systems, rather than a command line tool.

One idea (this is what I had in mind by leaving the payload format open in the spec here: https://github.com/sigstore/cosign/blob/main/SPEC.md#payloads) would be to choose a mediaType for the in-toto provenance files and add it as a supported payload type for verification. The main thing we'd need to add support in cosign for is the ability to deserialize one and find the digest of the referenced artifact, to confirm the provenance is actually for the desired container image.

Would that make sense? Then CI systems (say Tekton Chains) could automatically generate in-toto provenance and attach it to containers in an interoperable way that cosign and other tools (say OPA Gatekeeter, other admissions controllers) can verify.

@MarkLodato
Copy link
Contributor Author

(Note: I filed #264 about the storage mechanism, but that's orthogonal to the thread here.)

I think we might be on the same page, but I just want to flesh things out a bit to make sure.

Sorry, I should have explained more. The in-toto attestation has three layers:

  • Envelope, containing the signature
  • Statement (what cosign calls payload), containing the subject (i.e. digest of the image), predicateType, and predicate
  • Predicate, containing arbitrary JSON, which could be empty if there is no predicate.

Provenance is just one type of predicate, but others are possible too, like vulnerability scan or test result. Or you could have a null predicate, which would be the default for cosign sign.

Right now, the Simple Signing payload format serves the same purpose as the in-toto Statement, but it is OCI-specific and has no strong typing of predicates, among other things. That's why I'm suggesting switching.

Last I looked they were "compatible" with the way we store the signature components today, so we'd probably add an output/input converter rather than actually switch the way signatures are stored in the registry.

Correct, though I disagree with converting (#264).

We can sign and upload them with cosign today using something like:

Correction:

cosign sign -predicateFile <predicate.json> -key <blah> <image to attach the provenance to>

This can be any arbitrary metadata. By default, it would be an empty predicate.

I also imagine most of the provenance and signatures would come from CI systems, rather than a command line tool.

Couldn't the CI system shell out to the cosign tool, or use some sort of cosign library?

The main thing we'd need to add support in cosign for is the ability to deserialize one and find the digest of the referenced artifact, to confirm the provenance is actually for the desired container image.
...
Then CI systems (say Tekton Chains) could automatically generate in-toto provenance and attach it to containers in an interoperable way that cosign and other tools (say OPA Gatekeeter, other admissions controllers) can verify.

Yup, agreed.

@dlorenc
Copy link
Member

dlorenc commented Apr 16, 2021

Correction:

cosign sign -predicateFile <predicate.json> -key <blah> <image to attach the provenance to>

This can be any arbitrary metadata. By default, it would be an empty predicate.

Sorry, the -payload flag is an actual flag today that exists for this purpose. You can sign and attach literally anything with it today, including a predicateFile.

Couldn't the CI system shell out to the cosign tool, or use some sort of cosign library?

Yeah, but I don't think I want to encourage this for provenance. We support signing artifacts within a CI build execution, because the build produced the artifact and that's how people are used to signing artifacts today. I would prefer we encourage build systems to produce and sign provenance from outside the execution environment, which probably wouldn't be via shelling out. A library can handle that.

@MarkLodato
Copy link
Contributor Author

I would prefer we encourage build systems to produce and sign provenance from outside the execution environment, which probably wouldn't be via shelling out. A library can handle that.

Ah, makes sense. Totally agree with you there!

Back to the issue at hand. My suggestion is to (once it is stable) switch to the in-toto attestation format even for regular signing, because it will fit into the ecosystem we're trying to build with SLSA. Obviously you shouldn't commit to anything yet because SLSA and the ecosystem have not yet materialized. I'm just filing this to get directional agreement and to keep an eye out for design decisions that might impact that.

What do you think?

@dlorenc
Copy link
Member

dlorenc commented Apr 16, 2021

Back to the issue at hand. My suggestion is to (once it is stable) switch to the in-toto attestation format even for regular signing, because it will fit into the ecosystem we're trying to build with SLSA. Obviously you shouldn't commit to anything yet because SLSA and the ecosystem have not yet materialized. I'm just filing this to get directional agreement and to keep an eye out for design decisions that might impact that.

What do you think?

The primary goal here is broad adoption and support in other tooling for the signing of containers. Support for more rich provenance would come behind that. I still hesitate to switch the default behavior from something that can be trivially verified with a one line bash script to something more complex, even if it means we miss out on the ability to store rich attestations here.

I'm in full agreement that we should document how to use cosign to sign in-toto attestations, support their retrieval/verification and even to make it easy for people that want to use these, but the default signature format needs to be something that's as widely supported as possible (hence the choice of simple signing for now) or something with significant real-world demand.

The data I've seen and what cosign is designed to address is really just the incredibly limited use-case of "I just want to sign and verify containers".

IMO integrating provenance/attestation generation and signatures into things like CI/CD systems and making it completely transparent is the only way we're going to get adoption there.

@MarkLodato
Copy link
Contributor Author

I still hesitate to switch the default behavior from something that can be trivially verified with a one line bash script to something more complex

Can you provide a link to such a bash script? I don't see how that is possible with cosign's current design.

Unless I'm missing something, my suggestion does not change the complexity at all. It just changes whether you use Simple Signing or the in-toto Statement. Everything else stays the same.

as widely supported as possible (hence the choice of simple signing for now) or something with significant real-world demand

Yes, that makes total sense. Simple signing is the right choice for now.

@dlorenc
Copy link
Member

dlorenc commented Apr 16, 2021

Sure, we should probably actually document this. Here's a quick one:

https://gist.github.com/dlorenc/19af39d5c06b46a37e526fc87a6859f9

@dlorenc
Copy link
Member

dlorenc commented Apr 16, 2021

Here's one @bobcallaway wrote awhile ago with steps for doing the "keyless" signatures and transparency log aspects with standard tooling as well: https://github.com/redhat-et/sigstore-demo/blob/main/scripts/manual-steps.sh

@MarkLodato
Copy link
Contributor Author

Thanks, that helps (though it's far more than one line)!

To clarify, if you switched to in-toto attestations, there would only be two minor differences:

  • instead of using payload.json directly, you'd construct the PAE
  • a different jq filter on line 26 of your script (since the field name is different and it's an array)

@dlorenc
Copy link
Member

dlorenc commented Apr 19, 2021

Sorry to clarify it's a few lines to fetch, but that can't be helped regardless of the format. It's the compatibility with openssl/liberal/etc for verification that's important.

The PAE construction is exactly what I'm worried about, even though it's relatively simple it's still another step that isn't trivial to translate into every language and tool.

@MarkLodato
Copy link
Contributor Author

If we switched to a simpler PAE (secure-systems-lab/dsse#27), would that address your concern? Or are you more concerned about having any PAE at all?

@dlorenc
Copy link
Member

dlorenc commented Jul 29, 2021

This is done now with the new "cosign attest" and "cosign verify-attestation" commands. Thanks @developer-guy and @Dentrax!

@dlorenc dlorenc closed this as completed Jul 29, 2021
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

No branches or pull requests

2 participants