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

keyless releases via workload identities and transparency log support #157

Closed

Conversation

shibumi
Copy link
Contributor

@shibumi shibumi commented Sep 26, 2021

Inspired by my in-toto-golang goreleaser build I played a little bit with a similar workflow for go-tuf.
This PR is work in progress.

What works already:

  • Building tuf and tuf-client
  • Releasing the build artifacts

What is missing:

  • creating signatures via cosign

This PR does only make sense if go-tuf has a release cycle. Are there any plans for cutting a new release or releases at all?

@shibumi shibumi marked this pull request as draft September 26, 2021 22:14
@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

I have updated the PR a little bit and I have added signatures via cosign. How does this work:

  1. You have to put a cosign.pub public key into the repository
  2. The core-maintainer team creates a cosign private key. This private key will be attached to the github repository via github secrets.
  3. You add the password for the private key to the github secrets

You need the following two variables:

  • COSIGN_KEY: for the private key
  • COSIGN_PWD: for the password for the private key

I am aware that giving github access to both isn't the best solution, but it is the best I came up with.

EDIT: The alternative would involve manual builds + releases (this would violate SLSA level 1, iirc).

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

If you want to see how this looks like. You can have a look on my in-toto-golang fork:

https://github.com/shibumi/in-toto-golang/actions/runs/1280062339

Goreleaser will also automatically create a github changelog for you based on the commits. I suggest using conventional commits: https://www.conventionalcommits.org/en/v1.0.0/

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

One last addition: The release pipeline will only be triggered if:

  1. All tests has been successful
  2. There is a new tag being pushed to the repository

The release will fail if the two github secrets (mentioned above) are missing.

EDIT: Github does not allow pushing tags via PR.. so there will be never a release being scheduled by a malicious PR.

@shibumi shibumi changed the title WIP: release pipelines for go-tuf cli/server via goreleaser release pipelines for go-tuf cli/server via goreleaser Sep 27, 2021
@shibumi shibumi marked this pull request as ready for review September 27, 2021 22:18
@trishankatdatadog
Copy link
Member

Amazing, thanks @shibumi! Now we have to figure out how to best generate and upload the key...

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

@trishankatdatadog

Generating a keypair works via: cosign generate-key-pair
You can then push the cosign.pub file in this repository (the root dir of the repo).
Then just add the secret key + pw for the secret key in the Github secrets settings on Github:

https://kurisu.shibumi.dev/share/img-2021-09-28-00-25-57.png

@trishankatdatadog
Copy link
Member

WDYT about generating this key in the same place it will be used: GitHub Actions itself? As a one-time, manually-run job, ofc.

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

WDYT about generating this key in the same place it will be used: GitHub Actions itself? As a one-time, manually-run job, ofc.

This would work, as well. In that case you would need to add the generated cosign.pub key to the release artifacts. Otherwise it would be pointless to sign it if you have nothing to validate the signature with.

@trishankatdatadog
Copy link
Member

This would work, as well. In that case you would need to add the generated cosign.pub key to the release artifacts. Otherwise it would be pointless to sign it if you have nothing to validate the signature with.

Easily done, no?

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

@trishankatdatadog I thought about this a while. Do you know how the 'randomness' inside of Github Action VMs looks like?
What if the random seed for the cosign key generation in the github action is bad?

I had a proper look on cosign and it would be possible to generate a new key-pair for every PR run:

❯ export COSIGN_PASSWORD=$(openssl rand -base64 32)
❯ cosign generate-key-pair
Private key written to cosign.key
Public key written to cosign.pub

Do you have something 'bigger' in your mind? :)

Easily done, no?

It is not rocket science.. this is doable yes. The question is if it's a good idea. To be honest: I don't know.

@trishankatdatadog
Copy link
Member

I had a proper look on cosign and it would be possible to generate a new key-pair for every PR run:

That's hilarious. A throwaway signing key for every release. Can't we just use Fulcio? Is it in production yet? @asraa

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

That's hilarious. A throwaway signing key for every release. Can't we just use Fulcio? Is it in production yet? @asraa

Ah okay. My apologies :D looks like I misunderstood what you mean. Let me have a look on Fulcio ( I never used it before).

@trishankatdatadog
Copy link
Member

Ah okay. My apologies :D looks like I misunderstood what you mean. Let me have a look on Fulcio ( I never used it before).

Don't get me wrong: I don't think it's a bad idea...

@shibumi
Copy link
Contributor Author

shibumi commented Sep 27, 2021

There are two blockers with fulcio:

  1. The root CA will change in the future according to their README
  2. The fulcio + cosign feature is considered experimental according to the cosign README.

We could freeze this PR for a while and wait. @dlorenc mentioned on twitter that the certificate transparency features will be production ready soonish... maybe this does apply to signing via fulcio, too?!

@shibumi
Copy link
Contributor Author

shibumi commented Nov 9, 2021

@trishankatdatadog @asraa

FYI: I have experimented with cosign and github actions workload identities a little bit. My newest in-toto-golang PR (in-toto/in-toto-golang#128) showcases signatures via OIDC-Issuer and transparency logs in rekor.
The newest PR removes the necessary static secrets in the Github secret store and replaces them with ambient credentials via github OIDC issuer as mentioned in dan's blog article.
For this, I have also implemented missing functionality in cosign for storing the public key on disk (if wanted).

The only part what is missing now:

  1. Getting cosign's OIDC functionality out of experimental state.
  2. The public-available, stable, official rekor instance
  3. Further improvements (using TUF for signing TUF binaries.. etc)

@shibumi shibumi marked this pull request as draft November 16, 2021 17:52
@coveralls
Copy link

coveralls commented Nov 16, 2021

Pull Request Test Coverage Report for Build 1646963318

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 69.653%

Totals Coverage Status
Change from base Build 1574146571: 0.0%
Covered Lines: 2068
Relevant Lines: 2969

💛 - Coveralls

@trishankatdatadog
Copy link
Member

Thanks for continuing to make progress on this!

@shibumi
Copy link
Contributor Author

shibumi commented Nov 16, 2021

@trishankatdatadog @asraa short update on this PR:

I have done the following changes:

  1. I switched from Github Secrets to keyless signatures via workload identities
  2. One goreleaser file will generate a signed source tarball as well (very useful for downstream like linux distributions.. they usually compile the binaries from source)
  3. transparency logs will be automatically uploaded to the public rekor instance
  4. The used secrets are ephemeral and only valid for 30min. Cosign v1.3.1 will automatically retrieve the public certificate from the public rekor instance via looking up the digest of the artifact and the signature

A few open topics to discuss:

  1. TUF + keyless signatures via workload identities. (I think @asraa is working on a PoC for this)
  2. The oidc-issuer feature is still experimental in cosign (I hope it will be considered stable, soon).
  3. The rekor/fulcio/sigstore instances are not production ready yet, but Dan told me that they will transition the transparency logs from the current rekor instance to the new one. But don't take my word for it.
  4. Right now we only support amd64.. do we want more architectures?

@shibumi shibumi changed the title release pipelines for go-tuf cli/server via goreleaser keyless releases via workload identities and transparency log support Nov 16, 2021
@shibumi
Copy link
Contributor Author

shibumi commented Dec 11, 2021

Updated:

New cosign version: v1.4.1
New GoReleaser version: v1.1.0

Experimental mode is still needed. According to Dan, we might have a cosign release without it with version >= v.1.5.0

@shibumi shibumi force-pushed the feat/add-goreleaser branch 4 times, most recently from 0dd82d7 to 720e773 Compare January 2, 2022 19:13
@shibumi
Copy link
Contributor Author

shibumi commented Jan 2, 2022

I have updated this PR:

  • Rebased on the current main branch
  • Changed the go versions in the matrix from 1.13-1.16 to 1.16 and 1.17 (the last two stable releases)
  • Added the generated certificates to the Github release page
  • Added SBOM generation via Syft for the source code and the compiled binaries.

@shibumi shibumi force-pushed the feat/add-goreleaser branch 2 times, most recently from dca6553 to f6c9268 Compare January 2, 2022 19:57
This commit enables keyless signatures via the Github Actions workload identity. The pipeline will run on a new tag and will generate a compiled cli and server version of TUF and a signed source tarball. The keys are ephemeral and valid for 30min and strictly coupled to the workload identity of the Github Actions workflow. Transparency logs will be automatically uploaded to the public rekor instance
sboms:
- artifacts: archive
signs:
- cmd: cosign

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can move the COSIGN_EXPERIMENTAL environment variable over here under the env property of the sign section, WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean in the goreleaser files instead of the github action workflow file? Do you know how? Can you provide a gist?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run: go vet ./...
- name: Install staticcheck
run: "go install honnef.co/go/tools/cmd/[email protected]"
- name: Run staticcheck

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use golangci-lint tool instead of these lines, WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that makes sense. These lines are migrated from the old build workflow.. @asraa @trishankatdatadog are you fine with using golangci-lint instead of staticcheck (golangci-lint calls staticcheck, but can do more).

@trishankatdatadog
Copy link
Member

Closed by #234. Thanks for your hard work, @shibumi and @developer-guy!

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

Successfully merging this pull request may close these issues.

4 participants