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.
- 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.
pip install actionauditOr from source:
git clone https://github.com/YusufKaramuk1/actionaudit.git
cd actionaudit
pip install -e .# 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# 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 highSee Configuration and Custom rules below for the --policy schema and
--rules-dir.
Add ActionAudit to any repository's workflow:
- uses: YusufKaramuk1/actionaudit@v1.4.1
with:
path: .github/workflows
fail-on: highFindings are emitted as inline annotations on the pull request, and the step
fails when a finding at or above fail-on is present.
Add ActionAudit to .pre-commit-config.yaml:
repos:
- repo: https://github.com/YusufKaramuk1/actionaudit
rev: v1.4.1
hooks:
- id: actionauditThe hook runs whenever a workflow file changes and fails the commit on a
HIGH-or-above finding (override with args: ['--fail-on', 'critical']).
| 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 |
--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.
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-shaWrite 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.
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.
pip install -e ".[dev]"
pytest
ruff check src tests
mypy srcSee CONTRIBUTING.md for how to add a rule.
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.
MIT — see LICENSE.