Protecting Yourself
(And Your Poor CI Runners) Against Supply Chain Attacks
Connor Shea, Rocky Mountain Ruby
Step 1: Rewrite everything in Rust.
* This joke was much funnier before last week
Your dependencies
Set a cooldown
Malicious package releases usually get caught within a few hours!
Tool | Setting | Where | Available Since |
Bundler | cooldown | bundle config / --cooldown | 4.0.13+ (June 2026) |
npm | min-release-age | .npmrc | 11.10+ (February 2026) |
pnpm | minimumReleaseAge | pnpm-workspace.yaml | 10.16+ (September 2025) |
yarn | npmMinimalAgeGate | .yarnrc.yml | 4.10+ (September 2025) |
* Note that different package managers use different units of time, make sure to check the docs.
pnpm has had a default cooldown since v11 (April 2026), yarn since 4.15 (May 2026). npm and Bundler must opt-in.
Dependencies
Set a cooldown
Setting a cooldown in your Gemfile is easy!
Dependencies
# this will prevent installing gems newer than 3 days
source 'https://rubygems.org', cooldown: 3
ruby '>= 4.0.6'
gem 'rails', '~> 8.2.0'
“But the tragedy of the commons!”
Worry not: Security companies love finding these things
And you can skip the cooldown if a gem gets a critical security fix:
bundle update rails --cooldown 0
Dependencies
Add checksums to your Gemfile.lock
$ bundle lock --add-checksums
CHECKSUMS
rack (2.1.3) sha256=9ae0d2...
Bundler will confirm the SHA hashes of every gem before installing, so if RubyGems.org or your network get compromised, manipulated gems won’t effect you.
Bundler 4 adds this to new lockfiles by default, but any project from >1 year ago needs to opt-in.
(Requires Bundler 2.6+)
Dependencies
Turn off post-install scripts (or upgrade)
Package manager | Dependency scripts off by default |
npm | v12 (July 2026) |
pnpm | v10 (January 2025) |
yarn | v4.14 (April 2026) |
Post-install scripts run by default and can compromise you very easily if you upgrade a compromised package, disable them! (or upgrade to a version that disables them by default!)
You can enable install scripts per-package via config files/CLI commands, some packages do genuinely need them.
Unfortunately, Bundler has no equivalent setting currently.
Dependencies
CI / CD
Protect your GitHub Actions/GitLab CI setup
Pin GitHub Actions to commit SHAs
# a tag will install the latest version in the range
- uses: connorshea/super-cool-workflow@v3
# a commit SHA will always install the same version forever
- uses: connorshea/super-cool-workflow@<SHA> # v3.1.0
Enforce SHA hashes in settings
In the Actions settings, require workflows to be pinned to a full-length commit SHA.
Dependabot/Renovate will update for you
Dependabot and Renovate update pinned SHAs. You can use pinact to pin your existing actions files (or just ask Claude)
CI / CD
Don't install packages ad-hoc in CI
Bad!
gem install foo
npm install foo
npx is-true
What version does this install? The latest one! And the latest versions of its 30 dependencies!
If you run CI every 5 minutes, even short compromises on npm/RubyGems will ruin your security team’s day
Good :)
BUNDLE_FROZEN="true" bundle install
npm ci
pnpm install --frozen-lockfile
yarn install --immutable
CI / CD
With most of these, you can set these flags in the config file as well.
Lint your CI config with Zizmor
Run zizmor
$ zizmor .github/workflows/
Static analysis for GitHub Actions.
You can automatically enforce a lot of the things I’ve mentioned here!
CI / CD
Check your default GITHUB_TOKEN permissions
Feb 2023
Older repo or org? Every workflow may still get write by default!
In the Actions settings, make sure workflow permissions are set to read by default.
And set permissions per-job to limit what it can do:
permissions:
contents: read
CI / CD
By default with read/write:
Verify binaries you download
Pulling a CLI from a GitHub or GitLab release in a Dockerfile for CI/prod? Make sure it pins to a SHA hash.
ARG TOOL_SHA256=<sha256, committed in your repo>
RUN curl -fsSLo tool.tar.gz "$TOOL_URL" \
&& echo "$TOOL_SHA256 tool.tar.gz" | sha256sum -c -
Otherwise a compromised GitHub release can get you!
CI / CD
Thanks!
Keep your servers safe!
These slides are linked on the schedule if you want to reference them later.