Code Monkey home page Code Monkey logo

gitsign's Introduction

sigstore framework

Fuzzing Status CII Best Practices

sigstore/sigstore contains common Sigstore code: that is, code shared by infrastructure (e.g., Fulcio and Rekor) and Go language clients (e.g., Cosign and Gitsign).

This library currently provides:

  • A signing interface (support for ecdsa, ed25519, rsa, DSSE (in-toto))
  • OpenID Connect fulcio client code

The following KMS systems are available:

  • AWS Key Management Service
  • Azure Key Vault
  • HashiCorp Vault
  • Google Cloud Platform Key Management Service

For example code, look at the relevant test code for each main code file.

Fuzzing

The fuzzing tests are within https://github.com/sigstore/sigstore/tree/main/test/fuzz

Security

Should you discover any security issues, please refer to sigstores security process

For container signing, you want cosign

gitsign's People

Contributors

adityasaky avatar bobcallaway avatar boolman avatar cpanato avatar dependabot[bot] avatar eddiezane avatar haydentherapper avatar iavael avatar imjasonh avatar jdolitsky avatar jku avatar k4leung4 avatar lukehinds avatar mwarkentin avatar nsmith5 avatar pdeslaur avatar sabre1041 avatar sallyom avatar sandipanpanda avatar stgarf avatar wlynch avatar y12studio avatar zchee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gitsign's Issues

Gitsign fails to validate commits after public instance migration

Description

There's upstream changes being made to the public sigstore instance, and it looks like it's affecting gitsign.

$ git commit --allow-empty --message="foo"
[foo e703bda] foo 

$ git verify-commit HEAD
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x101ef78f4]

goroutine 1 [running]:
main.verifyDetached()
        /Users/wlynch/go/pkg/mod/github.com/sigstore/[email protected]/command_verify.go:109 +0x4e4
main.commandVerify()
        /Users/wlynch/go/pkg/mod/github.com/sigstore/[email protected]/command_verify.go:25 +0x54
main.runCommand()
        /Users/wlynch/go/pkg/mod/github.com/sigstore/[email protected]/main.go:102 +0x60c
main.main()
        /Users/wlynch/go/pkg/mod/github.com/sigstore/[email protected]/main.go:47 +0x20

Version

v0.0.2-alpha

Gitsign doesn't support git config --global options

Description

From @mattmoor:

I did --global, does that not work?


My ~/.gitconfig has this at the end:
[gpg "x509"]
        program = gitsign
[gpg]
        format = x509
[commit]
        gpgsign = true
[gitsign]
        connectorID = https://accounts.google.com/
which looks right?

If I configure it in the local repo it works 

Root cause appears to be go-git/go-git#508 - we're losing the custom gitsign config options when the configs are merged. This would also affect options set with git config --system

Version

v0.3.0

Idea: gitsign attest

Description

This is an idea I've had rattling in my mind for awhile that I figured I'd finally write down. Not an original idea! see sigstore/cosign#865 for initial discussion.

It would be cool to add attestation support to Gitsign similar to cosign attest! i.e.

$ gitsign attest --predicate=<file> <revision>
$ gitsign verify-attestation <revision>

Primary use case would be to attach attestation information about the source / code review to the commit itself - who reviewed the change, what tests ran against it, etc (maybe also SBOMs, but unclear why you'd want that in an attestation rather than in the repo itself).

Predicate schema TBD. There are some ideas in https://github.com/in-toto/attestation/blob/77e31a3e4456de0594f0faf0ee5a1e65cfaf63d6/README.md#custom-type-examples that we can use to get started and would be a good place to work with the broader SLSA community to canonicalize.

We can generate the attestation using the same DSSE process we're using for cosign attest.

We can store the attestation in a way similar to a git note, though likely under a different ref refs/attestations. We probably can't use notes directly because IIUC notes expect 1 note per commit, where as we'll likely have many attestations per commit. It'll likely look something like:

refs/attestations/commits
`- <tree sha>
   |- <commit 1>
      |- attestation1.json
      `- attestation2.json
   `- <commit 2>
      `- attestation1.json

Things to work out / double check the behavior of:

  • How do multiple attestations work with cosign attest?
  • How do we distinguish multiple attestations? (use the digest as the filename? user provided key?)
  • Do we need a mechanism to delete an attestation?
  • Standardize some common predicate formats.
  • Should we have a way to identify predicate types? (i.e. code review vs tests)
  • Is storing all attestations under the a single ref like refs/attestations/commits okay, or should we store attestations in a ref per commit? (i.e. refs/attestations/<target commit sha>). Probably worth looping in someone more familiar with git internals to advise here.
    • there might be some interesting ACL things source providers could do if we isolate per SHA (i.e. only let CI running at the commit modify attestations for the same commit)
  • And probably more I'm not thinking of.

Let me know if you have any thoughts!

Incorrect Rekor ID for tags

Description

I think we're computing the wrong rekor ID / SHA value for signed tags. How we're doing this today is we're precomputing the SHA value based on the incoming body and the signature we produce.

For commits the final commit object looks like:

$ git cat-file commit HEAD
tree b333504b8cf3d9c314fed2cc242c5c38e89534a5
parent 2dc0ab59d7f0a7a62423bd181d9e2ab3adb7b56d
author Billy Lynch <[email protected]> 1656524971 -0400
committer Billy Lynch <[email protected]> 1656524971 -0400
gpgsig -----BEGIN SIGNED MESSAGE-----
 MIIEBwYJKoZIhvcNAQcCoIID+DCCA/QCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
 hvcNAQcBoIICqDCCAqQwggIqoAMCAQICFHtMvZZL50P5bLkgDxwMf2MN4jdAMAoG
 CCqGSM49BAMDMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2ln
 c3RvcmUtaW50ZXJtZWRpYXRlMB4XDTIyMDYyOTE3NDkzNFoXDTIyMDYyOTE3NTkz
 NFowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNf9io+JonCZhwe/dSkSoJ/Y
 eRun8C7xhPVF3FhoPnPVWdywaAEIkniA2WSHXLHt5aQN/08bV65haMZA/Luhmhaj
 ggFJMIIBRTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYD
 VR0OBBYEFGzhjCzFUI0caspJJfD4bToYxfDhMB8GA1UdIwQYMBaAFN/T6c9WJBGW
 +ajY6ShVosYuGGQ/MCIGA1UdEQEB/wQYMBaBFGJpbGx5QGNoYWluZ3VhcmQuZGV2
 MCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCB
 iwYKKwYBBAHWeQIEAgR9BHsAeQB3AAhgkvAoUv9oRdHRayeEnEVnGKwWPcM40m3m
 vCIGNm9yAAABgbCVKBkAAAQDAEgwRgIhAJHJalxdErw5icNqfgWtyrv75XGXxAZz
 F/J4b7B8ikQAAiEAj8g8ZiSIGmePmES19Y/yFeGj6Fz0NGE2Rk5uJdKyAGEwCgYI
 KoZIzj0EAwMDaAAwZQIxAKpQFL9D5s1YVEmNWBoEQ1oo6gBESGhd5L1Kcdq52Ltt
 KWXKKB7tpVRwC0lfof2ILgIwU1LTaKeKWb0vToMY9InoS2+hAVljbEh3oxKm/JoX
 hiRx2GiDe2OyLCs76/kbH6C/MYIBJTCCASECAQEwTzA3MRUwEwYDVQQKEwxzaWdz
 dG9yZS5kZXYxHjAcBgNVBAMTFXNpZ3N0b3JlLWludGVybWVkaWF0ZQIUe0y9lkvn
 Q/lsuSAPHAx/Yw3iN0AwCwYJYIZIAWUDBAIBoGkwGAYJKoZIhvcNAQkDMQsGCSqG
 SIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjIwNjI5MTc0OTM0WjAvBgkqhkiG9w0B
 CQQxIgQgSbThfvXoc6INDxPzRtlUu0TTBjFLm4XmwuxXAzfsZmkwCgYIKoZIzj0E
 AwIERzBFAiBeNZewVOFI5aa7bPUXa05HDgz5yevQ9aPclDX6U+koTAIhAMbyysil
 7I/UWLzhwM+9iusn3JXy71akUTcrqi2MNPaO
 -----END SIGNED MESSAGE-----

foo

but for tags this looks like:

$ git cat-file tag signed-tag
object 040b9af339e69d18848b7bbe05cb27ee42bb0161
type commit
tag signed-tag
tagger Billy Lynch <[email protected]> 1656525095 -0400

Signed tag
-----BEGIN SIGNED MESSAGE-----
MIIEBgYJKoZIhvcNAQcCoIID9zCCA/MCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
hvcNAQcBoIICpzCCAqMwggIpoAMCAQICFAh/hJ2AXyPGPHk7DoV0cZtNAixmMAoG
CCqGSM49BAMDMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2ln
c3RvcmUtaW50ZXJtZWRpYXRlMB4XDTIyMDYyOTE3NTE0NVoXDTIyMDYyOTE4MDE0
NVowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDZmQ6b/lJDC93Mkt+EJmt2Y
Wzn2cUU2Em2mclkuBOhlJxbI2tFkPST1XdFwmMNeNO8uRr0rOrfjHO0+Z1IDuhGj
ggFIMIIBRDAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYD
VR0OBBYEFIzo21kImebDCCgam8WnCIczP7K4MB8GA1UdIwQYMBaAFN/T6c9WJBGW
+ajY6ShVosYuGGQ/MCIGA1UdEQEB/wQYMBaBFGJpbGx5QGNoYWluZ3VhcmQuZGV2
MCwGCisGAQQBg78wAQEEHmh0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aDCB
igYKKwYBBAHWeQIEAgR8BHoAeAB2AAhgkvAoUv9oRdHRayeEnEVnGKwWPcM40m3m
vCIGNm9yAAABgbCXK9kAAAQDAEcwRQIgfeiJzAUTEw+xJIqLCca0qp6BEWtPDK2A
PP25vHhKiU0CIQDfksmqmKXODyppY5RUUupSjCov/zzEcWEXMwc3odSXyDAKBggq
hkjOPQQDAwNoADBlAjEAgOopk3t0XbtEv1CbcHKmvnxcckaPDREo5S7xgqNMAbdK
QOmNeX4w4gVjErYTsW7qAjACq5qa8QbtcnaEW9zUyENgr6HlwWn6KjmMy0Wfffkr
JOUkdvm1gxL5z5K5dLbtL7ExggElMIIBIQIBATBPMDcxFTATBgNVBAoTDHNpZ3N0
b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlAhQIf4SdgF8j
xjx5Ow6FdHGbTQIsZjALBglghkgBZQMEAgGgaTAYBgkqhkiG9w0BCQMxCwYJKoZI
hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMjA2MjkxNzUxNDZaMC8GCSqGSIb3DQEJ
BDEiBCBOeu3oQKkxhDK7WZlQ8zD2CTntr5NorUHNzxqCJXJq4jAKBggqhkjOPQQD
AgRHMEUCIAUScSkHWXgx0rA6eltI4d8TJh0Ac3VIkpps15a78GybAiEA/ODg7zMU
Armh8hgYbHyo1nG3hRMeQqvWjn7/89rAGNc=
-----END SIGNED MESSAGE-----

Currently we're assuming commits - which means for tags we're unmarshalling incorrect data -

gitsign/internal/git/git.go

Lines 131 to 135 in 7fb3656

func commitHash(data, sig []byte) (string, error) {
// Precompute commit hash to store in tlog
obj := &plumbing.MemoryObject{}
_, _ = obj.Write(data)
obj.SetType(plumbing.CommitObject)

I think this issue is low impact - we can still verify tags using git verify-tag because we can redo the same operation as was done for signing, and the Rekor IDs should be unique because they contain the cert. This doesn't have the same property as commits in that we can use the tag SHA to look up the Rekor entry.

Version

7fb3656

golang 1.17 version has the installation error.

Description

the golang version in go.md is go 1.17, however the installation will show the below error:

./main.go:95:26: info.Settings undefined (type *debug.BuildInfo has no field or method Settings)

the code is

	if *versionFlag {
		version := "unknown"
		info, ok := debug.ReadBuildInfo()
		if ok {
			for _, s := range info.Settings {
				if s.Key == "vcs.revision" {
					version = s.Value
				}
			}
		}
		fmt.Println(version)
		return nil
	}

For go 1.17 , the function debug.ReadBuildInfo() really do not have Settings method, but go 1.18 has:

type BuildInfo struct {
	GoVersion string         // Version of Go that produced this binary.
	Path      string         // The main package path
	Main      Module         // The module containing the main package
	Deps      []*Module      // Module dependencies
	Settings  []BuildSetting // Other information about the build.
}

So, should the version in go.mod will be changed to 1.18?

Release automation failing

Description

Release workflow is failing with

gitsign imports
	github.com/sigstore/gitsign imports
	github.com/pborman/getopt/v2: ambiguous import: found package github.com/pborman/getopt/v2 in multiple modules:
	github.com/pborman/getopt v0.0.0-20180811024354-2b5b3bfb099b (/home/runner/go/pkg/mod/github.com/pborman/[email protected]/v2)
	github.com/pborman/getopt/v2 v2.1.0 (/home/runner/go/pkg/mod/github.com/pborman/getopt/[email protected])

See e.g https://github.com/sigstore/gitsign/runs/6413949532?check_suite_focus=true#step:7:362

Not sure whats up with this. Thought it was go1.17 versus 1.18 related but that didn't seem to fix the issue

Remove cosign dependency

Description

Generally tracking issue for removing the dependency on cosign to reduce the dependency sprawl. Ideally all shared code should be moved to sigstore/sigstore if possible.

Support users who SSH into a remote server

SSHing into a remote machine to develop is a fairly common workflow.

ssh me.corp.biz
git init # and setup gitsign
echo foo > README
git commit -am "just fooing"

Unfortunately the UX in this case is somewhat suboptimal, though it has improved greatly. Instead of popping up a browser window like it would if you were git commiting locally, this prints a URL and asks you to open in a browser you have access to, whereupon you OAuth, and copy a code back to the waiting gitsign prompt to continue.

This isn't bad (and again, it's much improved!), but it means quite a few more manual steps for each commit: copy/paste URL, the usual OAuth, copy/paste auth code.

To make this easier, it could be cool to provide a local agent that connects to the remote agent over SSH, and listens for browser-open requests, then opens a (local) browser window, gets the token, then sends it back over that same connection to the remote gitsign instance, where it's exchanged for a cert. Or, maybe, the local agent trades the token for the cert and passes only the cert, I don't know.

In any case, I think most of this code already exists in some form already, between gitsign and the cred cache, it's just about packaging it differently, and configuring the handoffs between the local agent and the remote gitsign, without sacrificing security.

Verification panics if summary is nil

Description

Reported in slack: https://sigstore.slack.com/archives/C03ETLNSA3Z/p1652941032953469?thread_ts=1652940129.504849&cid=C03ETLNSA3Z

gitsign/command_verify.go

Lines 123 to 126 in 20e9e75

summary, err := git.Verify(context.Background(), buf.Bytes(), sig.Bytes())
if err != nil {
if summary.Cert != nil {
emitBadSig(summary.Cert)

If we return a nil VerificationSummary (i.e. return nil, err), the summary.Cert access will nil panic. We should add a check to only check the cert iff the summary is present.

Out of band auth flow not working

Description

The auth process in gitsign outputs a URL you should be able to open in the browser to get a verification code, but the oauth2 server redirects to localhost after logging in. In this case localhost is not accessible so the auth flow cannot complete.

$ git commit -m "foo"
error opening browser: exit status 3
Go to the following link in a browser:

         https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=P69wZPuonUkCS2-LAp26XO-Ndw3GzeyATyuixsMRz7c&code_challenge_method=S256&nonce=xxx&redirect_uri=http%3A%2F%2Flocalhost%3A45077%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=xxx
Enter verification code:

Version

gitsign v0.2.0

OAuth device flow support

Description

Credit to @philpennock for this idea! We should be able to write directly to /dev/tty to get around the "git eats stdout/stderr" restriction and prompt for device flow. I've already verified a simple print gets through using https://pkg.go.dev/github.com/mattn/go-tty - so we need to:

  1. Refactor the code to plumb the TTY writer through to the device flow
  2. Figure out a way to distinguish browser capable vs terminal only sessions.

For 2 - we can't follow what cosign does here since all invocations of the tool will trip the device flow since the tool is being wrapped by Git.

https://github.com/sigstore/cosign/blob/2e00e8a341ac3a447a8078147db941bd01c4d03c/cmd/cosign/cli/fulcio/fulcio.go#L140-L151

I was thinking maybe we just try opening the browser and if it fails, fall back to device flow? I'm just worried we might hit weird edge cases where a terminal based browser may try and open though. Open to ideas here!

Verify: require cert to match committer?

This could be a disruptive change to users, so looking for feedback before we commit to this - should we require by default that the cert contained in the git commit match the email of the git committer?

Right now we just check for a valid signature, and users would need to add additional checks to verify the identity matches.

This would be in line with Sigstore clients should require a provided identity by @haydentherapper and @znewman01, since we don't have an easy way to pass additional params via git verify-commit or git log. This also means we don't have a good way to specify the OIDC provider or Sigstore instance, so we may need additional out of band config (i.e. envvar / #99) for this to be complete.

#65 may be a hard requirement here, since otherwise we won't be able to generate privacy preserving certs. We could also provide an option to disable this behavior (though prefer not to do this if possible).

Thoughts? cc @imjasonh @nsmith5

WSL can't be reach by redirect URL

I'm using WSL on windows (Don't judge me!!!!) And when running gitsign, it tries to reach back on localhost but this doesn't work.

I think just a way to bind the callback server to 0.0.0.0 instead of 127.0.0.1 would work? I'd be glad to test whatever solution comes out!

Version

gitsign version v0.2.0

Exposes private email address from GitHub

Description

When authenticating with GitHub, gitsign appears to retrieve a users private email address and insert that address into the commit being signed. It does this, even if a user has configured their GitHub account to keep their email address private, and even if the user has configured their GitHub account to reject commits that contain their private email.

It's unclear why gitsign needs to expose a users primary email address configured in GitHub. It could instead expose the GitHub username, or the GitHub user id email address, which in my case is [email protected].

It would be better privacy, and less surprising, if gitsign didn't pull information like email addresses into the commit.

For example, this is the commit created by using GitHub as the auth, where the asterisks are my private email address:

commit 10bde749ceef2544aab0c6d8d73db66e079307f0
tlog index: 2619545
smimesign: Signature made using certificate ID 0xad76a5fc3b3318f5d356e899c6b57f4fcea6aa24 | CN=sigstore-int
smimesign: Good signature from [********************]
Parsed Git signature: true
Validated Git signature: true
Located Rekor entry: true
Validated Rekor entry: true
Author:     Leigh McCulloch <[email protected]>
AuthorDate: Thu Jun 9 16:25:37 2022 -0700
Commit:     Leigh McCulloch <[email protected]>
CommitDate: Thu Jun 9 16:25:37 2022 -0700

Version

❯ gitsign --version
unknown

When I install gitsign using go install it installed from the v0.1.0 tag.

Keyless signature are invalid for linux/amd64 since v0.1.0

Description

I am trying to verify my installation of gitsign using the keyless signature. Unfortunately, all signatures since v0.1.0 (all non-prerelease versions) fail to verify because the commit SHA in the signature does not match commit SHA of the release tag.

Am I doing something wrong? The same approach works successfully for cosign and rekor.

I have used the following snippets to reproduce this:

  1. Choose version to verify:

    VERSION=0.4.1
  2. Download release binaries for gitsign on linux/amd64:

    for EXT in "" .pem .sig; do
        curl -sLfO https://github.com/sigstore/gitsign/releases/download/v${VERSION}/gitsign_${VERSION}_linux_amd64${EXT}
    done
    
  3. Fetch commit sha of release tag:

    SHA="$(git ls-remote https://github.com/sigstore/gitsign refs/tags/v${VERSION} | cut -f1)"
    echo "Git SHA for tag v${VERSION}: ${SHA}"
  4. Verify signature:

    COSIGN_EXPERIMENTAL=1 cosign verify-blob gitsign_${VERSION}_linux_amd64 \
        --certificate gitsign_${VERSION}_linux_amd64.pem \
        --signature gitsign_${VERSION}_linux_amd64.sig \
        --certificate-oidc-issuer https://token.actions.githubusercontent.com \
        --certificate-identity "https://github.com/sigstore/gitsign/.github/workflows/release.yml@refs/tags/v${VERSION}" \
        --certificate-github-workflow-name release \
        --certificate-github-workflow-ref "refs/tags/v${VERSION}" \
        --certificate-github-workflow-repository "sigstore/gitsign" \
        --certificate-github-workflow-sha "${SHA}" \
        --certificate-github-workflow-trigger push

    This fails with the following message:

    Error: verifying blob [gitsign_0.4.1_linux_amd64]: validating certRef: expected GitHub Workflow SHA not found in certificate
    main.go:62: error during command execution: verifying blob [gitsign_0.4.1_linux_amd64]: validating certRef: expected GitHub Workflow SHA not found in certificate
    
  5. Fetch commit SHA in signature:

    curl -sLf https://github.com/sigstore/gitsign/releases/download/v${VERSION}/checksums.txt \
    | grep gitsign_ | grep "linux_amd64$" | cut -d' ' -f1 \
    | xargs rekor-cli search --sha \
    | xargs -I{} rekor-cli get --uuid {} --format json \
    | jq -r '.Body.HashedRekordObj.signature.publicKey.content' \
    | base64 -d \
    | openssl x509 -noout -text

Version

First version: 0.1.0
Last version: 0.4.1

More versions:

$ cosign version
  ______   ______        _______. __    _______ .__   __.
 /      | /  __  \      /       ||  |  /  _____||  \ |  |
|  ,----'|  |  |  |    |   (----`|  | |  |  __  |   \|  |
|  |     |  |  |  |     \   \    |  | |  | |_ | |  . `  |
|  `----.|  `--'  | .----)   |   |  | |  |__| | |  |\   |
 \______| \______/  |_______/    |__|  \______| |__| \__|
cosign: A tool for Container Signing, Verification and Storage in an OCI registry.

GitVersion:    v1.13.1
GitCommit:     d1c6336475b4be26bb7fb52d97f56ea0a1767f9f
GitTreeState:  clean
BuildDate:     2022-10-17T18:00:05Z
GoVersion:     go1.19.2
Compiler:      gc
Platform:      linux/amd64

$ rekor-cli version
  ____    _____   _  __   ___    ____             ____   _       ___
 |  _ \  | ____| | |/ /  / _ \  |  _ \           / ___| | |     |_ _|
 | |_) | |  _|   | ' /  | | | | | |_) |  _____  | |     | |      | |
 |  _ <  | |___  | . \  | |_| | |  _ <  |_____| | |___  | |___   | |
 |_| \_\ |_____| |_|\_\  \___/  |_| \_\          \____| |_____| |___|
rekor-cli: Rekor CLI

GitVersion:    v1.0.1
GitCommit:     d3162350e96098ca8a24adfdbee42057e43b5de6
GitTreeState:  clean
BuildDate:     2022-11-10T15:26:56Z
GoVersion:     go1.19.3
Compiler:      gc
Platform:      linux/amd64

gitsign timestamp cert verification broken

Description

My fault for not catching this pre-submission, but looks like timestamp verification doesn't work if the timestamp cert isn't included in the fulcio root pool. We'll need to modify the CertPool loading to include the system root.

Version

175234a

Version command returns "unknown"

Description

When running gitsign -v or gitsign --version, this is what I'm getting:

unknown

Context: I am updating the Sigstore docs website to include a section for Gitsign. I would like to use this command within the documentation to verify that the installation was successful (and confirm it is in the $PATH since I had some issues with my Go installation).

Version

Using version 0.1.0

gitsign bot

Throw DCO bot in the toilet and take over things with gitsign bot.

In all seriousness, a bot that checks commits are signed, or fails CI.

Cylance MaxSecure flagging gitsign_0.1.1_windows_amd64.exe as a trojan

Description

Cylance Max Secure is flagging the 64bit gitsign executable as a potential trojan. (Trojan.Malware.300983.susgen)

A quick google search has shown that unfortunately this is somewhat common with golang if you pack/unpack DLLs into the exe on Windows. However I can't verify that gitsign, or any it's dependencies, do this.

Other virus scanners have not detected anything. So I'm somewhat sure it's a false positive in this case.

I'm raising an issue mainly for awareness that other Windows users may encounter this too.

Ref - https://www.virustotal.com/gui/file/0f026879fae8a7cc503f7829a885ffc14b9d6ae4d52b9086c5ba05b9ca9e1343/detection

When rebasing, and a wrong chrome window gets the request, no easy (if any?) way to recover.

Description
I have multiple chrome windows open, one for my work, one for personal, and one for say Knative.

When I started to rebase a project that's wired up to use gitsign, it spun up the request to authenticate on one of the wrong windows, which will not work. Usually with other things that require auth, it prints the URL so if a wrong chrome window is spun up, I can cut & paste the URL to the correct window but with gitsign, I don't know how to do that so hit ctrl-c which seems to cause hilarity.

vaikas@villes-mbp someproject % git rebase -ff upstream/main
^Cbasing (1/4)
vaikas@villes-mbp someproject % git rebase -ff upstream/main
fatal: It seems that there is already a rebase-merge directory, and
I wonder if you are in the middle of another rebase.  If that is the
case, please try
	git rebase (--continue | --abort | --skip)
If that is not the case, please
	rm -fr ".git/rebase-merge"
and run me again.  I am stopping in case you still have something
valuable there.

So, I wonder if it would be useful to print the url where it's trying to use for auth so in case like this I could cut&paste to right chrome window.

Version
vaikas@villes-mbp someproject % gitsign --version
unknown

`gitsign --version` runs only inside a git repository

Description
I have followed the installation guide here and installed gitsign on my Macbook. The next step in the guide checking the installation recommends to run gitsign --version to check the installation. If I do that from a random directory, the command fails with an error message repository does not exist.

Steps to reproduce
Precondition: The environment already has gitsign installed.

  • Create a new directory and change to it cd $(mktemp -d)
  • Run gitsign --version
  • You'll get an error 'repository does not exist'

Expected behaviour as per the docs : Gitsign prints out version number.

Version
v0.3.1

Additional Information

  • If I initialize a git repo(git init) in the newly created temp directory and runs gitsign --version I do get the expected output
  • If I change to an existing git repo on the disk, I get the expected output
  • When using --version and --help switches, I think it is to much to demand that the end user needs to do that in a git repo
  • It could trip new users

`gitsign --version` shows `unknown`

Hi,

I just started to play a bit with gitsign to start packaging it for nixpkgs and I noticed that when using the binaries in the release assets the version was not set:

$ ./gitsign_0.0.2-alpha_linux_amd64 --version
unknown

I did not check the build pipeline but since it relies on VCS information retrieved from the debug/buildinfo I am guessing it will not play well with 107ac24 anyway.

gitsign/main.go

Lines 76 to 88 in 107ac24

if *versionFlag {
version := "unknown"
info, ok := debug.ReadBuildInfo()
if ok {
for _, s := range info.Settings {
if s.Key == "vcs.revision" {
version = s.Value
}
}
}
fmt.Println(version)
return nil
}

Easier credential caching

I've started using this recently and need to login to GitHub each time i try to push something to the origin using GitHub's desktop application which gets annoying when dealing with multiple PRs/repos. Is there a way cache or store the login creds for a time period instead?

GITSIGN_REKOR_URL not respected

Description

Reported in slack: https://sigstore.slack.com/archives/C03ETLNSA3Z/p1652940129504849

rekor, err := rekor.New(rekorDefaultURL)
if err != nil {
return nil, nil, errors.Wrap(err, "error creating rekor client")
}

gitsign/internal/git/git.go

Lines 147 to 150 in 20e9e75

rekor, err := rekor.New("https://rekor.sigstore.dev")
if err != nil {
return nil, err
}

We're using rekorDefaultURL which always points to the public rekor instance. This should be respecting the GITSIGN_REKOR_URL environment variable.

Related, we should check if the current usage of GITSIGN_REKOR_URL is actually doing anything 🤔 (and if not, remove)

RekorURL: envOrValue("GITSIGN_REKOR_URL", "https://rekor.sigstore.dev"),

Batch signing support

Description

This is probably a broader sigstore feature request, but creating an issue here to track.

An annoyance with using gitsign today is you need to hop through the oauth flow for every commit - this can be very tedious for quick git commit --amends or multi-commit rebases.

We'll want to look into some way to cache the signing keypair (or possibly the Fulcio OIDC token) to support multiple operations for the lifetime of the keypair (~10 mins) without needing to hop through the flow again and get a new key. This key shouldn't hit disk.

https://git-scm.com/docs/git-credential-cache strikes me as something similar to model off of for ideas.

Related discussion: https://sigstore.slack.com/archives/C01PZKDL4DP/p1652208232815029

Offline Verification

Description

It would be good to modify gitsign to be able to support offline verification.

  1. Remove need for clients to reach out to Rekor if they have the full inclusion proof.
  2. Get gitsign off of non-GA Rekor APIs

Plan is to include the Rekor log entry fields as ASN.1 unauthenticated attributes in the PKCS7 object. This will also allow us to store the log index / uuid in the commit itself.

Select auth provider with config

Probably dependent on #99, but something that would be nice is if we had a way for users to pre-select the auth provider they want to use for a repo.

Currently we use the default interactive provider, but if we had a per-repo config, then we could have an option to specify the TokenGetter to use https://github.com/sigstore/sigstore/blob/2ec832bbea880d6fb3f7b0b7cdfaffde490c571e/pkg/oauthflow/flow.go#L68-L73

Would still require a browser window to go through the oauth flow, but would save a click if you already knew what you wanted to use.

tuf: warning using deprecated ecdsa hex-encoded keys

Description

git verify-commit is outputting a warning:

$ git verify-commit head
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
tuf: warning using deprecated ecdsa hex-encoded keys
...

A similar bug hit cosign, so we likely need to make a similar change:

https://sigstore.slack.com/archives/C01PZKDL4DP/p1663249878057829
sigstore/cosign#2256

Version

This was introduced in some version > 0.3.0 (probably in a dependabot update to update cosign/rekor)

File based configuration

Description

It would be great to wire up viper or something similar to have file based configuration for gitsign (i.e. ~/.gitsign) rather than needing to export a bunch of environment variables.

Is GitLab supported

Much of the documentation and existing issues focus on GitHub but GitLab is a pretty major player as well. What, if any, work is needed for GitLab? Can it be configured to accept GitSign ephemeral certs? What limitations are there to doing this? Is this just browser based or can sn IDE like VS Cose be used?

Idea: KMS support

Description

If the user.signingKey git config option is set, this value will be set as an argument to gitsign:

user.signingKey Value gitsign args
gitsign --status-fd=2 -bsau Billy Lynch <[email protected]>
asdf gitsign --status-fd=2 -bsau asdf

We could use this to emulate the cosign --key flag and support KMS keys!
This could also support local keys, but IMO this is a less compelling use case since smimesign should be able to handle this already unless all you want is the local key to be uploaded to Rekor.

feat: make container image of gitsign

Description

Will you make a container image of gitsign with practices that you are using for other sigstore projects such as using ko or another tool, I'm willing to do this.

cc: @cpanato

proposal: provenance generation and verifying attestation using cosign with new predicate type

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:

$ gitsign attestation generate

For cosign: introduce new --gitsign true|false flag:

$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation \
    --type cosign.sigstore.dev/attestation/gitsign/v1 \
    --gitsign \
    foo/bar:baz

New --gitsign flag traverses each commits and verifies by running under the hood:

$ cosign verify-blob \
  --cert commits[*].rekor.signature.publicKey \
  --signature commits[*].rekor.signature.content \
  commits[*].author.digest.sha1

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

{
    "_type": "https://in-toto.io/Statement/v0.1",
    "subject": [],
    "predicateType": "cosign.sigstore.dev/attestation/gitsign/v1",
    "predicate": {
        "invocation": {
            "fulcio_url": "https://fulcio.sigstore.dev",
            "rekor_url": "https://rekor.sigstore.dev",
            "oidc": {
                "client_id": "sigstore",
                "issuer": "https://oauth2.sigstore.dev/auth",
                "redirect_url": ""
            },
            "timestamp": 1627564731
        },
        "commits": [
            {
                "issuer": {
                    "o": "sigstore.dev",
                    "cn": "sigstore-intermediate"
                },
                "signature": {
                    "status": "G",
                    "format": "pkcs7",
                    "publicKey":"base64-encoded-pkcs7-cert"
                },
                "rekor": {
                    "signature": {
                        "algorithm": "ecdsa-with-SHA256",
                        "content": "MEYCIQC1gffaJyVGfmJNoX94n9vOj+1EKEAlolT9UH7Bb2MuwwIhAJ1FFee9bDQdLbjt4yjbYz5Ojd3uITilNU4KLGJqiSQr",
                        "cert": "base64-encoded-cert"
                    },
                    "digest": {
                        "sha256": "d00bf6f1a50835a372b137ea18306d6a1d554500caf821e375817173db760868"
                    }
                },
                "author": {
                    "name": "[email protected]",                 
                    "digest": {
                        "sha1": "6a2b1f12938059f2fbe68754657fad33a4fca372"
                    }
                }
            },
            {
                "signature": {
                    "status": "G",
                    "format": "pgp",
                    "publicKey": "base64-encoded-pgp-cert"
                },
                "author": {
                    "name": "[email protected]",
                    "digest": {
                        "sha1": "5ee8eca4f05ef4b79eb6dc21c09198d4d61e3495"
                    }
                }
            },
            {
                "signature": {
                    "status": "N"
                },
                "author": {
                    "name": "[email protected]",
                    "digest": {
                        "sha1": "adba2b44bd04f8f2c92fbf739af797b8dcd046b5"
                    }
                }
            }
        ]
    }
}
  • author.name: (required) name of the author

  • author.digest.sha1: (required) commit

  • signature.status: (required) %G? of a commit

  • signature.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

  1. Define a new SLSA provenance predicate type either here in gitsign or in the in-toto repository.

  2. We should add a new attestation generate command in gitsign:

$ gitsign attestation generate -o gitsign.json

See git-log(1) page for more details about the %G? signature status.

Pseudocode:

loop through each commits
  check %G? for each commit
    if commit no signed: // <sig>N</sig>
      set signature.status = N
    if commit signed with GPG: // <sig>G</sig>
      set signature.status = G
      set signature.format = GPG
      set signature.publicKey = base64-encoded-pgp-cert
    if commit signed with gitsign:
      search on Rekor: rekor-cli search --artifact <COMMIT>
        get certificate: $(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.publicKey.content)
        get signature: $(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.content)
        get issuer from the cert
        get necessary rekor obj values from rekor API
        append issuer and rekor objects
    append author object
  1. Introduce a new --gitsign boolean flag in cosign verify-attestation:
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation \
    --type cosign.sigstore.dev/attestation/gitsign/v1 \
    --gitsign \
    foo/bar:baz

Cosign should first verify the attestation as is. If verification succeed, it should parse the .att to load all cosign.sigstore.dev/attestation/gitsign/v1 predicate type to struct definitions.

The New --gitsign flag traverses each commit and verifies by running under the hood:

$ cosign verify-blob \
  --cert commits[*].rekor.signature.publicKey \
  --signature commits[*].rekor.signature.content \
  commits[*].author.digest.sha1

Pseudocode:

loop through each commits
  verify the attestation
    if verification fails
      exit
    if verification succeed
      parse predicate to structs
        traverse in commits[*]
          if commit signed with gitsign
            run $ cosign verify-blob --cert .rekor.signature.publicKey --signature .rekor.signature.content .author.digest.sha1
          if commit signed with gpg
            run $ git verify-commit .author.digest.sha1 (in cosign)
          if commit unsigned
            exit
          if one of verification fails exit

End User Usage

  1. Generates a provenance:
$ gitsign attestation generate -o gitsign.json
  1. Attests and push to OCI:
$ COSIGN_EXPERIMENTAL=1 cosign attest \
    --type cosign.sigstore.dev/attestation/gitsign/v1 \
    --predicate gitsign.json \
    foo/bar:baz
  1. Verifies the attestation:
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation \
    --type cosign.sigstore.dev/attestation/gitsign/v1 \
    --gitsign \
    foo/bar:baz

Intended Users

  • container image builders
  • pipelines
  • end 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

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

  2. 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 to gitsign attestation generate tackle this problem? So we can only get commits after n th.

Alternative Methods

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

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

  1. XREF: #94 by @wlynch

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

  1. Does this all make sense overall?
  2. Are all fields in rekor object really necessary? How would it be if we just pass UUID instead?
  3. Should we verify each commit in history that made up the container image? (before running the container image)
  4. Instead of generating the attestation that only has one signature, shouldn't each commiter sign the same attestation with their PK or keyless somehow?
  5. Should we sign all commits individually?
  6. Should we store the final attestation in a version controlled in the repository itself? (i.e. in ref/, so anyone can verify all commits using gitsign itself either)
  7. Does this proposal uses Zero Trust ("trust nothing, verify everything") principles?

Waiting for your feedback!

cc @dlorenc @lukehinds @TomHennen @adityasaky @SantiagoTorres

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.