Audited Actions
pinprick maintains a list of GitHub Actions that have been scanned and confirmed to have zero runtime fetch findings. When auditing, actions in this list are skipped — avoiding redundant API calls and scans.
Lookup order
Section titled “Lookup order”- Bundled — compiled into the binary at build time. Same trust as the binary itself.
- Local cache —
~/.cache/pinprick/audited/. Populated automatically when you scan an action and it comes back clean. - Remote —
https://pinprick.rs/audited-actions/. Opt-in viafetch-remote = truein your config file. - GitHub API — full source fetch and scan as last resort.
Remote catalog signing
Section titled “Remote catalog signing”A remote catalog entry tells pinprick to skip scanning a SHA, so its integrity matters more than TLS alone can guarantee — a compromised CDN must not be able to mark malicious SHAs as audited. Every catalog file is therefore signed with minisign: the signature is served next to the file (….json.minisig), and the pinprick binary verifies it against a public key embedded at build time before honoring any entry.
Verification is fail-closed. A missing or invalid signature — or a binary built without the public key — disables the remote layer entirely, and pinprick falls back to scanning via the GitHub API. Nothing is silently trusted.
What “audited” means
Section titled “What “audited” means”Each SHA was scanned for unversioned runtime fetch patterns. Specifically:
- Shell: pipe-to-shell,
curl/wgetto/latest/or unversioned URLs,gh release downloadwithout a tag, unpinnedgit clone,go install @latest, and unpinned package installs - PowerShell: pipe-to-shell equivalents,
Invoke-WebRequest/iwr/Invoke-RestMethod/irmto/latest/or unversioned URLs, and unpinnedInstall-Module/Install-Script - JavaScript:
fetch()/axios/got/http.getto/latest/or unversioned URLs,exec()/child_processshelling out tocurl - Python:
urllib.request.urlopen/requests.getto/latest/or unversioned URLs,subprocessshelling out tocurl/wget - Docker:
FROM :latestor untagged,curl/wgetinRUNinstructions, and remoteADDsources
A clean repository-level audit also covers actions exposed from subpaths at the same SHA. A clean subpath audit applies only to that subpath, not to sibling actions or the repository as a whole.
What “audited” does NOT mean
Section titled “What “audited” does NOT mean”This is not a full security review. An action listed as audited may still:
- Fetch resources from dynamically constructed URLs
- Execute code from inputs or environment variables
- Have vulnerabilities unrelated to runtime fetching
- Contain patterns in languages pinprick does not scan (Ruby, Go)
For static analysis of workflow files — permissions, template injection, credential handling — use zizmor.
Why the SHA is permanent
Section titled “Why the SHA is permanent”A SHA is a commit hash. If any file in the commit changes — including dist/index.js — the hash changes. So an audit result for a SHA is deterministic and permanent.
Contributing
Section titled “Contributing”To add a new entry to the audited-actions list:
- Run
pinprick auditagainst a repository using the action at the SHA you want to add - Confirm zero findings
- Add the SHA and tag to the appropriate JSON file in
audited-actions/{owner}/{repo}.json - Open a PR
Each file is a JSON array:
[{ "sha": "9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0", "tag": "v7.0.0" }]