A private RubyGems mirror or proxy is a server your builds install from instead of reaching rubygems.org directly. It caches gems you have used, hosts internal gems, and gives you one place to block, log and review. Point Bundler at it, deny direct egress from CI, and scope internal gems to the internal source only.
Mirror or proxy: what is the difference?
A full mirror copies the whole public index, which is large and rarely needed. The RubyGems command reference notes that the old gem mirror command moved into a separate gem, rubygems-mirror. A caching proxy, sometimes called a pull-through repository, fetches a gem from upstream on first request, stores it and serves later requests locally. Most teams want the proxy, often as a feature of a general artifact repository that also handles other ecosystems.
What does it buy you?
- Availability. Builds keep working if the public registry is down or a gem version disappears upstream.
- Control. You can block specific gems or versions, quarantine new releases, and require review for new names.
- Evidence. Logs show which build pulled which gem and when, which helps during an incident.
- Internal gems. One service hosts private gems next to cached public ones.
How do you point clients at it?
RubyGems manages remote sources with gem sources, and the command reference lists options to add a source and to clear the list. Bundler reads the sources in your Gemfile, and Bundler's configuration includes a mirror setting that redirects requests for one source to another without editing every Gemfile. Check the Bundler configuration documentation for the exact key format in your version before rolling it out.
Set it once in CI images and developer machine configuration so nobody installs by habit from the public source.
How do you stop dependency confusion?
If an internal gem named acme-billing also exists on the public registry, whichever source answers first can win. That is the dependency confusion setup. Defend in layers:
- Declare internal gems inside a
sourceblock in the Gemfile so Bundler resolves them from the internal source only. - Make the proxy refuse to serve a public gem whose name matches an internal one.
- Reserve your internal names on the public registry where practical.
- Keep the lockfile committed so the resolved source for each gem is recorded.
How do you make the proxy a security control?
A proxy that simply passes everything is a cache, not a control. Add policy:
- Delay new versions. Hold a release for a short period before it can be served, which gives the community time to spot a malicious publish.
- Block known-bad gems and versions from advisory feeds.
- Require a ticket or review for a gem name new to your organization.
- Verify what you can: check that gem versions match the checksums in your lockfile.
- Deny outbound access to the public registry from build networks, so the proxy cannot be bypassed.
A constructed example: a developer adds a gem named like a popular library with one letter changed. The proxy policy flags a never-before-seen name published two days ago, holds it, and a reviewer sees the typo.
How do you run it safely?
Treat the proxy as part of the supply chain. Restrict who can publish internal gems, use per-team credentials with narrow scope, back up the storage, patch the server, and log every upload. Keep the upstream credentials, if any, out of build jobs.
What to do
- Choose a repository server that supports RubyGems proxying and internal hosting.
- Configure CI images and workstations to use only that source.
- Move internal gems under a Gemfile source block.
- Block direct egress to the public registry from build networks.
- Add a hold period and blocklist for new gem versions.
- Log and review pulls and publishes.
- Back up and patch the server.
Safeguard dependency scanning can read your Gemfile.lock and flag advisories, and the Gold registry and free scan at gold.safeguard.sh/scan let you check a dependency list in the browser.
Quick check
Does a proxy make malicious gems impossible?
No. It gives you the place to apply holds, blocks and review. A malicious gem can still pass if policy lets it through.
Do I need a proxy if I commit Gemfile.lock?
The lockfile fixes versions, but installs still reach the public registry. A proxy adds availability, blocking and logs on top.
Sources
Last reviewed: 18 October 2026.