Static security scanner for GitHub Actions workflows.
Project description
ActionAudit
Static security scanner for GitHub Actions workflows.
ActionAudit reads .github/workflows/*.yml, parses the YAML, and runs a set of
security rules over it. Each finding comes with the exact location
(workflow.yml:42), a severity, an OWASP CI/CD category, a human-readable
explanation of why it is dangerous, and how to fix it.
Why ActionAudit
- Local-first and deterministic. No network calls during a scan, no AI in the core. The same input always produces the same output.
- Educational. Every finding explains the risk and the fix, not just the
rule name.
actionaudit explain <rule>gives the full background. - Standards-aligned. Every rule maps to an OWASP Top 10 CI/CD Security Risk.
- Multiple output formats. Coloured terminal, dark-theme HTML, JSON, and SARIF for GitHub Code Scanning.
Install
pip install actionaudit
Or from source:
git clone https://github.com/YusufKaramuk1/actionaudit.git
cd actionaudit
pip install -e .
Usage
# Scan the workflows in the current repository
actionaudit scan .
# Scan a specific file or directory
actionaudit scan .github/workflows/ci.yml
# Produce an HTML or SARIF report
actionaudit scan . --format html --output report.html
actionaudit scan . --format sarif --output results.sarif
# Fail the process (exit 1) if a HIGH+ finding exists -- useful in CI
actionaudit scan . --fail-on high
# List and explain rules
actionaudit list-rules
actionaudit explain expression-injection-in-run
Advanced usage
# Apply a built-in profile: strict / balanced / education
actionaudit scan . --profile strict
# Load configuration from a declarative YAML policy file (no code execution)
actionaudit scan . --policy actionaudit-policy.yml
# Brownfield adoption: capture a baseline, then fail only on NEW findings
actionaudit scan . --format json --output baseline.json
actionaudit scan . --baseline baseline.json --fail-on high
See Configuration and Custom rules below for the --policy schema and
--rules-dir.
Use as a GitHub Action
Add ActionAudit to any repository's workflow:
- uses: YusufKaramuk1/actionaudit@v1.4.0
with:
path: .github/workflows
fail-on: high
Findings are emitted as inline annotations on the pull request, and the step
fails when a finding at or above fail-on is present.
Use as a pre-commit hook
Add ActionAudit to .pre-commit-config.yaml:
repos:
- repo: https://github.com/YusufKaramuk1/actionaudit
rev: v1.4.0
hooks:
- id: actionaudit
The hook runs whenever a workflow file changes and fails the commit on a
HIGH-or-above finding (override with args: ['--fail-on', 'critical']).
Rules
| ID | Severity | OWASP | What it catches |
|---|---|---|---|
expression-injection-in-run |
CRITICAL | CICD-SEC-4 | Untrusted ${{ ... }} input interpolated into a run: script |
pull-request-target-with-checkout |
CRITICAL | CICD-SEC-4 | pull_request_target workflow checking out PR head code (Pwn Request) |
workflow-dispatch-input-injection |
HIGH | CICD-SEC-4 | Workflow input interpolated into a run: script |
dangerous-workflow-run-chain |
HIGH | CICD-SEC-4 | workflow_run workflow consuming an upstream workflow's artifacts |
untrusted-artifact-execution |
HIGH | CICD-SEC-3 | A downloaded artifact executed in the same job without verification |
github-token-write-all |
HIGH | CICD-SEC-5 | permissions: write-all or no permissions: block |
third-party-action-not-pinned-sha |
HIGH | CICD-SEC-3 | Third-party action pinned to a mutable tag instead of a commit SHA |
hardcoded-secret |
HIGH | CICD-SEC-6 | Literal credential (AWS / GitHub / Stripe / Slack / PEM) in the file |
inline-curl-pipe-bash |
MEDIUM | CICD-SEC-3 | Remote script piped straight into a shell |
actions-cache-poisoning-risk |
MEDIUM | CICD-SEC-3 | Cache key derived from PR-controlled input |
taint-propagation-via-env |
MEDIUM | CICD-SEC-4 | Untrusted input reaching a run: shell via env (unquoted / eval) |
persist-credentials-default-true |
MEDIUM | CICD-SEC-6 | actions/checkout keeping the default credential persistence |
self-hosted-runner-fork-trigger |
MEDIUM | CICD-SEC-7 | Self-hosted runner reachable by forked pull requests |
bash-with-set-x |
LOW | CICD-SEC-10 | Shell debug tracing (set -x) that can leak secrets into logs |
Output formats
--format terminal(default) — coloured summary in the console.--format json— stable JSON schema for automation.--format html— standalone dark-theme report with per-finding remediation.--format sarif— SARIF v2.1.0 for GitHub Code Scanning.
Configuration
Add a [tool.actionaudit] section to pyproject.toml:
[tool.actionaudit]
disabled_rules = ["bash-with-set-x"]
[tool.actionaudit.severity]
hardcoded-secret = "critical"
To suppress a single finding, add an inline comment on the offending line (or the line just above it):
- uses: tj-actions/changed-files@v44 # actionaudit: ignore third-party-action-not-pinned-sha
Custom rules
Write organisation-specific rules and load them alongside the built-in ones
with --rules-dir:
actionaudit scan . --rules-dir ./company-rules/
Each .py file in the directory may define Rule subclasses (see
CONTRIBUTING.md for the contract). Note: --rules-dir
imports and executes the Python files it finds — only point it at directories
you trust.
Philosophy
ActionAudit only scans GitHub Actions workflow files. It is not a runtime monitor, not a generic secret scanner, and not a multi-platform CI tool — that focus is deliberate. See ROADMAP.md for what is planned and what is intentionally out of scope.
Development
pip install -e ".[dev]"
pytest
ruff check src tests
mypy src
See CONTRIBUTING.md for how to add a rule.
Türkçe özet
ActionAudit, GitHub Actions iş akışlarındaki (.github/workflows/*.yml)
güvenlik açıklarını ve hatalı yapılandırmaları statik olarak tespit eden,
yerel çalışan, deterministik bir CLI tarayıcısıdır. Her bulgu; kesin konum
(workflow.yml:42), önem derecesi, OWASP CI/CD kategorisi, riskin neden
tehlikeli olduğunun açıklaması ve nasıl düzeltileceği ile birlikte raporlanır.
git clone https://github.com/YusufKaramuk1/actionaudit.git
cd actionaudit && pip install -e .
actionaudit scan .
Şu an 14 kural içerir ve her biri OWASP Top 10 CI/CD risk kategorilerinden
biriyle eşleştirilmiştir. Çıktı biçimleri: terminal, JSON, koyu temalı HTML,
SARIF ve GitHub annotation'ları. Yapılandırma pyproject.toml'daki
[tool.actionaudit] bölümünden, --profile / --policy ile veya satır içi
# actionaudit: ignore yorumlarıyla yapılır; --baseline ile yalnızca yeni
bulgular raporlanabilir.
License
MIT — see LICENSE.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file actionaudit-1.4.1.tar.gz.
File metadata
- Download URL: actionaudit-1.4.1.tar.gz
- Upload date:
- Size: 46.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85ef169f837428eb728e15ad3e92ffa3ccb57a61406b89866d9102212c59165a
|
|
| MD5 |
db8b58e60bb57c1da0af4dfbcb1cd37c
|
|
| BLAKE2b-256 |
28cde659649e50b20ed2a8ad0baef244c6cfa1fa2c3166da51c02f521bd599e5
|
Provenance
The following attestation bundles were made for actionaudit-1.4.1.tar.gz:
Publisher:
publish.yml on YusufKaramuk1/actionaudit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actionaudit-1.4.1.tar.gz -
Subject digest:
85ef169f837428eb728e15ad3e92ffa3ccb57a61406b89866d9102212c59165a - Sigstore transparency entry: 1659927978
- Sigstore integration time:
-
Permalink:
YusufKaramuk1/actionaudit@4002176922d87e0e5e7a64d1dc12729f8ca7c3ca -
Branch / Tag:
refs/tags/v1.4.1 - Owner: https://github.com/YusufKaramuk1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4002176922d87e0e5e7a64d1dc12729f8ca7c3ca -
Trigger Event:
release
-
Statement type:
File details
Details for the file actionaudit-1.4.1-py3-none-any.whl.
File metadata
- Download URL: actionaudit-1.4.1-py3-none-any.whl
- Upload date:
- Size: 51.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
355956ec5a1b39bf22203e23f4d238456fa84c7d03a7743cbfe14ea8b4dc11d9
|
|
| MD5 |
271ce3e7ff86fa846ce3a9e9ca2147f3
|
|
| BLAKE2b-256 |
06523d85dad367e4b12908525ca06f0105d152b435f54099f6044ecc03ff5613
|
Provenance
The following attestation bundles were made for actionaudit-1.4.1-py3-none-any.whl:
Publisher:
publish.yml on YusufKaramuk1/actionaudit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
actionaudit-1.4.1-py3-none-any.whl -
Subject digest:
355956ec5a1b39bf22203e23f4d238456fa84c7d03a7743cbfe14ea8b4dc11d9 - Sigstore transparency entry: 1659928057
- Sigstore integration time:
-
Permalink:
YusufKaramuk1/actionaudit@4002176922d87e0e5e7a64d1dc12729f8ca7c3ca -
Branch / Tag:
refs/tags/v1.4.1 - Owner: https://github.com/YusufKaramuk1
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4002176922d87e0e5e7a64d1dc12729f8ca7c3ca -
Trigger Event:
release
-
Statement type: