Skip to content

Scorecard's PinnedDependencies is wrong for lockfile-enforced repos — 79 alerts on _pathroot, inline pinning would break CI #674

Description

@hyperpolymath

Owner ruling 2026-08-27: raise this upstream; do not work around it. Recording the finding and the evidence so the position is documented and reproducible.

The conflict

OSSF Scorecard's PinnedDependenciesID flags uses: actions/checkout@v7.0.1 as unpinned. On metadatastician/_pathroot that produces 79 alerts (68 PinnedDependenciesID + 11 CodeQL actions/unpinned-tag) — 52% of the repo's 151 open alerts — and with code_scanning threshold all, every one of them blocks every PR.

But the repo is lockfile-enforced, and on such repos that ref is pinned.

Why the lockfile is strictly stronger than an inline SHA

.github/workflows/actions.lock records, per dependency:

'actions/attest-build-provenance@v4.2.2':
ref: 'v4.2.2'commit: 'sha1-4d101475d8b20a2381f78447822ac1eab6504dd8'owner_id: 44036562repo_id: 760702757uses:
- 'actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d'

An inline SHA gives you the commit only. The lockfile additionally binds:

fieldwhat it defends againstinline SHA
committag repointing✅ equivalent
owner_id / repo_idrepo takeover / rename-squatting — a different repo reusing the same path❌ not expressed
uses:transitive dependencies of composite actions❌ cannot be expressed at all

So converting to inline SHAs reduces supply-chain coverage.

And it actively breaks the workflows

Measured previously on hypatia: inline-pinning 40 refs across 21 workflows produced

  • 14 workflows → startup_failure (0 on the parent commit) — the lockfile no longer matched, so they were rejected before any job started;
  • dtolnay/rust-toolchain dropped from 7 lockfile entries;
  • both required CodeQL contexts became phantom — a workflow that never starts never reports — so PRs read as BLOCKED with no failing check.

Reverting restored all of it. gh actions-lock also refuses a ref that no tag or branch contains ("a symbolic ref is required for the lockfile"), so inline-pinning a commit that is not tag-reachable removes it from the lockfile entirely.

Verified on _pathroot today: gh actions-lock --no-fix reports all 32 workflows valid, while Scorecard reports 68 unpinned dependencies for the same tree.

Position

Scorecard has no knowledge of actions.lock and evaluates the uses: string in isolation. For lockfile-enforced repositories its PinnedDependenciesID finding is factually wrong, and acting on it degrades security and breaks CI.

Not being worked around per the ruling — no threshold change, no dismissals, no inline pinning. The path is upstream: Scorecard should recognise .github/workflows/actions.lock and treat a ref it covers as pinned.

An upstream report is drafted and ready to file against ossf/scorecard on request.

Related: standards#655, _pathroot#18.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions