Skip to content

Commit 2fd3496

Browse files
MatheusRichhsbt
authored andcommitted
Add commented-out rubygems_mfa_required to bundle gem template
Package registries are active supply chain attack targets. Recent high-profile incidents include the Axios NPM compromise (https://socket.dev/blog/axios-npm-package-compromised) and the LiteLLM PyPI compromise (https://docs.litellm.ai/blog/security-update-march-2026). RubyGems supports an MFA-required opt-in via gemspec metadata: spec.metadata["rubygems_mfa_required"] = "true" but most gems haven't enabled it. A big reason is discoverability. Nothing in the `bundle gem` flow mentions the option, so authors would need to already know it exists to find it. Reference: https://guides.rubygems.org/mfa-requirement-opt-in/ This commit adds a commented-out `spec.metadata["rubygems_mfa_required"] = "true"` line, along with a short explanatory comment and a reference link, to the gemspec template used by `bundle gem`. Default behavior is unchanged because the line is commented out, but every new gem author now sees the MFA opt-in right where they configure their gemspec. Opting in is then a matter of deleting the leading `# `.
1 parent 57f9870 commit 2fd3496

2 files changed

Lines changed: 15 additions & 0 deletions

File tree

bundler/lib/bundler/templates/newgem/newgem.gemspec.tt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ Gem::Specification.new do |spec|
2222
spec.metadata["changelog_uri"] = "<%= config[:changelog_uri] %>"
2323
<%- end -%>
2424

25+
# Uncomment the line below to require MFA for gem pushes.
26+
# This helps protect your gem from supply chain attacks by ensuring
27+
# no one can publish a new version without multi-factor authentication.
28+
# See: https://guides.rubygems.org/mfa-requirement-opt-in/
29+
# spec.metadata["rubygems_mfa_required"] = "true"
30+
2531
# Specify which files should be added to the gem when it is released.
2632
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
2733
gemspec = File.basename(__FILE__)

spec/commands/newgem_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,15 @@ def create_temporary_dir(dir)
650650
to match(/example\.com/)
651651
end
652652

653+
it "includes a commented-out rubygems_mfa_required metadata hint" do
654+
bundle "gem #{gem_name}"
655+
656+
gemspec_contents = bundled_app("#{gem_name}/#{gem_name}.gemspec").read
657+
658+
expect(gemspec_contents).to include('# spec.metadata["rubygems_mfa_required"] = "true"')
659+
expect(gemspec_contents).to include("https://guides.rubygems.org/mfa-requirement-opt-in/")
660+
end
661+
653662
it "sets a minimum ruby version" do
654663
bundle "gem #{gem_name}"
655664

0 commit comments

Comments
 (0)