Third-party action is not pinned by commit SHA
Control: Third-party actions must be pinned by commit SHAยท Config key: actionsMustBePinnedByCommitSha
๐ What is this?
A workflow step (or a job-level reusable-workflow call) references a third-party action by a mutable ref (tag like v4 or branch like main) instead of a 40-character commit SHA.
โ ๏ธ Impact
Tag and branch refs are mutable. The March 2025 tj-actions/changed-files compromise (CVE-2025-30066) retagged a stable version to point at malicious code that exfiltrated repo secrets from every CI run consuming the action, and there were thousands of them.
๐ง How to fix
Replace each uses: owner/repo@vX with uses: owner/repo@<40-char-sha> # vX.Y.Z. Use Dependabot or Renovate to bump the SHA when upstream releases.
# .github/workflows/test.yml: โ Mutable refs everywherejobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: tj-actions/changed-files@v45 - uses: some-third-party/action@main# .github/workflows/test.yml: โ
Pinned by SHAjobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: tj-actions/changed-files@cc733854b1f224978ef800d29e4709d5ee2883e4 # v46.0.5 - uses: some-third-party/action@a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4 # v2.1.0
# .plumber.yaml: skip first-party actionsgithub: controls: actionsMustBePinnedByCommitSha: enabled: true trustedOwners: [actions, github]๐ก Tips
- List
actionsandgithubundertrustedOwnersto skip the rule for first-party GitHub-owned actions. - Local actions (
uses: ./.github/actions/foo) are always exempt because they live in the same repo. - Pair with ISSUE-702, ISSUE-707 and ISSUE-709 for a complete supply-chain ruleset (archived repos, impostor SHAs, stale pins).
โ๏ธ Configuration
This control is configured in .plumber.yaml under the github section:
github:
controls:
actionsMustBePinnedByCommitSha:
enabled: trueSee the CLI documentation for the full configuration reference.