From 2ec646b9d4984d6e1f6a80ff2323d2b2172bd283 Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:24:41 +0000 Subject: [PATCH 1/2] fix(gapic-common): require grpc >= 1.83 for post-quantum key exchange gRPC began defaulting to the X25519MLKEM768 hybrid post-quantum key exchange in 1.83 (grpc/grpc#42560). The existing "~> 1.66" floor permits a resolver to select any release in the 1.66-1.82 range, which silently downgrades the transport to classical-only cryptography with no signal to the caller and no way for them to detect it. Raising the floor to ">= 1.83", "< 2.a" guarantees that every downstream generated client resolves a PQC-capable gRPC transport. The upper bound preserves the existing practice of excluding a future 2.x major. The resolved version in Gemfile.lock is unchanged at 1.83.0; only the declared constraint moves. --- gapic-common/Gemfile.lock | 2 +- gapic-common/gapic-common.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gapic-common/Gemfile.lock b/gapic-common/Gemfile.lock index 42048aa..28df410 100644 --- a/gapic-common/Gemfile.lock +++ b/gapic-common/Gemfile.lock @@ -10,7 +10,7 @@ PATH googleapis-common-protos (~> 1.6) googleapis-common-protos-types (~> 1.15) googleauth (~> 1.12) - grpc (~> 1.66) + grpc (>= 1.83, < 2.a) GEM remote: https://rubygems.org/ diff --git a/gapic-common/gapic-common.gemspec b/gapic-common/gapic-common.gemspec index 204f9a0..dd28e43 100644 --- a/gapic-common/gapic-common.gemspec +++ b/gapic-common/gapic-common.gemspec @@ -43,5 +43,5 @@ Gem::Specification.new do |spec| spec.add_dependency "google-cloud-env", "~> 2.2" spec.add_dependency "google-logging-utils", "~> 0.1" spec.add_dependency "google-protobuf", "~> 4.26" - spec.add_dependency "grpc", "~> 1.66" + spec.add_dependency "grpc", ">= 1.83", "< 2.a" end From 05ec5ae194c4ed8b3d3f794edcd7f10cb9f5c708 Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Mon, 21 Sep 2026 17:56:50 +0000 Subject: [PATCH 2/2] docs(gapic-common): document the OpenSSL floor for REST post-quantum key exchange The grpc >= 1.83 floor added in this PR is enforceable in the gemspec, so gRPC gets post-quantum key exchange automatically. REST cannot work that way: it delegates to the host's system OpenSSL, ML-KEM first ships in OpenSSL 3.5, and Ruby's openssl is a default gem bound to whatever libssl the host provides, so no gem constraint can express it. That leaves documentation as the only way to state the REST requirement. Below OpenSSL 3.5 a REST connection silently negotiates classical X25519 - correct and safe, but not post-quantum, and until now nothing told the user which of the two they were getting. --- gapic-common/README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/gapic-common/README.md b/gapic-common/README.md index 9feb9f1..36d0cca 100644 --- a/gapic-common/README.md +++ b/gapic-common/README.md @@ -24,6 +24,35 @@ work, but are unsupported and not recommended. See https://www.ruby-lang.org/en/downloads/branches/ for details about the Ruby support schedule. +## Post-Quantum Key Exchange + +Clients built on this library negotiate the hybrid post-quantum key exchange +group `X25519MLKEM768` — classical X25519 paired with ML-KEM-768 ([NIST FIPS +203][]) — over TLS 1.3. No application code changes are required, because the +handshake belongs to the transport layer. The two transports source that +support differently: + +| Transport | Cryptographic provider | Requirement | Enforced by this gem? | +| --- | --- | --- | --- | +| gRPC | BoringSSL, vendored inside the `grpc` gem | `grpc >= 1.83` | Yes | +| REST | Host system OpenSSL, via `Net::HTTP` and Faraday | OpenSSL `>= 3.5` | No | + +gRPC clients get post-quantum key exchange automatically: `gapic-common` +depends on `grpc >= 1.83`, the first release to offer `X25519MLKEM768` in the +TLS ClientHello by default. + +The REST requirement cannot be expressed as a gem dependency. Ruby's `openssl` +is a default gem bound to whatever `libssl` the host provides, and ML-KEM first +ships in OpenSSL 3.5. On an older host, REST connections negotiate classical +X25519 instead — a safe fallback rather than an error, but not post-quantum. To +check the OpenSSL your Ruby is linked against: + +```sh +ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION' +``` + +[NIST FIPS 203]: https://csrc.nist.gov/pubs/fips/203/final + ## Contributing Contributions to this library are always welcome and highly encouraged.