Skip to content

chore: add a release cooldown and pin CI actions to commit SHAs - #13

Merged
josemontesdeoca merged 3 commits into
mainfrom
supply-chain-hardening
Aug 7, 2026
Merged

chore: add a release cooldown and pin CI actions to commit SHAs#13
josemontesdeoca merged 3 commits into
mainfrom
supply-chain-hardening

Conversation

@josemontesdeoca

Copy link
Copy Markdown
Member

Two mutable inputs reach this repo without anyone reviewing them: a package version published minutes ago, and whatever commit a third-party action's branch or tag points at when a job starts.

Why

setup-flyctl tracked @master in the deploy job, so an arbitrary future commit would have run inside the job holding the production Fly deploy token, and a tag is no safer since it can be moved to a malicious commit without any version string in the workflow changing. On the registry side, a compromised release is usually caught and yanked within a day or two, and nothing here kept an install off it on day zero.

What changed

  • pnpm-workspace.yaml (new): settings only, this repo is a single package. minimumReleaseAge: 2880 makes anything published in the last 48h unresolvable. minimumReleaseAgeExclude is the escape hatch when a security fix is needed sooner, a reviewable config change rather than a standing hole.
  • package.json: pnpm 10.11.0 to 10.34.5. minimumReleaseAge needs 10.16+, and 10.34.1 is where the integrity-check bypass in CVE-2026-50021 was fixed.
  • Workflows: setup-flyctl and pnpm/action-setup pinned to commit SHAs, with the version kept in a trailing comment. Each SHA is exactly what the ref it replaces resolves to today (master, v1 and 1.6 on flyctl are all one commit), so nothing about these runs changes except the mutability. GitHub-owned actions stay on tags.
  • .github/dependabot.yml (new): SHAs never move on their own, so this is what keeps the pins from rotting. github-actions only, grouped into one PR a month. npm version-update and security-update PRs stay off: frozen-lockfile installs plus the cooldown already handle drift, and advisories get triaged against real exposure rather than auto-patched.
  • verify.yml: pnpm audit --prod with continue-on-error, informational by design. What it reports is dominated by deep transitive packages we do not control, so a blocking gate would be red on day one and routed around by day two. Visible and trending is the point.

Verify

pnpm config get minimumReleaseAge                                           # 2880
git ls-remote https://github.com/superfly/flyctl-actions refs/heads/master  # ed8efb3...
git ls-remote https://github.com/pnpm/action-setup 'refs/tags/v4^{}'        # b906aff...

minimumReleaseAge, available since pnpm 10.16, keeps freshly published
versions unresolvable for 48 hours — the window in which registry
compromises are typically caught and yanked. minimumReleaseAgeExclude
is the escape hatch when a security fix is needed sooner: a reviewable
config change rather than a standing hole.

The pnpm bump also carries the fix for the fail-open integrity check
in CVE-2026-50021. The new workspace file is settings-only; this repo
is a single package, not a pnpm workspace.
setup-flyctl tracked @master in the deploy job — an arbitrary future
commit executing with the Fly deploy token in scope. It now takes the
same SHA platform already pins, which master, 1.6 and v1 all point at,
so nothing moves except the mutability.

pnpm/action-setup follows the same principle: a tag can be retagged at
a malicious commit without any version string in the workflow changing.
Each SHA is what its tag resolves to today, and the trailing version
comment keeps the diff readable.
Reports known advisories in the production graph without gating the
build — the graph carries a sizeable transitive backlog, so a blocking
gate would be red on its first run and ignored soon after. The number
being visible and trending is the point.

Dependabot's github-actions entry keeps the pinned action SHAs current;
without it they silently rot.
@josemontesdeoca josemontesdeoca self-assigned this Aug 7, 2026
@josemontesdeoca
josemontesdeoca requested a review from irl-dan August 7, 2026 23:39
@josemontesdeoca
josemontesdeoca merged commit 93e4795 into main Aug 7, 2026
4 checks passed
@josemontesdeoca
josemontesdeoca deleted the supply-chain-hardening branch August 8, 2026 00:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant