Skip to content

Commit

Permalink
Verify a signature using secrets from a gitlab project (#934)
Browse files Browse the repository at this point in the history
* feat: support verify using gitlab secrets

Signed-off-by: hectorj2f <[email protected]>

* docs: add verify changes for gitlab

Signed-off-by: hectorj2f <[email protected]>
  • Loading branch information
Hector Fernandez authored Oct 22, 2021
1 parent 9e304d1 commit 9f80297
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 3 deletions.
24 changes: 21 additions & 3 deletions cmd/cosign/cli/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ against the transparency log.`,
cosign verify --key hashivault://[KEY] <IMAGE>
# verify image with public key stored in a Kubernetes secret
cosign verify --key k8s://[NAMESPACE]/[KEY] <IMAGE>`,
cosign verify --key k8s://[NAMESPACE]/[KEY] <IMAGE>
# verify image with public key stored in GitLab with project name
cosign verify --key gitlab://[OWNER]/[PROJECT_NAME] <IMAGE>
# verify image with public key stored in GitLab with project id
cosign verify --key gitlab://[PROJECT_ID] <IMAGE>`,

Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -119,7 +125,13 @@ against the transparency log.`,
cosign verify-attestation --key gcpkms://projects/<PROJECT>/locations/global/keyRings/<KEYRING>/cryptoKeys/<KEY> <IMAGE>
# verify image with public key stored in Hashicorp Vault
cosign verify-attestation --key hashivault:///<KEY> <IMAGE>`,
cosign verify-attestation --key hashivault:///<KEY> <IMAGE>
# verify image with public key stored in GitLab with project name
cosign verify-attestation --key gitlab://[OWNER]/[PROJECT_NAME] <IMAGE>
# verify image with public key stored in GitLab with project id
cosign verify-attestation --key gitlab://[PROJECT_ID] <IMAGE>`,

Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -182,7 +194,13 @@ The blob may be specified as a path to a file or - for stdin.`,
cosign verify-blob --key gcpkms://projects/[PROJECT ID]/locations/[LOCATION]/keyRings/[KEYRING]/cryptoKeys/[KEY] --signature $sig <blob>
# Verify a signature against Hashicorp Vault
cosign verify-blob --key hashivault://[KEY] --signature $sig <blob>`,
cosign verify-blob --key hashivault://[KEY] --signature $sig <blob>
# Verify a signature against GitLab with project name
cosign verify-blob --key gitlab://[OWNER]/[PROJECT_NAME] --signature $sig <blob>
# Verify a signature against GitLab with project id
cosign verify-blob --key gitlab://[PROJECT_ID] --signature $sig <blob>`,

Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
6 changes: 6 additions & 0 deletions doc/cosign_verify-attestation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions doc/cosign_verify-blob.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions doc/cosign_verify.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/cosign/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ var providerMap = map[string]Git{

type Git interface {
PutSecret(ctx context.Context, ref string, pf cosign.PassFunc) error
GetSecret(ctx context.Context, ref string) (string, error)
}

func GetProvider(provider string) Git {
Expand Down
5 changes: 5 additions & 0 deletions pkg/cosign/git/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,8 @@ func (g *Gh) PutSecret(ctx context.Context, ref string, pf cosign.PassFunc) erro

return nil
}

// NOTE: GetSecret is not implemented for GitHub
func (g *Gh) GetSecret(ctx context.Context, ref string) (string, error) {
return "", nil
}
36 changes: 36 additions & 0 deletions pkg/cosign/git/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,39 @@ func (g *Gl) PutSecret(ctx context.Context, ref string, pf cosign.PassFunc) erro

return nil
}

func (g *Gl) GetSecret(ctx context.Context, ref string) (string, error) {
token, tokenExists := os.LookupEnv("GITLAB_TOKEN")
var varPubKeyValue string
if !tokenExists {
return varPubKeyValue, errors.New("could not find \"GITLAB_TOKEN\"")
}

var client *gitlab.Client
var err error
if url, baseURLExists := os.LookupEnv("GITLAB_HOST"); baseURLExists {
client, err = gitlab.NewClient(token, gitlab.WithBaseURL(url))
if err != nil {
return varPubKeyValue, errors.Wrap(err, "could not create GitLab client")
}
} else {
client, err = gitlab.NewClient(token)
if err != nil {
return varPubKeyValue, errors.Wrap(err, "could not create GitLab client")
}
}

varPubKey, pubKeyResp, err := client.ProjectVariables.GetVariable(ref, "COSIGN_PUBLIC_KEY")
if err != nil {
return varPubKeyValue, errors.Wrap(err, "could not retrieve \"COSIGN_PUBLIC_KEY\" variable")
}

varPubKeyValue = varPubKey.Value

if pubKeyResp.StatusCode < 200 && pubKeyResp.StatusCode >= 300 {
bodyBytes, _ := io.ReadAll(pubKeyResp.Body)
return varPubKeyValue, errors.Errorf("%s", bodyBytes)
}

return varPubKeyValue, nil
}
21 changes: 21 additions & 0 deletions pkg/signature/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (

"github.com/sigstore/cosign/pkg/blob"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/cosign/pkg/cosign/git"
"github.com/sigstore/cosign/pkg/cosign/git/gitlab"
"github.com/sigstore/cosign/pkg/cosign/kubernetes"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature"
Expand Down Expand Up @@ -110,6 +112,25 @@ func PublicKeyFromKeyRef(ctx context.Context, keyRef string) (signature.Verifier
}
}

if strings.HasPrefix(keyRef, gitlab.ReferenceScheme) {
split := strings.Split(keyRef, "://")

if len(split) < 2 {
return nil, errors.New("could not parse scheme, use <scheme>://<ref> format")
}

provider, targetRef := split[0], split[1]

keyValue, err := git.GetProvider(provider).GetSecret(ctx, targetRef)
if err != nil {
return nil, err
}

if len(keyValue) > 0 {
return loadPublicKey([]byte(keyValue))
}
}

return LoadPublicKey(ctx, keyRef)
}

Expand Down

0 comments on commit 9f80297

Please sign in to comment.