Ruby Shield: A Reflection on Four Years of Securing the Ruby Supply Chain

In July 2022, Ruby Central and Shopify launched Ruby Shield, a four-year partnership built around a single goal: giving the tools at the heart of the Ruby ecosystem the sustained investment they need to stay secure and reliable. Shopify committed $1 million over four years, along with dedicated engineering time from its Ruby and Rails Infrastructure team, and left it to Ruby Central to direct that support wherever it would do the most good for the community.

Software supply chain attacks are climbing sharply across every major package ecosystem, and RubyGems.org, the registry that nearly every Ruby application depends on, was being maintained on a shoestring. Ruby Shield gave us the ability to plan security and reliability work on a timescale of years rather than days.

After four years, this June, Ruby Shield came to a close. Ruby Shield helped move RubyGems.org from best-effort, volunteer-maintained project toward a professionally operated service with modern authentication, verifiable publishing, and around-the-clock coverage. Along the way, the ecosystem it protects has served tens of billions of gem downloads a year with almost no interruption. This post is our final reflection on the program: what it funded, what changed because of it, and where the work goes from here.

The First Three Years

Ruby Shield existed to strengthen and secure Ruby's software supply chain, and that meant investing on two fronts at once. The first was operational: keeping RubyGems.org reliably online for developers worldwide and automated systems that reach for it every day. The second was security: closing the gaps that attackers most often exploit to compromise open source packages. We shared progress along the way, most notably in our Ruby Shield update in early 2023 and our first Annual Open Source Report, and the highlights below trace the through-line across all three years.

On-call rotation

Before Ruby Shield, RubyGems.org was maintained mostly by a small team of unpaid volunteers. Ruby Shield funded a shift to a follow-the-sun on-call rotation, with engineers awake and responsible for the service somewhere in the world at every hour of the day. This helped the sustainability of operations immensely. Reliability is easy to overlook, because it is invisible when it works. But every one of those downloads is a developer, a deploy, or a CI run that would have stalled if the registry had been down. When RubyGems.org goes down, a human is already aware, communicating, and working to resolve the incident.

MFA improvements

Account takeover is one of the most common ways attackers compromise a package: steal or guess a maintainer's credentials, then publish a malicious version of a gem that thousands of projects already trust. A large share of Ruby Shield's security work went into making that far harder.

Building on the multi-factor authentication RubyGems.org already offered, we made it mandatory for the maintainers of the most-downloaded gems, starting with owners of gems above 180 million total downloads and expanding coverage from there., starting with owners of gems above 180 million total downloads and expanding coverage from there. You can read the original policy in Requiring MFA on popular gem maintainers. We then added hardware security key and passkey (WebAuthn) support, giving maintainers phishing-resistant options that are dramatically harder to steal than a password or a one-time code.

Together these changes hardened the accounts that matter most, the ones whose compromise would ripple out across the largest share of the ecosystem. Raising the bar on authentication for popular gems directly reduces the risk of the account takeovers that so often begin a supply chain attack.

Trusted publishing

Even with strong authentication, long-lived API tokens are a liability. They sit in CI configurations and on developer machines, and a single leaked token can be replayed by anyone who finds it. Trusted Publishing, one of the program's signature deliverables, addressed this directly. Instead of storing a permanent token, a gem author connects their gem to a trusted environment such as a GitHub Actions workflow, and each publish uses a short-lived credential exchanged automatically over OpenID Connect.

The security gain is substantial. There is no long-lived secret to leak, credentials expire almost immediately, and the provenance of a release becomes transparent: what gets published can be tied back to the repository and workflow that produced it. Trusted Publishing brought RubyGems.org in line with the strongest publishing practices across the packaging world and gave the Ruby community a safer default for automated releases.

Bundler Lockfile Checksums

Security at the registry only goes so far if the software installing gems cannot verify what it receives. Bundler Lockfile Checksums, a nearly two-year effort involving four engineers, closed that gap on the client side. When enabled, Bundler records the checksum of every gem version in the lockfile and verifies it before installation, so a tampered or substituted package is caught before it ever reaches a developer's machine or a production deploy. With Bundler 4, we set this as the default.

This protects against attacks that authentication and authorization cannot see, such as a package being altered somewhere between publication and installation. It gives teams a way to guarantee that the gems running in production are exactly the ones they locked during development.

Ruby Shield did not accomplish all of this on its own. It worked alongside support from AWS, the Sovereign Tech Agency, Alpha-Omega, and Ruby Central's individual and corporate members. What Ruby Shield uniquely provided was multi-year stability: the confidence to start ambitious work, staff it properly, and see it through to release.

The Final Year

If the first three years were about building new capabilities, the final year was about maturing them into durable practice. The headline features were largely in place; the work that Ruby Shield funded in its last stretch went into the less visible layer underneath, the processes, tooling, and hardening that turn a set of features into a service an ecosystem can rely on. The same two fronts held: keeping the service running well, and closing the gaps attackers look for.

Prohibiting Reused Passwords

Reused passwords are a persistent avenue for account takeover: a credential leaked in an unrelated breach can be replayed against a package registry. RubyGems.org now checks user passwords against the Have I Been Pwned database at login. When a compromised password is detected, the user is shown an explanation and automatically sent a reset link, after which they can carry on as normal. The check is done privately, without ever sending the full password or its full hash to a third party. You can read the details in Protecting rubygems.org from the outside in.

Detecting and defending against abuse

Some of the year's most valuable work went into catching bad actors earlier and giving the team the visibility to respond. Previously, validating a published gem meant unpacking its metadata into a Ruby object, an approach a crafted malicious gem could abuse to mount a denial-of-service attack against the push process itself. We merged new validation rules that detect these gems much earlier, without parsing the metadata at all, described alongside the password work in the same post above.

Around that, we built out a broader set of abuse-response tools: protections on reserved gem names, blocks on disposable email domains, webhook rate limits, spam-account cleanup, and temporary registration controls we can switch on during an active abuse event. We also wired monitoring into login, signup, and gem-push behavior, so the team now has real signal for detection and triage. Investigating suspicious activity used to be a one-off scramble; it is now an observable, repeatable workflow. For a fuller picture of how this layered defense works in practice, see How RubyGems.org Protects Our Community's Critical OSS Infrastructure.

Dependency Cooldowns

Attackers who compromise a maintainer's account are betting that projects will pull in their poisoned release before anyone spots it. Dependency cooldowns call that bet, refusing any version until it has been public for a configured period of time so new releases can be vetted before Bundler resolves to them. Cooldowns required some foundational work underneath it: RubyGems.org's Compact Index was rebuilt to serve each version's time of publish for Bundler to read. More more information, please read Cool down before you install: give new gems a few days to be vetted.

Maturing how we operate

For much of its history, access to RubyGems.org was managed informally, which was workable with a handful of long-tenured volunteers but risky as the team grows and changes. This year we replaced that with a documented operating model: a defined set of team roles, a written PII policy, an offboarding checklist that catalogues every access point to revoke when someone leaves, and a standard onboarding session that walks every new engineer, security hire, or rotating contributor through the stack and how it is run. Access is now something we grant and revoke deliberately, which shrinks the window an attacker could exploit through a stale or forgotten credential.

We also rebuilt the on-call program itself. Expanding the roster to allow a sustainable rotation while keeping a follow-the-sun model. We drafted comprehensive runbooks covering our monitors and the common operational tasks. The practical effect is that any on-call engineer can now respond to an incident without prior hands-on experience with that specific system, which makes coverage both broader and more resilient.

How Ruby Shield Transformed Our Program

Ruby Shield's most lasting effect is not any single feature. It is the way it changed how Ruby Central thinks about its role.

When the program began, Ruby Central's open source work was closer to a series of funded tasks than a program with a strategy. Four years of stable investment let us plan, hire, and commit to multi-year efforts, and in doing so it pushed us to start thinking and behaving like a software foundation: formalizing governance, writing down policies, defining roles, maturing our operations, and treating RubyGems.org as critical infrastructure that deserves professional stewardship rather than best-effort volunteering. The maturation described in the last year is, in many ways, the visible result of that shift in mindset.

It also changed how we think about who should sustain this work. Ruby Shield brought to light a question that had been easy to avoid: why were the tools that nearly every Ruby company depends on being kept alive by a small number of people and a thin, uncertain funding base? If this infrastructure is truly critical, then supporting it should not rest on the generosity of a single company or the spare time of volunteers. It should be a shared responsibility of the companies that build their businesses on Ruby.

That thinking is what led us to the Ruby Alliance. Rather than depending on one company to carry this load, we want to bring together a core group of Ruby companies to sustain RubyGems.org and the Ruby toolchain collectively. Ruby Shield proved the model works when a company invests with vision and without strings; the Ruby Alliance is our effort to broaden that from a single partnership into a durable coalition, so the security and reliability gains of the last four years continue and compound rather than depending on any one sponsor.

Closing

None of this would have happened without Shopify. Committing $1 million over four years, along with the time of its own engineers, and then trusting Ruby Central to direct that support wherever it would help the community most, took real vision. Shopify saw that the health of the Ruby supply chain was worth investing in for its own sake, and the entire ecosystem is more secure for it. We are deeply grateful for their partnership.

It is hard to overstate how much this program shaped Ruby Central. Ruby Shield did more than fund a list of features. It gave us the stability to grow into a more capable steward of RubyGems, RubyGems.org, and Bundler, and it reset our expectations for what this infrastructure can and should be. The work it started, from modern authentication and verifiable publishing to a professionally operated, well-monitored service, is now part of how we run things every day.

The work does not end here, and it cannot be carried by one company alone. Shopify is continuing to support these efforts by joining the Ruby Alliance. If your business is built on Ruby, RubyGems.org is part of your supply chain, and its security and reliability are worth protecting. We encourage the companies that depend on this ecosystem to join us in sustaining it, through the Ruby Alliance and our supporter programs, so that we can build on this foundation. Ruby Shield showed what is possible when a company invests in the commons. Now we would like to make that investment something the whole community shares.