SEC001 — unpinned-action¶
Severity: blocker · Category: Security
What it checks¶
Flags any uses: reference to a third-party action (or reusable
workflow) that isn't pinned to a full 40-character commit SHA — a
mutable tag like @v4 or a branch like @main instead.
Why it matters¶
Tags and branches can be moved. If an action's maintainer's account is
compromised — or a malicious actor gains write access to the action's
repo — they can silently repoint @v4 at a different commit without
anyone's workflow file changing at all. Every consumer picks up the new
code on their very next run. A commit SHA can't be moved; it's the only
form of uses: reference that's actually immutable.
Examples¶
Flagged — the ref after @ is a mutable tag:
steps:
- uses: actions/checkout@v4
- uses: some-org/deploy-action@main
Fixed — pinned to a full commit SHA, with the human-readable version kept as a trailing comment so it's still easy to see at a glance:
steps:
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.2.2
- uses: some-org/deploy-action@f1a2b3c4d5e6f7890123456789abcdef0123456 # v2.1.0
Local actions (uses: ./my-action) and Docker actions
(uses: docker://alpine:3.19) are exempt — there's no equivalent SHA to
pin for either.
Suppressing¶
- uses: actions/checkout@v4 # vlotpipe: ignore[SEC001]
Only do this for actions you fully trust and actively monitor — this is
the rule with the strongest real-world evidence behind it (see
docs/SECURITY_RESEARCH.md's account of the tj-actions/changed-files
incident, where every tag-pinned consumer was compromised
simultaneously).