Safeguard
Supply Chain•

What does pinned dependencies mean, and will a buyer check it?

A pinned dependency is fixed to an exact version or hash instead of a moving range. Here is what to pin, what to leave, and how to explain the choice.

Safeguard Security Team
4 min read

A pinned dependency is set to a specific version or hash, not a range or a moving tag. Pinning means a build today and a build next month use the same inputs, unless you change them on purpose. Buyers check it because unpinned inputs let unreviewed code reach production.

Definition

OpenSSF Scorecard's Pinned-Dependencies check describes a pinned dependency as one explicitly set to a specific hash instead of a mutable version or range. It looks for unpinned dependencies in places such as Dockerfiles and shell scripts, and it currently supports repositories hosted on GitHub. It rates the risk as medium, with the concern being possible compromised dependencies.

Pinning applies in several places, and each has its own file.

WhereUnpinned examplePinned form
Application packagesA version range in a manifestExact versions in a lock file
Container base imageA tag that movesAn image digest
Workflow actionsA branch or tagA full commit SHA
Build scriptsDownloading latestA fixed version with checksum

Why pinning helps

If a maintainer account is compromised and a malicious release is published, a range such as "any 2.x" may pull it into your next build automatically. A pin stops that until someone updates it. GitHub's hardening guidance makes the same argument for actions: pinning to a full commit SHA means an attacker would need a hash collision to slip in a change.

The cost

Pins age. A pinned dependency with a known vulnerability stays vulnerable until updated, and GitHub generates alerts for actions just when they use semantic versioning, not SHA pinning. Pinning therefore needs a companion: an update bot or a regular review that proposes new versions with tests.

Steps

  1. Commit lock files for every application, and make CI install from them.
  2. Pin container base images by digest, and rebuild on a schedule to pick up security patches.
  3. Pin workflow actions to commit SHAs with a comment naming the version.
  4. Replace "download latest" lines in scripts with fixed versions and checksum checks.
  5. Turn on an update tool so pins move forward in reviewed pull requests.
  6. Record the policy in one paragraph.

What not to pin

Libraries you publish for others should declare compatible ranges, since consumers need room to resolve. Keep the lock file for your own CI and testing. Say in documentation which is which.

What a buyer sees

Scorecard output on your repositories, or a quick scan of your Dockerfiles and workflows. "Pinned by digest, updated weekly through reviewed pull requests" is a good sentence. "We use latest to stay current" is not.

A realistic target

Perfect pinning is unusual. Start with production build paths: the main service Dockerfile, release workflows and anything touching signing or publishing credentials. Expand from there and note the rest in your known gaps.

Try it yourself

Click through it at your own pace, or open it full screen.

See how exact versions appear in an inventory, which is what a lock file gives you and a range does not.

Safeguard generates SBOMs and scans dependencies with their resolved versions. A free scan shows what is resolved in a repository today.

Quick check

Does pinning make me safe from malicious packages?

It reduces automatic exposure to a new bad release. A package that was already malicious when you pinned it stays malicious, so review matters too.

How often should pins be updated?

Set a regular cadence, such as weekly pull requests, with faster updates for known exploited vulnerabilities.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.