-
Notifications
You must be signed in to change notification settings - Fork 64
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
proposal: provenance generation and verifying attestation using cosign with new predicate type #105
Comments
Thanks for putting this together! I definitely want to explore what kind of attestations we can start putting together for git commits. So I'm a bit hesitant about trying to create an attestation that captures all commits in a single document for a few reasons:
You would probably want to scope this to a particular ref - i.e. what commits are reachable by I think you also raise a great point with the concern around backwards compatibility w.r.t. how to handle repos that previously weren't signing commits. I don't think there's significant advantage for repo consumers in guaranteeing that every commit in the history was signed, so as long as the commit you're building from was signed by a trusted identity. That said, I 100% agree that we should be encouraging people to sign all commits, because ideally you should be able to check out an arbitrary revision and have trust in the integrity of that commit. |
(ninja'd by @wlynch :)) This is an interesting proposal! A couple thoughts in no particular order:
|
Good idea to sign attestations about commits!
I agree. This does not seem like it generally scales. I'm also not sure what it really buys you. Maybe signing the release/tag should be sufficient? Also, what about the possibility to sign some/all sources files, not just commits? |
TL;DR: Create a provenance by traversing each commit. Attest into OCI registry. Verify all commits in attestation using cosign.
Abstract
This issue proposes introducing new
cosign.sigstore.dev/attestation/gitsign/v1
predicate type for using the in-toto/attestation model. Also proposes a new subcommand in gitsign itself:attestation generate
to generate an attestation file by traversing each commits.Motivation
While working on the Cosign VULN_SPEC proposal a few months ago, we learned a lot from the both sigstore and in-toto community members and valuable comments. And no doubt this proposal will be our next opportunity for new learnings for sure. Gitsign is a brand-new tool and very promising. So with @developer-guy, we thought that this proposal would be worth creating and discussing further here. So created this one, as far as we can do best.
Proposal
The main idea is to generate a provenance for the entire commit history for the repository in the container image build-time (to prevent a slight time window in which it could have tampered). And storing as an attestation format in the OCI registry. As a consumer of the container image, verifying gitsign attestation means that I verify the attestation itself and each commit that has been made by committers using their public key that is either fetched from Rekor (PKCS7 cert) or GPG verify (PGP cert).
By doing so; rather than saying "I trust this repository and binaries thus all artifacts are signed", the statement becomes "all commits that have made by commiters are signed & verified by either using gitsign and GPG, so I trust each commit. and also container image, binaries and artifacts already signed.".
And example use-case for verifying is to use cosign to verify attestation and also verify all the commits by using gitsign under the hood.
Whis proposal requires collaborate with gitsign and cosign together. Implement all of this, we would do add some commands:
For gitsign: introduce new
attestation generate
command:For cosign: introduce new
--gitsign true|false
flag:New
--gitsign
flag traverses each commits and verifies by running under the hood:The 30,000-foot view
Please note that this spec should be generic and open for extendibility. This is not intended to be specially built for just gitsign. Wnyone who wants to create their own git commit signing tool should be able to consume this. Here is how new
cosign.sigstore.dev/attestation/gitsign/v1
predicate looks like (draft - open for feedback):author.name: (required) name of the author
author.digest.sha1: (required) commit
signature.status: (required)
%G?
of a commitsignature.format: (optional) signed with? (gpg, gitsign, etc.)
signature.publiKey: (optional) certificate from ($ git cat-file commit HEAD)
rekor: (optional) (if keyless signed with gitsign)
rekor.signature.algorithm: (required) signature algorithm
rekor.signature.content: (required) Rekor.Body.HashedRekordObj.signature.content
rekor.signature.cert: (required) Rekor.Body.HashedRekordObj.signature.publicKey.content
rekor.digest.sha256: (required) Rekor.Body.HashedRekordObj.data.hash.value
issuer: (optional) (if keyless signed)
issuer.o: (required) organization
issuer.cn (required) commonName
Implementation
Define a new SLSA provenance predicate type either here in gitsign or in the in-toto repository.
We should add a new
attestation generate
command in gitsign:See git-log(1) page for more details about the
%G?
signature status.Pseudocode:
--gitsign
boolean flag incosign verify-attestation
:Cosign should first verify the attestation as is. If verification succeed, it should parse the
.att
to load allcosign.sigstore.dev/attestation/gitsign/v1
predicate type to struct definitions.The New
--gitsign
flag traverses each commit and verifies by running under the hood:Pseudocode:
End User Usage
Intended Users
User Story
This container image seems signed by a trusted author but still, I couldn't trust the source code because I don't know who contributed. There is always the possibility that committers could have impersonated someone else by using their name and email. What I want is to verify all the commits that include in the source code that makes up the final container image. So I can be sure that there is no unsigned commit. All commits have a signature and are verified.
Concerns
We should be careful here since our main goal here is to not just say "all commits are verified" but "all commits are verified and trusted". So we should not forget that.
Backward compatibility is another big issue for us. What if a repository started enforcing GPG after the 50th commit and switched to a brand-new gitsign tool after the 200th commit? How the whole concept will work here?
Would pass something
-n | --number <INTEGER>
flag togitsign attestation generate
tackle this problem? So we can only get commits after n th.Alternative Methods
Instead of generating an attestation and verifying, we can simply enforce signed commits only rule in the Git providers (GitHub, GitLab, etc.). So It would be easier to reject unsigned commits. E.g. server-side precommit hooks.
Similar to 1, instead of trusting the commits, we can trust the commit authors. By making an allowlist for the public keys that committers use, we can create restrictive policies to reject upcoming commits from the anonymous (i.e. open-source) contributors.
Related Proposals
What distinguishes our proposal from the following above is that we do not create attestation on each commit, but instead keep a single one. Also this proposal does NOT store anything in
refs
folder. We also want to verify everything as much as possible before using.Open Questions
rekor
object really necessary? How would it be if we just passUUID
instead?Waiting for your feedback!
cc @dlorenc @lukehinds @TomHennen @adityasaky @SantiagoTorres
The text was updated successfully, but these errors were encountered: