Skip to main content

Scan .github/workflows for known GitHub Actions supply-chain and CI security misconfigurations (unpinned actions, pwn requests, script injection, over-broad permissions).

Project description

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 ($49, 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: write specifically when combined with pull_request_target) — only the unambiguous write-all case is checked today.
  • Traversal into reusable/composite workflows (workflow_call).
  • Pinning checks for docker:// actions.

License

MIT. Author: HiroCheck.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gha_audit-0.1.2.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gha_audit-0.1.2-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file gha_audit-0.1.2.tar.gz.

File metadata

  • Download URL: gha_audit-0.1.2.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for gha_audit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 0ffab734ecfaae6b56de01c0e9716d0ae54ac9c90c8e76087c255aeb61f4c3e9
MD5 454b5fb093de6c8cad6a7cacaf3e3947
BLAKE2b-256 0fb19c05c7efdcd8af8ff21ee5ad49b69851afac696f28e9963794d062ae5849

See more details on using hashes here.

File details

Details for the file gha_audit-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: gha_audit-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for gha_audit-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0fae06002bdb740ed5ed8abccac330a9a6acd934d9fe5598fdc9f6405fd7e26f
MD5 a4f6c800bb7b979bf9fd6d5a16b54ba1
BLAKE2b-256 0df87d3c47664f902c3bb04fb203ccf421061b2b5a65fcbdc9470d817975779b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page