Pinner ๐งช
A high-performance Rust CLI utility to hash-pin your CI/CD dependencies. Secure your supply chain by converting volatile, mutable tags (like @v2) into immutable, cryptographic commit SHAs (like @df4cb1c...).
Why Pin? ๐
Using mutable tags like @v2 or @main in GitHub Actions or other CI/CD providers introduces a security risk. If an attacker gains access to a dependency's repository, they can move the tag to a malicious commit, leading to a supply chain attack on your infrastructure.
Hash-pinning ensures that you run the exact code you've audited, every single time. Pinner automates this process while keeping your workflows readable by appending the original tag as a comment.
Features โจ
- Surgical Replacement: Uses
tree-sitterfor precise YAML parsing, preserving comments, indentation, and formatting perfectly. - Multi-Forge Support: Works with GitHub, GitLab, Bitbucket, and Forgejo/Gitea.
- Tag Preservation: Automatically appends the original tag as a comment (e.g.,
@<hash> # v2). - Container Pinning: Automatically pins Docker images to their immutable digests (e.g.,
image: alpine@sha256:...). - Flexible Upgrades: Multiple strategies to keep your actions up to date (Major, Minor, Latest).
- CI Ready: Includes a
verifymode to ensure all actions remain pinned in your PRs.
Installation ๐ ๏ธ
One-line installation (Recommended)
macOS/Linux:
|
Windows:
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/ffalcinelli/pinner/main/install.ps1 | iex"
From source
Usage ๐
1. Pin all actions
Scans workflows and converts all tags to pinned hashes.
Input: - uses: actions/checkout@v3
Output: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
2. Upgrade to latest
Update pinned actions to their latest versions based on a strategy.
[!CAUTION] Automatic upgrades can undermine your security. The primary goal of hash-pinning is to ensure you run only code you have vetted. While
verifyshould be run in every CI pipeline to enforce this,upgradeshould be used as an intentional step in your development process, followed by a review of the new version to maintain the integrity of your supply chain. Automated, unvetted upgrades re-introduce the very supply chain risks that hash-pinning is designed to prevent.
# Default: Upgrade to latest available release
# Upgrade only within the current major version (e.g., v2.1.0 -> v2.4.5)
3. Verify pinning
Ensure that all actions in your workflows are pinned. Perfect for CI pipelines.
Configuration โ๏ธ
Pinner can be configured via a .pinner.toml file in your repository root.
# List of actions to ignore during pinning/upgrading
= ["my-org/private-action"]
# Number of concurrent API requests (default: 10)
= 5
# Custom API URLs (for Enterprise instances)
= "https://github.mycompany.com/api/v3"
= "https://gitlab.mycompany.com/api/v4"
Supported Forges ๐
Pinner supports multiple CI/CD and git hosting platforms:
| Forge | Command | Env Var for Token |
|---|---|---|
| GitHub | pinner pin |
GITHUB_TOKEN |
| GitLab | pinner pin |
GITLAB_TOKEN |
| Bitbucket | pinner pin |
BITBUCKET_TOKEN |
| Forgejo/Gitea | pinner pin |
FORGEJO_TOKEN |
CI/CD Integration ๐ค
Add this to your workflow to ensure all actions stay pinned:
jobs:
verify-pinning:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v4
- name: Install Pinner
run: curl -LsSf https://raw.githubusercontent.com/ffalcinelli/pinner/main/install.sh | sh
- name: Verify Pinning
run: pinner verify
Name Origin โ๏ธ
The name Pinner is inspired by the Pinner reaction in organic chemistry. Discovered by Adolf Pinner, this reaction involves the acid-catalyzed conversion of a reactive nitrile into a highly stable Pinner salt.
Just as the Pinner reaction transforms a volatile compound into a stable, fixed salt, this CLI transforms "floating" tags into secure, immutable, and fixed commit SHAs.
License ๐
MIT License. See LICENSE for details.