From 22185c23dbf4a66f9a6ededf1fbb220abd97c618 Mon Sep 17 00:00:00 2001 From: DecIntercom Date: Wed, 5 Aug 2026 14:06:09 +0100 Subject: [PATCH 1/2] Route CI gem installs through a scanning registry mirror MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `bundle install` resolved straight from rubygems.org over plaintext HTTP, with no install-time scanning of build dependencies. Two changes are needed, not one: - Point Bundler's rubygems.org mirror at the scanning registry, with the credential supplied by CI rather than committed. - Switch the Gemfile source to https. Bundler matches mirrors by exact source URI including scheme, so a `mirror.https://rubygems.org` setting does not apply to a Gemfile declaring `http://rubygems.org` — the mirror would have been configured but never used. The step fails the build if the mirror is not active. Forked pull requests are the exception: CI does not share credentials with forks, so those builds log that they are unrouted and continue rather than failing a contributor. Co-Authored-By: Claude Opus 5 (1M context) --- .circleci/config.yml | 42 +++++++++++++++++++++++++++++++++++++----- Gemfile | 2 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 23fcf9e1..42a81a45 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,28 @@ -version: 2 +version: 2.1 + +commands: + configure_bundler: + steps: + - run: + name: Route Bundler through the Socket Firewall registry + command: | + set -euo pipefail + if [ -z "${SOCKET_GEM_URL:-}" ]; then + # CircleCI does not share context credentials with forked PRs, so a + # fork cannot be routed. Say so rather than failing the contributor. + if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then + echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org." + exit 0 + fi + echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)" + exit 1 + fi + # Legacy two-argument form: these images ship Bundler 1.x, where + # `bundle config set --global` does not exist and silently no-ops. + bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL" + bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \ + || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; } + jobs: "Test against Ruby 2.4": docker: @@ -6,6 +30,7 @@ jobs: working_directory: ~/intercom-ruby steps: - checkout + - configure_bundler - run: bundle install - run: bundle exec rake "Test against Ruby 2.5": @@ -14,6 +39,7 @@ jobs: working_directory: ~/intercom-ruby steps: - checkout + - configure_bundler - run: bundle install - run: bundle exec rake "Test against Ruby 2.6": @@ -22,6 +48,7 @@ jobs: working_directory: ~/intercom-ruby steps: - checkout + - configure_bundler - run: bundle install - run: bundle exec rake @@ -29,7 +56,12 @@ workflows: version: 2 build_and_test: jobs: - - "Test against Ruby 2.4" - - "Test against Ruby 2.5" - - "Test against Ruby 2.6" - + - "Test against Ruby 2.4": + context: + - socket-firewall + - "Test against Ruby 2.5": + context: + - socket-firewall + - "Test against Ruby 2.6": + context: + - socket-firewall diff --git a/Gemfile b/Gemfile index 4516ffc0..0cfe52d3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source "http://rubygems.org" +source "https://rubygems.org" gem 'webmock' gemspec From 738e95277425c2a5d1ebc6e1966e23ce1a61233f Mon Sep 17 00:00:00 2001 From: DecIntercom Date: Wed, 5 Aug 2026 15:21:54 +0100 Subject: [PATCH 2/2] Keep the config on version 2 Bumping to 2.1 to share the mirror step across the three jobs errored the pipeline: 2.1 validates job names against ^[A-Za-z][A-Za-z\s\d_-]*$ and the existing names contain dots ("Test against Ruby 2.4"). Renaming them would change the status check names, so the step is repeated per job on version 2 instead. Slightly more duplication, no behaviour change. --- .circleci/config.yml | 52 +++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 42a81a45..ce245629 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,8 +1,11 @@ -version: 2.1 - -commands: - configure_bundler: +version: 2 +jobs: + "Test against Ruby 2.4": + docker: + - image: circleci/ruby:2.4.9 + working_directory: ~/intercom-ruby steps: + - checkout - run: name: Route Bundler through the Socket Firewall registry command: | @@ -22,15 +25,6 @@ commands: bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL" bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \ || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; } - -jobs: - "Test against Ruby 2.4": - docker: - - image: circleci/ruby:2.4.9 - working_directory: ~/intercom-ruby - steps: - - checkout - - configure_bundler - run: bundle install - run: bundle exec rake "Test against Ruby 2.5": @@ -39,7 +33,21 @@ jobs: working_directory: ~/intercom-ruby steps: - checkout - - configure_bundler + - run: + name: Route Bundler through the Socket Firewall registry + command: | + set -euo pipefail + if [ -z "${SOCKET_GEM_URL:-}" ]; then + if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then + echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org." + exit 0 + fi + echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)" + exit 1 + fi + bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL" + bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \ + || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; } - run: bundle install - run: bundle exec rake "Test against Ruby 2.6": @@ -48,7 +56,21 @@ jobs: working_directory: ~/intercom-ruby steps: - checkout - - configure_bundler + - run: + name: Route Bundler through the Socket Firewall registry + command: | + set -euo pipefail + if [ -z "${SOCKET_GEM_URL:-}" ]; then + if [ -n "${CIRCLE_PR_REPONAME:-}" ]; then + echo "Forked PR: no Socket Firewall credentials available, gems will come from rubygems.org." + exit 0 + fi + echo "FATAL: SOCKET_GEM_URL is required (provided by the socket-firewall context)" + exit 1 + fi + bundle config mirror.https://rubygems.org "$SOCKET_GEM_URL" + bundle config mirror.https://rubygems.org | grep -q socket-firewall-registry \ + || { echo "FAIL: bundler mirror not pointing at Socket Firewall"; exit 1; } - run: bundle install - run: bundle exec rake