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.
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 | |
|---|---|---|---|
| gha_audit-0.1.3.tar.gz | 17.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gha_audit-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
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
|