Use trusted publishers to release gems

This can be seen as a follow up on Use Github Actions to release gems.

Over the past 2 weeks I’ve been investigating setting up trusted publishers. In particular for Ruby but also a bit for Python. This RFC focuses on Ruby. Supply-chain attack analysis: Ultralytics - The Python Package Index Blog was the biggest reason I became interested again.

The idea behind trusted publishing is that you can release via GitHub Actions (or other providers) and provide some sort of traceability. The primary aim is to increase protection against supply chain attacks.

Trusted Publishing - RubyGems Guides describes it for Rubygems, but if you look at their example of it uses a fairly large flow that you need to maintain:

This uses the rubygems/release-gem action which mandates that use you rake which also sets requirements on the environment, like installing all gems. This is something I wanted to avoid because I didn’t like it when I first played with it a year ago (see Support releasing without rake · Issue #3 · rubygems/release-gem · GitHub as well). While testing this I had hoped to come up with an easy reusable workflow like we use today with release-gem.yaml but in my experimentation I found that you can’t use reusable workflows because it messes up the tokens, which is fair because that’s what it implements.

Luckily they have designed their actions more modular and there’s rubygems/configure-rubygems-credentials that only sets up credentials. And that works, but there’s still a decent amount of config you’re copying over between repositories. With dozens of gems it’s a pain to keep them in sync.

What I’ve come up with is a composite action: GitHub - ekohl/ruby-release: Release Ruby gems with minimal tooling

My proposal is to convert all existing usage of our reusable action and retire it. Then we can start mandating MFA for our gems, which was a big reason for the investigation in the first place.

While I don’t want to mandate using this action now, I’d certainly encourage everyone to adopt it. Today we sometimes see that people forget to push a tag, but if pushing a tag is the mandatory step to release it’s rather hard to forget.

4 Likes

Makes me wonder if we should look into the list of owners, too.

I enabled MFA for my account after reading your post and looked at the 2 gems I am owner. I see Greg still being an owner for foreman_monitoring and smart_proxy_monitoring who could perhaps be removed.

So I looked also at others and I see also people no longer working on the project on the one side and on the other side some being owned by “theforeman”. Thinking about plugins breaking Foreman like currently dhcp_browser, would it make sense to get this owner in place everywhere allowing for a release by the release owner / packaging team?

I have also contemplated removing people and it’s probably a good thing though I’d prefer to have that as a separate discussion.

What IMHO is mandatory is that any gem that lives in our GitHub namespace is at least owned by theforeman on Rubygems. For others I’d say it’s recommended. There is a shared repository where a few people have access to the credentials so we can manage it.

1 Like

I’ve just released foreman_dhcp_browser with a very minimal release.yml:

On foreman_dhcp_browser | RubyGems.org | your community gem host you can see it was released by the GitHub Action.

I have decided to transfer the repository to GitHub - voxpupuli/ruby-release: Release Ruby gems with minimal tooling so a larger organization can maintain it. I debated whether it should be voxpupuli or theforeman, but decided to go for the former so there’s a larger organization behind it.

1 Like

Also very nice, they just released the Rubygems API to create these trusted publishers 3 days ago:

This means we can easily create them in bulk for all our gems.

1 Like

I played a bit more with this and came up with trusted_gem_publishers.py · GitHub. I also started PRs to use this:

A list of repositories that have GitHub publishing set up, but haven’t been converted yet:

  • foreman_kernel_care
  • foreman_puppet
  • foreman_remote_execution
  • foreman_salt
  • foreman_templates
  • hammer_cli_katello
  • ldap_fluff
  • smart_proxy_dhcp_infoblox
  • smart_proxy_dns_infoblox
  • smart_proxy_monitoring
  • smart_proxy_salt

And somehow there’s an API key for foreman_google but it doesn’t have publishing set up.

If you’re a repository maintainer of any of the above, please submit a similar PR and add me as a reviewer so I can set up the rest.

1 Like

Opened Use trusted publishers to release the gem by adamruzicka · Pull Request #950 · theforeman/foreman_remote_execution · GitHub

1 Like