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

cosign generate-key-pair github://my-org/my-repo does not store the secrets accordingly in github #1431

Closed
marcofranssen opened this issue Feb 9, 2022 · 4 comments · Fixed by #1990
Assignees
Labels
bug Something isn't working

Comments

@marcofranssen
Copy link
Contributor

marcofranssen commented Feb 9, 2022

Description

When generating a keypair like this the keys are not accordingly set in the GitHub secrets.

export GITHUB_TOKEN=my_token
$ cosign cosign generate-key-pair github://my-org/my-repo
Private key written to COSIGN_PASSWORD environment variable
Private key written to COSIGN_PRIVATE_KEY environment variable
Public key written to COSIGN_PUBLIC_KEY environment variable
Public key also written to cosign.pub

This is tested with following workflow.

      - uses: sigstore/cosign-installer@main
        with:
          cosign-release: 'v1.5.1'

      - name: Cosign sign image
        env:
          COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
        run: |
          echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key
          cosign sign --key cosign.key ghcr.io/my-org/hello-world:latest

This workflow results in printing the following in the logs.

echo '' > cosign.key
  cosign sign --key cosign.key ghcr.io/my-org/hello-world:latest
  shell: /usr/bin/bash -e {0}
  env:
    COSIGN_PASSWORD: 
an error occurred: no provider found for that key reference, will try to load key from disk...

⚠️ NOTE the empty echo statement in the first log line. as well the empty COSIGN_PASSWORD environment variable.

Also when trying to echo the generated keypairs from the shell where I ran the command generate-keypair it seems the environment variables are not set.

env | grep COSIGN_
echo $COSIGN_PUBLIC_KEY
echo $COSIGN_PRIVATE_KEY
echo $COSIGN_PASSWORD

However when generating key as following does show there is a secret.

cosign generate-key-pair

Then I simply update the secrets in Github by copy pasting the file contents.

When I run the workflow now it shows as following in the logs.

echo '***
  ***
  ***
  ***
  ***
  ***
  ***
  ***
  ***
  ***
  ***
  ' > cosign.key
  cosign sign --key cosign.key ghcr.io/my-org/hello-world:latest
  shell: /usr/bin/bash -e {0}
  env:
    COSIGN_PASSWORD: ***
an error occurred: no provider found for that key reference, will try to load key from disk...

⚠️ Now the secrets are injected (redacted by Github). Both for the echo statement as well the env COSIGN_PASSWORD.

This might be caused by the version bump of the github package a while ago.

@marcofranssen marcofranssen added the bug Something isn't working label Feb 9, 2022
@marcofranssen marcofranssen changed the title cosign cosign generate-key-pair github://my-org/my-repo does not store the secrets accordingly in github cosign generate-key-pair github://my-org/my-repo does not store the secrets accordingly in github Feb 10, 2022
@n3wt0n
Copy link

n3wt0n commented Feb 16, 2022

I'm experiencing the same problem, with

n3wt0n@DESKTOP-NAIAR9O:~$ ./cosign version

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

GitVersion:    v1.5.1
GitCommit:     c3e4d8b7cd2f6f065941510b260f173b70c695fa
GitTreeState:  clean
BuildDate:     '2022-01-30T20:05:28Z'
GoVersion:     go1.17.6
Compiler:      gc
Platform:      linux/amd64

@chipzoller
Copy link

This is (surprisingly) still an issue with Cosign 1.9.

@znewman01
Copy link
Contributor

Relevant code here:

func (g *Gh) PutSecret(ctx context.Context, ref string, pf cosign.PassFunc) error {
keys, err := cosign.GenerateKeyPair(pf)
if err != nil {
return fmt.Errorf("generating key pair: %w", err)
}
var httpClient *http.Client
if token, ok := os.LookupEnv("GITHUB_TOKEN"); ok {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: token},
)
httpClient = oauth2.NewClient(ctx, ts)
} else {
return errors.New("could not find \"GITHUB_TOKEN\" env variable")
}
client := github.NewClient(httpClient)
split := strings.Split(ref, "/")
if len(split) < 2 {
return errors.New("could not parse scheme, use github://<owner>/<repo> format")
}
owner, repo := split[0], split[1]
key, getRepoPubKeyResp, err := client.Actions.GetRepoPublicKey(ctx, owner, repo)
if err != nil {
return fmt.Errorf("could not get repository public key: %w", err)
}
if getRepoPubKeyResp.StatusCode < 200 && getRepoPubKeyResp.StatusCode >= 300 {
bodyBytes, _ := io.ReadAll(getRepoPubKeyResp.Body)
return fmt.Errorf("%s", bodyBytes)
}
passwordSecretEnv := &github.EncryptedSecret{
Name: "COSIGN_PASSWORD",
KeyID: key.GetKeyID(),
EncryptedValue: base64.StdEncoding.EncodeToString(keys.Password()),
}
passwordSecretEnvResp, err := client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, passwordSecretEnv)
if err != nil {
return fmt.Errorf("could not create \"COSIGN_PASSWORD\" github actions secret: %w", err)
}
if passwordSecretEnvResp.StatusCode < 200 && passwordSecretEnvResp.StatusCode >= 300 {
bodyBytes, _ := io.ReadAll(passwordSecretEnvResp.Body)
return fmt.Errorf("%s", bodyBytes)
}
fmt.Fprintln(os.Stderr, "Password written to COSIGN_PASSWORD github actions secret")
privateKeySecretEnv := &github.EncryptedSecret{
Name: "COSIGN_PRIVATE_KEY",
KeyID: key.GetKeyID(),
EncryptedValue: base64.StdEncoding.EncodeToString(keys.PrivateBytes),
}
privateKeySecretEnvResp, err := client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, privateKeySecretEnv)
if err != nil {
return fmt.Errorf("could not create \"COSIGN_PRIVATE_KEY\" github actions secret: %w", err)
}
if privateKeySecretEnvResp.StatusCode < 200 && privateKeySecretEnvResp.StatusCode >= 300 {
bodyBytes, _ := io.ReadAll(privateKeySecretEnvResp.Body)
return fmt.Errorf("%s", bodyBytes)
}
fmt.Fprintln(os.Stderr, "Private key written to COSIGN_PRIVATE_KEY github actions secret")
publicKeySecretEnv := &github.EncryptedSecret{
Name: "COSIGN_PUBLIC_KEY",
KeyID: key.GetKeyID(),
EncryptedValue: base64.StdEncoding.EncodeToString(keys.PublicBytes),
}
publicKeySecretEnvResp, err := client.Actions.CreateOrUpdateRepoSecret(ctx, owner, repo, publicKeySecretEnv)
if err != nil {
return fmt.Errorf("could not create \"COSIGN_PUBLIC_KEY\" github actions secret: %w", err)
}
if publicKeySecretEnvResp.StatusCode < 200 && publicKeySecretEnvResp.StatusCode >= 300 {
bodyBytes, _ := io.ReadAll(publicKeySecretEnvResp.Body)
return fmt.Errorf("%s", bodyBytes)
}
fmt.Fprintln(os.Stderr, "Public key written to COSIGN_PUBLIC_KEY github actions secret")
if err := os.WriteFile("cosign.pub", keys.PublicBytes, 0o600); err != nil {
return err
}
fmt.Fprintln(os.Stderr, "Public key also written to cosign.pub")
return nil
}

See google/go-github#1607 for what I think we need to do to fix it.

We should definitely fix this here ASAP, but I'd also be interested in sending a patch upstream to go-github to:

  1. Make the API actually return an error when the request fails; it seems to just silently do nothing right now.
  2. Add a simpler API that doesn't require callers to handle the encryption themselves.

@cpanato cpanato self-assigned this Jun 13, 2022
@cpanato
Copy link
Member

cpanato commented Jun 13, 2022

on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants