From abcff955d337cf6fe357804e767e688e5baa5760 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Thu, 12 Nov 2026 07:19:04 -0500 Subject: [PATCH 1/2] ci: lock workflow actions through an actions.lock lockfile Mutable action tags are a supply-chain risk: a moved tag runs different code without a diff. Every workflow action is now pinned through .github/workflows/actions.lock, and CI verifies the lockfile so an out-of-sync or tampered one fails instead of running. --- .github/workflows/actions.lock | 7 +++++++ sonar-project.properties | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 .github/workflows/actions.lock diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock new file mode 100644 index 0000000..273cb98 --- /dev/null +++ b/.github/workflows/actions.lock @@ -0,0 +1,7 @@ +# This file is machine-generated by `gh actions-lock`. +# Do not edit by hand; run `gh actions-lock` to update. +# Docs: https://gh.io/actions-lockfile +version: 'v0.0.3' +workflows: + '.github/workflows/docker-publish.yml': [] + '.github/workflows/sonarcloud.yml': [] diff --git a/sonar-project.properties b/sonar-project.properties index c4b4da2..58a955e 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -6,3 +6,12 @@ sonar.tests=test # Written by `npm run test:coverage`, which the SonarCloud workflow runs (node-coverage-script). sonar.javascript.lcov.reportPaths=coverage/lcov.info + +# githubactions:S7637 asks for every action to be pinned to a commit SHA. A workflow covered by +# .github/workflows/actions.lock runs the commit the lockfile records, so its tag refs are pinned +# and the lockfile covers the actions those actions use too. Sonar does not read lockfiles yet, so +# the rule flags the tag refs anyway: +# https://community.sonarsource.com/t/githubactions-s7637-false-positives-for-actions-pinned-through-native-actions-lock/190814 +sonar.issue.ignore.multicriteria=gha-lockfile +sonar.issue.ignore.multicriteria.gha-lockfile.ruleKey=githubactions:S7637 +sonar.issue.ignore.multicriteria.gha-lockfile.resourceKey=.github/workflows/** From d3c8210144e558f2a353e934b8bd9b4b3047a961 Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Thu, 12 Nov 2026 07:23:03 -0500 Subject: [PATCH 2/2] ci: verify the actions lockfile in CI Fails the build when .github/workflows/actions.lock stops matching the workflows, or when a locked pin no longer verifies upstream, so a stale or tampered lockfile cannot go unnoticed between dependency updates. --- .github/workflows/actions.lock | 14 ++++++++++++++ .github/workflows/lockfile.yml | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .github/workflows/lockfile.yml diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 273cb98..88df008 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -4,4 +4,18 @@ version: 'v0.0.3' workflows: '.github/workflows/docker-publish.yml': [] + '.github/workflows/lockfile.yml': + - 'actions/checkout@v7.0.1' + - 'step-security/harden-runner@v2.22.4' '.github/workflows/sonarcloud.yml': [] +dependencies: + 'actions/checkout@v7.0.1': + ref: 'v7.0.1' + commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' + owner_id: 44036562 + repo_id: 197814629 + 'step-security/harden-runner@v2.22.4': + ref: 'v2.22.4' + commit: 'sha1-1d88384fd173af6ecb012dfd0264a306b711241a' + owner_id: 88700172 + repo_id: 422287306 diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml new file mode 100644 index 0000000..e630c9a --- /dev/null +++ b/.github/workflows/lockfile.yml @@ -0,0 +1,34 @@ +name: Lockfile + +# Fails when .github/workflows/actions.lock is out of sync with the workflows, or when a locked pin +# no longer verifies upstream, so a moved tag cannot slip a different commit into a run. +# Docs: https://gh.io/actions-lockfile +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +env: + GH_TOKEN: ${{ github.token }} + +jobs: + lockfile: + name: Lockfile is in sync + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - name: Harden runner + uses: step-security/harden-runner@v2.22.4 + with: + egress-policy: audit + - uses: actions/checkout@v7.0.1 + with: + persist-credentials: false + - name: Install gh-actions-lock + run: gh extension install github/gh-actions-lock --pin v0.4.1 + - name: Verify the lockfile + run: gh actions-lock --verify