Supply Chain Security for RuboCop 🔒
Supply Chain Security
This issue tracks work to bring a secure build + release process to the RuboCop gem.
Why?
The rubocop gem is the most widely adopted linter in the entire Ruby ecosystem. It can be found in nearly every Ruby project with a Gemfile that has some concept of linting. Rubocop is one of the most downloaded RubyGems of all time with over half a billion downloads. Just according to GitHub's network dependents stats, this project is included in over 350,000 repositories.
We should ensure that each release of rubocop is done in a secure, auditable, and verifiable manner so that the entire ecosystem of Ruby projects that use this Gem can ensure it is always safe 🔒.
How?
After chatting with @bbatsov (the core maintainer / author of rubocop), it is clear that security is always important and the build process for rubocop today could have some room for improvements. Right now, rubocop is built and released locally via the rake release command. This command does the following:
- Ensures the working directory is clean
- Builds the gem
- Creates a new git tag and pushes it to the remote
- Pushes the gem to RubyGems
This is okay but the consumers of this Gem have no way to verify or validate the build process and truly ensure that no tampering or malicious actions were taken during the build process.
So this is what I am purposing we do:
- Modify the current
rake releasecommand so that it only pushes a git tag. This way the "release" flow stays familiar for maintainers. But it will do a lot more... - After the
rake releasecommand runs and it pushes the git tag, it triggers a GitHub Actions "release" workflow - The workflow builds the Gem and uploads it as an artifact
- The resulting Gem that was built is signed and verified via artifact attestations and sigstore
- The gem is automatically publishes to RubyGems via OIDC and Trusted Publishing
- A new GitHub Release is automatically created via the
gh release createCLI command - 🎉
After the workflow completes, it will:
- Have a provenance badge on the RubyGems page
- Have an
/attestationspage on GitHub with signed artifacts
- Have the ability for consumers of the Gem to verify it via:
gh attestation verify rubocop-X.X.X.gem - Have a repeatable, and transparent build process
What I will do to help...
I know the maintainers of this project have a lot of work on their plates so I will go ahead and work on opening a PR to this project with all the changes needed to bring this to life in one place. That way the maintainers can look at the actual changes and discuss here whether it is something they are interested in adopting or not. Actually being able to see what the workflow will look like is going to be very useful in this context (IMO).
Hopefully this helps and sorry for the long wall of text here but I think the context is quite important! 🙇 ❤ 🔒
This is great! The reliance on GitHub bothers me too much to do it for my own work, and that's why I built stone_checksums, and sign my gems myself. Love to see improved security!
In rubocop-rspec we decided to use the workflow provided by rubygems: https://github.com/rubygems/release-gem
Could you touch on why you decided not to use that workflow in your PR #14108?
@bquorning I did so intentionally to try and get also close as possible to SLSA Level 3. A big part of getting to L3 is having the "build" process be separate from the "signing" process to isolate signing material. The extra added benefits we will get with this is having Actions build provenance and RubyGems signed provenance in the same workflow.
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed soon if no further activity occurs. Thank you for your understanding!
I still have an open pull request marked as "high priority" so I don't think this should be closed.
I've tagged this issue as well, so going forward the bot will ignore it.