gha-audit
Scan .github/workflows/*.yml for known GitHub Actions supply-chain and
CI security misconfigurations, before they become an incident.
pip install gha-audit
gha-audit .
What it catches
| Check | Severity | Real-world pattern |
|---|---|---|
unpinned-action |
warn | uses: owner/repo@main (or any tag) instead of a full commit SHA. A mutable ref can be repointed to run different code without a corresponding change in your repo to review — this is exactly how the tj-actions/changed-files compromise played out in 2025. |
pull-request-target-checkout |
error | A workflow triggers on pull_request_target (runs with your repo's secrets and write token) and checks out the pull request's own head. A fork's PR can then run its own code with your secrets — the canonical "pwn request" pattern. |
script-injection |
error | A run: step interpolates ${{ github.event.issue.title }} (or PR title/body, comment body, github.head_ref, ...) directly into the shell command. These values are attacker-controlled and are substituted as raw text before the shell runs — arbitrary shell input is possible. |
broad-permissions |
warn | Top-level permissions: write-all. GitHub's own hardening guide recommends the opposite: grant only the specific scopes each job needs. |
All four are static, deterministic checks with no network access beyond
reading files already in your checkout — gha-audit never executes or
fetches the actions it inspects.
Usage
gha-audit . # scan the current repo, human-readable output
gha-audit path/to/repo # scan a different path
gha-audit --json . # machine-readable output
gha-audit --strict . # also fail (non-zero exit) on 'warn' findings, not just 'error'
Exit code is 0 when nothing is found (or only warn-level findings
without --strict), 1 when an error-level finding exists.
(gha-audit . is shorthand for gha-audit scan . — both work.)
Pro: HTML audit report
The scan above is free and unrestricted. For a standalone HTML report you
can hand to a reviewer, attach to a PR, or archive for a security audit,
gha-audit report is a paid feature ($99, one-time license key):
gha-audit report . --license-key <KEY> -o audit.html
Unlock it here: https://buy.stripe.com/6oU9AU3xigSZedP90WdMI03
(the key can also be set via the GHA_AUDIT_KEY environment variable
instead of --license-key). The free gha-audit scan behavior is
completely unaffected — only the report export is gated.
Accuracy
Measured against a labelled fixture corpus (tests/test_accuracy.py),
each fixture isolated to exercise exactly one check:
- Recall: 100.00% (8/8 known-vulnerable fixtures detected)
- False-positive rate: 0.00% (0/7 known-safe fixtures flagged)
Numbers are transcribed from the test harness's own output, not narrated.
What it doesn't do (yet)
- Trigger-aware permissions analysis (e.g. flagging
contents: writespecifically when combined withpull_request_target) — only the unambiguouswrite-allcase is checked today. - Traversal into reusable/composite workflows (
workflow_call). - Pinning checks for
docker://actions.
License
MIT. Author: HiroCheck.
Metadata
Release files for gha-audit 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gha_audit-0.1.3.tar.gz | 17.2 kB | Without provenance | Details for gha_audit-0.1.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| gha_audit-0.1.3-py3-none-any.whl | Python 3 | none | any | Details for gha_audit-0.1.3-py3-none-any.whl |
Total release size: 33.7 kB
Release files / gha_audit-0.1.3.tar.gz
| Download URL | gha_audit-0.1.3.tar.gz |
|---|---|
| Size | 17.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
32952f5212eeaab71c3b0a686339b4fd8f88a2dc57b57155ee62b86f487b2b58
|
|
BLAKE2b-256 checksum How to use checksums |
27d7536804f74fa6d457ecf4f6adfefca81f8f5dc126c16c3fc87f1470ddd1d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / gha_audit-0.1.3-py3-none-any.whl
| Download URL | gha_audit-0.1.3-py3-none-any.whl |
|---|---|
| Size | 16.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dadef0e506a68db8536fb67dc5aec65d7c0d3f24f108e569168ecd9df6f68389
|
|
BLAKE2b-256 checksum How to use checksums |
b45bb463a0365af9947f92996f809fca9b24c9f068fdd48ad72c1559b4f61909
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for gha-audit 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.