Remove openssl gem requirement - #5736
Conversation
Nothing tied the Gemfile to `.ruby-version` before, so resolving under an older Ruby was silently allowed. That became load-bearing when 75d3bd3 dropped the explicit `openssl` gem: the workaround for ruby/openssl#949 now comes from the default `openssl` 3.3.1 that ships with Ruby 3.4.9, and an older Ruby would bring back the CRL verification failures without any signal. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 5 <noreply@anthropic.com>
|
I'll analyze this and get back to you. |
|
Claude finished @mokagio's task in 3m 59s —— View job ReviewNice change — I left two inline comments on 1. The
|
There was a problem hiding this comment.
Pull request overview
Removes the explicit openssl gem dependency from the Bundler setup and ensures the repository’s intended Ruby version is enforced by Bundler (via .ruby-version), preventing accidental use of older Rubies that may hit the prior OpenSSL compatibility issues.
Changes:
- Drop the
opensslgem fromGemfileandGemfile.lock. - Enforce Ruby version by adding
ruby file: '.ruby-version'toGemfile. - Record the Ruby version (
3.4.9) inGemfile.lockunderRUBY VERSION.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| Gemfile | Enforces Ruby version from .ruby-version and removes the explicit openssl gem requirement. |
| Gemfile.lock | Removes openssl from the resolved dependency set and records the enforced Ruby version. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| source 'https://rubygems.org' | ||
|
|
||
| ruby file: '.ruby-version' |
There was a problem hiding this comment.
ruby file: resolves the file relative to the Gemfile's directory and strips whitespace/a ruby- prefix, so with .ruby-version containing 3.4.9\n this works from any subdirectory. Two things worth being deliberate about:
It's an exact pin, not a floor. Bundler turns this into = 3.4.9, so anyone on 3.4.10 (or 3.5.x) gets a hard Your Ruby version is X, but your Gemfile specified 3.4.9 on every bundle exec. That's stricter than what the PR description motivates (guarding against old Ruby). It's consistent with .ruby-version already being exact for rbenv/mise users, so it's a defensible choice — just be aware the newly-affected population is exactly the "no version manager" crowd this targets, and for them the failure mode is now a hard stop rather than "it worked". If you'd rather express a floor while keeping a single source of truth, there isn't a file:-based way to do it — you'd have to write ruby '>= 3.4.9', '< 4' literally and accept the duplication.
Nit: this PR removes the only comment that documented the TLS history, and the new line's intent isn't self-evident. Consider:
| ruby file: '.ruby-version' | |
| # Enforce the version declared in `.ruby-version`, so that machines without a | |
| # Ruby version manager can't silently run the automation on an older Ruby. | |
| ruby file: '.ruby-version' |
There was a problem hiding this comment.
This seems strange, I've never seen us needing to do this in any other project, why thus would we really start needing to do this in this repo?
There was a problem hiding this comment.
I read the rationale in the commit message:
Nothing tied the Gemfile to
.ruby-versionbefore, so resolving under an older
Ruby was silently allowed.
That became load-bearing when 75d3bd3 dropped the explicitopensslgem: the workaround for ruby/openssl#949 now comes from the defaultopenssl3.3.1 that ships with Ruby 3.4.9, and an older Ruby would bring back the CRL verification failures without any signal.
But I'm still not 100% convinced. I mean, sure, that's an extra "belt and suspenders" pinning that reduces that risk. But I think it's fair to assume that all the environments in which we use that Gemfile (especially on CI and on AppsInfra engineers' machines) we all use rbenv to begin with, which will always rely on .ruby-version automatically. And if we decide this extra explicit pinning in the Gemfile is really important to add, we should add it on every repo (but I'm not convinced it's worth it?)
There was a problem hiding this comment.
Correct, the requirement is not needed, just something I thought it be good to try out for size.
I asked Opus 5 to validate my openssl removal and it pointed out the no-guarantee on which Ruby version would be in use and therefore that the openssl issue would be address at runtime.
It suggested to force the Ruby version in Gemfile via ruby file: .ruby-version. That was a TIL for me.
While it's quite unlikely we'd run in a machine with old Ruby version running the automation, the idea of ensuring the version is respected seem valuable.
I decided to try it out for size in this PR and I'm glad I got your feedback on it—and Claude's, as I hand't considered the "it's a pin, not a floor."
Looking at this one day later, I still think it's useful in principle, but maybe not as useful as I imagined in our instance, given:
- We aim for devs not to need Ruby
- We manage all the infra that needs Ruby and therefore can ensure a Ruby version manager and other such things
Putting it all together, it's really downgrades the usefulness of this condition.
I'll remove it.
| # SSL_connect returned=1 errno=0 peeraddr=3.5.132.155:443 state=error: certificate verify failed (unable to get certificate CRL) | ||
| # | ||
| # See https://github.com/ruby/openssl/issues/949 | ||
| gem 'openssl', '~> 4.0' |
There was a problem hiding this comment.
Worth double-checking the premise here: removing this doesn't leave you with "no openssl gem", it drops you back to the default gem bundled with Ruby. Gemfile.lock had openssl (4.0.2); Ruby 3.4 ships openssl as a default gem in the 3.3.x line, so this is effectively a downgrade of the TLS stack, not just deleting a redundant entry.
So "unnecessary in Ruby 3.4.9" holds only if the fix for ruby/openssl#949 is present in the 3.3.x default gem, not merely in 4.0. Quick check on a 3.4.9 install:
ruby -ropenssl -e 'puts [RUBY_VERSION, OpenSSL::VERSION, OpenSSL::OPENSSL_LIBRARY_VERSION].join(" / ")'Two caveats on how to validate:
SSL_connect ... unable to get certificate CRLis sensitive to the system OpenSSL library and cert store, so a green Linux Buildkite run does not prove macOS dev machines are fine. Reproduce on the environment where it originally bit (I couldn't find the commit that added the pin — the checkout here is shallow — but the wording suggests a local/dev-machine failure).- After this change the openssl version is no longer recorded in
Gemfile.lockat all, so it becomes implicit per-environment, and you pick up openssl fixes only on Ruby patch releases /.ruby-versionbumps rather than on the gem's own cadence. Minor, but it's the reproducibility trade-off you're making.
There was a problem hiding this comment.
Verified. Everything is good for our usage in Ruby 3.4.9.
3.4.9 ships openssl 3.3.1, which contains the fix for the issue.
AI-performed research details
The fix is ruby/openssl#950, which
removes V_FLAG_CRL_CHECK_ALL from the default cert store. It shipped in
openssl 3.1.2 / 3.2.2 / 3.3.1
(maintainer confirmation),
and Ruby picked it up as a default-gem backport in 3.4.8
(Bo98).
Same file, two tags — this is the whole argument:
- Ruby 3.2.2:
ext/openssl/lib/openssl/ssl.rb#L93-L95
sets the flag → broken against OpenSSL 3.6.0. Default gem 3.1.0. - Ruby 3.4.9:
ext/openssl/lib/openssl/ssl.rb#L93-L94
— the line is gone. Default gem 3.3.1.
Confirmed on a local 3.4.9 install:
$ bundle exec ruby -ropenssl -e 'puts [RUBY_VERSION, OpenSSL::VERSION].join(" / ")'
3.4.9 / 3.3.1
That also dates the pin: it landed in #4929 (2026-01-30) while .ruby-version
was 3.2.2, i.e. openssl 3.1.0, which predates the fix. It was load-bearing then
and stopped being so at #5605, when we moved to 3.4.9.
On "downgrade of the TLS stack" — the gem is a binding, not the TLS
implementation. The stack is the system OpenSSL library (unchanged by this
diff); 4.0.2 → 3.3.1 is a binding-API downgrade, and both sides carry the CRL
fix. And you're right that a green CI run proves nothing here: my machine links
OpenSSL 3.5.5, which doesn't trigger the bug at all. The source anchors above
are the environment-independent proof.
The reproducibility point stands, though: the
developers being on Ruby >= 3.4.8
See discussion at https://github.com/Automattic/pocket-casts-android/pull/5736/changes#r3775036237 TL;DR: Sure it seems useful, but in practice it's overly cautious. Our setup is such that we can trust Ruby version respect in all the runtimes where it's important to have it.
|
Claude finished @mokagio's task in 1m 56s —— View job Review (updated for
|
| google-apis-sheets_v4 (~> 0.48) | ||
| openssl (~> 4.0) | ||
|
|
||
| RUBY VERSION | ||
| ruby 3.4.9 | ||
|
|
There was a problem hiding this comment.
This RUBY VERSION stanza is a leftover from 8156757 — the last commit (24de909) removed ruby file: '.ruby-version' from the Gemfile but only touched the Gemfile, so the lockfile still records a Ruby requirement that no longer exists.
Bundler writes this section only when the Gemfile declares a Ruby version, so the next bundle install / bundle lock will drop it again and produce an unrelated lockfile diff in whatever PR happens to run it next. If any environment runs Bundler in frozen/deployment mode, a lockfile that doesn't match the Gemfile is also the kind of mismatch that can hard-fail rather than silently re-resolve.
Cheapest fix is to drop it here so the committed lock matches what bundle install would generate:
| google-apis-sheets_v4 (~> 0.48) | |
| openssl (~> 4.0) | |
| RUBY VERSION | |
| ruby 3.4.9 | |
| google-apis-sheets_v4 (~> 0.48) | |
|
Claude finished @mokagio's task in 49s —— View job Review (updated for
|

Tweaking #5733 to remove
faraday, I noticedopensslwas inGemfilestill.I recalled the requirement was due to a compatibility issue between
openssland earlier versions of Ruby.I asked Opus 5 to validate and it pointed out that, while the removal was appropriate, there was no way enforcing the 3.4.9 Ruby version, so a machine with no tooling to read and respect.ruby-versionmight end up on an old version that still has the issue.It suggested to force the Ruby version inGemfileviaruby file: .ruby-version. That was a TIL for me.While it's quite unlikely we'd run in a machine with old Ruby version running the automation, the idea of ensuring the version is respected seem valuable. I think we should adopt it.Let's use this PR to see how it looks like.