For an application, Gemfile.lock decides: it is committed and every deployment installs exactly those versions. A gem is different. When an application depends on your gem, Bundler ignores any Gemfile and Gemfile.lock inside it and resolves your gemspec's runtime dependencies together with the application's.
Who resolves the versions
The RubyGems guide frames it as who is at the end of the chain. An application is the end, so it locks. A library is a link in someone else's chain, so it cannot lock. Your gem runs with whatever versions the consumer's resolution picks.
| File | Belongs to | Purpose |
|---|---|---|
| gemspec | A gem | Name, version, metadata, runtime and development dependencies |
| Gemfile | An application, or a gem's dev setup | Which gems and sources to use |
| Gemfile.lock | Written by Bundler | Exact versions for reproducible installs |
Why this matters for security
If you publish a gem, loose constraints in the gemspec are normal, and the guide says they should stay wide so your gem coexists with others. That means your users, not you, decide which patched versions of your dependencies they run. If you tightly pin a vulnerable version in a gemspec, you can block your own users from patching.
If you consume gems, remember that a library's tested lock file was never used in your build. Your lock file is the record of what you run.
Steps if you maintain a gem
- Keep gemspec runtime constraints wide, but set a sensible lower bound once a fix exists.
- Test against a range of dependency versions in CI, not only the latest.
- Declare development dependencies in the Gemfile if you use both files, as the guide recommends.
- Release a new version when a dependency you rely on has an advisory, and note the minimum safe version.
- Protect your publishing account, as in our note on RubyGems account security.
Steps if you ship an application
- Commit Gemfile.lock.
- Install with frozen mode in CI.
- Scan the lock file, not the Gemfile, for known advisories.
- Review lock diffs in every dependency pull request.
source "https://rubygems.org"
gemspec
gem "rspec", "~> 3.13"
The layout above is the convention for a gem repository, where the gemspec method pulls runtime dependencies in.
Try it yourself
Click through it at your own pace, or open it full screen. See the full resolved set, which is what you actually run.
Where Safeguard fits
Safeguard's policies and gates can check dependency changes in a pull request before merge. A free scan shows what it finds today.
Quick check
Should a gem commit its Gemfile.lock?
The guide treats it as a separate trade off. Either way, consumers will not use it when they install your gem.
Where do runtime dependencies go in a gem?
In the gemspec, using add_dependency. Development dependencies can go in the gemspec or in the Gemfile.
Sources
Last reviewed: 19 October 2026.