From 4d0603f00678926e5226066513c768432e7f01ac Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:08:46 +0000 Subject: [PATCH 1/2] chore(ci): hard-assert REST post-quantum key exchange on an OpenSSL 3.5 image The existing matrix runs on ubuntu-latest, whose system OpenSSL is 3.0.13. ML-KEM only exists from OpenSSL 3.5, so the REST transport there negotiates classical X25519 and the conformance assertion stays tolerant. gRPC is unaffected, since it carries its own BoringSSL inside the grpc gem. Add a job that re-runs the same showcase suite inside ruby:3.2-trixie, which provides OpenSSL 3.5.5, with SHOWCASE_REQUIRE_REST_PQC set. That promotes the tolerant assertion into a hard X25519MLKEM768 requirement and is what actually proves REST post-quantum key exchange works. The job asserts the image's OpenSSL is at least 3.5 before running the suite. Without that check, a future retag of the base image onto an older OpenSSL would silently drop back to the tolerant path and reintroduce exactly the false-green this job exists to prevent. ruby/setup-ruby is deliberately omitted: inside a container it detects debian-13-x64, treats the job as self-hosted, and will not use prebuilt binaries. The image's own Ruby is already linked against the OpenSSL we want. Once ubuntu-latest advances to Ubuntu 26.04, which ships OpenSSL 3.5.5, this job collapses into a single environment variable on the matrix above. --- .github/workflows/ci.yml | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec5655d57..d09808f15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,3 +45,63 @@ jobs: - name: Run CI run: | toys ci + + # The showcase suite above runs on ubuntu-latest, whose system OpenSSL is + # 3.0.13. ML-KEM only exists from OpenSSL 3.5, so the REST transport there + # legitimately falls back to classical X25519 and the post-quantum assertion + # stays tolerant. gRPC is unaffected because it carries its own BoringSSL + # inside the grpc gem. + # + # This job re-runs the same suite on a Debian trixie image (OpenSSL 3.5.5) and + # sets SHOWCASE_REQUIRE_REST_PQC, which promotes that tolerant assertion into + # a hard X25519MLKEM768 requirement. It is what actually proves REST + # post-quantum key exchange works. + # + # Once ubuntu-latest moves to Ubuntu 26.04 (OpenSSL 3.5.5) this job can be + # dropped and SHOWCASE_REQUIRE_REST_PQC set on the matrix above instead. That + # migration starts 2026-10-19 (actions/runner-images#14748). Tracked in + # b/564510736 - check the runner's actual OpenSSL before removing this, + # rather than going by the announced dates. + pqc-rest: + if: ${{ github.repository == 'googleapis/gapic-generator-ruby' }} + runs-on: ubuntu-latest + container: ruby:3.2-trixie + env: + SHOWCASE_REQUIRE_REST_PQC: "1" + steps: + # Deliberately no ruby/setup-ruby: inside a container it detects + # debian-13-x64, treats the job as self-hosted, and will not use the + # prebuilt binaries. The image's own Ruby is already linked against the + # OpenSSL we want. + - name: Checkout repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - name: Checkout submodules + run: | + # actions/checkout writes as the runner user (uid 1001) but this + # container runs as root, so git rejects the tree as dubiously + # owned. The host-runner `tests` job above does not hit this. + git config --global --add safe.directory '*' + git submodule set-url shared/googleapis https://github.com/googleapis/googleapis.git + git submodule set-url shared/gapic-showcase https://github.com/googleapis/gapic-showcase.git + git submodule update --init --recursive + - name: Verify the image provides a post-quantum capable OpenSSL + run: | + ruby -ropenssl -e ' + required = Gem::Version.new "3.5.0" + actual = Gem::Version.new OpenSSL::OPENSSL_LIBRARY_VERSION.split[1] + if actual < required + abort "This job asserts post-quantum key exchange but the image " \ + "provides OpenSSL #{actual}, below the required #{required}." + end + puts "OpenSSL #{actual} supports post-quantum key exchange." + ' + - name: Install dependencies + run: | + gem install --no-document toys + toys bundle install + - name: Run showcase tests + run: | + cd shared + toys test showcase From fec716390a0f3111b358276340c9fe4cab58e3ba Mon Sep 17 00:00:00 2001 From: Torrey Payne <11740989+torreypayne@users.noreply.github.com> Date: Thu, 24 Sep 2026 19:54:27 +0000 Subject: [PATCH 2/2] chore(ci): describe the pqc-rest job in terms of the host-determined REST assertion --- .github/workflows/ci.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d09808f15..7d042c383 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,15 +47,15 @@ jobs: toys ci # The showcase suite above runs on ubuntu-latest, whose system OpenSSL is - # 3.0.13. ML-KEM only exists from OpenSSL 3.5, so the REST transport there - # legitimately falls back to classical X25519 and the post-quantum assertion - # stays tolerant. gRPC is unaffected because it carries its own BoringSSL - # inside the grpc gem. + # 3.0.13. ML-KEM only exists from OpenSSL 3.5, so the REST test there + # expects the classical X25519 fallback. gRPC is unaffected because it + # carries its own BoringSSL inside the grpc gem. # - # This job re-runs the same suite on a Debian trixie image (OpenSSL 3.5.5) and - # sets SHOWCASE_REQUIRE_REST_PQC, which promotes that tolerant assertion into - # a hard X25519MLKEM768 requirement. It is what actually proves REST - # post-quantum key exchange works. + # This job re-runs the same suite on a Debian trixie image (OpenSSL 3.5.5), + # where the REST test expects a post-quantum group instead. It is what + # actually proves REST post-quantum key exchange works. SHOWCASE_REQUIRE_REST_PQC + # makes the suite fail if the image's OpenSSL ever drops below 3.5, rather + # than silently falling back to the classical expectation. # # Once ubuntu-latest moves to Ubuntu 26.04 (OpenSSL 3.5.5) this job can be # dropped and SHOWCASE_REQUIRE_REST_PQC set on the matrix above instead. That