Global Options
These options can be used with any subcommand to modify Pinner's behavior.
-w, --workflows <PATH>
Default: GitHub/GitLab/etc paths
Specify workflow files or directories to process. Can be used multiple times.
-y, --yes
Flag
Automatically confirm all replacements without prompting. Ideal for non-interactive environments.
-d, --dry-run
Flag
Print what would be changed without actually modifying any files.
--format <TYPE>
Values: text, json, markdown
Output results in the specified format. --json is a deprecated alias for --format json.
--concurrency <NUM>
Default: 10
Number of concurrent API requests to make. Increase for large projects, decrease to avoid rate limits.
--ignore <PATTERN>
Multiple
Actions or images to ignore (e.g., "actions/checkout"). Can be used multiple times.
Subcommands
pin
Scans your workflows and replaces all mutable tags with immutable commit SHAs. This is the primary command for securing your supply chain.
upgrade
Updates pinned actions to their latest versions based on the selected --upgrade-strategy.
verify
Checks if all actions in your workflows are pinned. Returns a non-zero exit code if unpinned actions are found. Perfect for CI/CD.
set <ACTION> <HASH>
Forcibly sets a specific action to a provided hash across all matching occurrences in your workflows.
install-hook
Installs a git pre-commit hook in your local repository that automatically runs pinner verify before every commit.
init
Automatically initializes a .pinner.toml configuration file for your repository with sensible defaults.
export-sbom
Generates and exports a Software Bill of Materials (SBOM) for all actions and images used in your workflows.
scan
Queries the OpenSSF OSV database for both current dependency commit hashes and upgrade candidates, performs Cosign/Sigstore signature verification for OCI images, and prompts to save vetted whitelists and compromised blacklists.
generate-completion [SHELL]
Generates shell completion scripts for Bash, Zsh, Fish, Powershell, or Elvish. If the shell is omitted, Pinner will attempt to detect your current shell automatically.
Environment Variables
Pinner automatically reads these variables for authentication and configuration.
Authentication & APIs
| Variable | Description | Default |
|---|---|---|
GITHUB_TOKEN |
Auth token for GitHub API | - |
GITLAB_TOKEN |
Auth token for GitLab API | - |
BITBUCKET_TOKEN |
Auth token for Bitbucket API | - |
FORGEJO_TOKEN |
Auth token for Forgejo/Gitea API | - |
OCI_USERNAME |
Username for OCI Registries (Use AWS for ECR) |
- |
OCI_PASSWORD |
Password for OCI Registries (ECR login token) | - |
Cloud Provider Notes
AWS ECR
To pin private ECR images, pass the token from the AWS CLI:
PINNER_OCI_USERNAME=AWS \
PINNER_OCI_PASSWORD=$(aws ecr get-login-password) \
pinner pin
Azure Marketplace
Azure DevOps tasks are mapped to the microsoft/azure-pipelines-tasks monorepo to resolve SHAs from the latest releases.
CircleCI
Pinner supports pinning Docker images (cimg/*) used in CircleCI workflows. CircleCI Orbs use semantic versions and are not hash-pinned.
Configuration Overrides
Any setting from .pinner.toml can be overridden using an environment variable with the PINNER_ prefix.
| Variable | Description |
|---|---|
PINNER_CONCURRENCY |
Override the number of concurrent API requests. |
PINNER_IGNORE |
Override the list of ignored actions (comma-separated). |
PINNER_GITHUB_URL |
Override the GitHub API URL. |
Configuration File
Create a .pinner.toml file in your repository root to persist settings and share them with your team.
Example .pinner.toml
# Actions to exclude from processing
ignore = ["actions/checkout", "my-org/private-repo"]
# Execution settings
concurrency = 5
# API URL overrides (for Enterprise)
github_url = "https://github.mycompany.com/api/v3"
gitlab_url = "https://gitlab.mycompany.com/api/v4"
# Whitelist of vetted dependency hashes/references (supports plain strings or maps)
vetted = [
# Plain string format (backwards compatible)
"actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332",
# Structured format with original tag and timestamp of insertion
{ ref = "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10", tag = "v6.0.3", timestamp = "2026-06-18T15:28:25Z" }
]
# Blacklist of compromised dependency hashes/references
compromised = [
"actions/checkout@badhash1234567890badhash1234567890bad",
{ ref = "actions/checkout@evilhash1234567890evilhash1234567890bad", tag = "v3.1.0", timestamp = "2026-06-18T15:28:25Z" }
]
# Disable visual security feedback (default: false)
no_security_feedback = false
Global Configuration & Overrides
Pinner automatically loads security configurations from global user locations, allowing you to share whitelists and blacklists across multiple repositories:
~/.cache/pinner/config.toml(Global cache)~/.config/pinner/config.toml(Standard user configuration)~/.pinner.toml(User's home directory configuration)
Precedence (Local Overrides):
The local project-level .pinner.toml file acts as a strict override. If an entry is marked vetted locally, it will override any global compromised entry, and if marked compromised locally, it overrides any global vetted entry. Non-conflicting local and global entries are automatically combined.