actionsec
Your CI pipeline runs with a write token and your secrets. actionsec checks
it isn't a liability. It scans your GitHub Actions workflows for the handful of
mistakes that actually get repos compromised — unpinned third-party actions,
script injection from untrusted input, over-broad token permissions, and the
pull_request_target footgun. Zero config, zero dependencies.
pip install actionsec
actionsec
.github/workflows/ci.yml
✗ critical L12 pull-request-target-checkout `pull_request_target` checks out PR head code — untrusted code runs with a write token and secrets
✗ critical L16 script-injection untrusted `github.event.pull_request.title` in a run step — pass it through an env: var instead
✗ high L5 broad-permissions `permissions: write-all` gives the token full read/write — scope it down
✗ high L13 unpinned-action `some-marketplace/deploy-action@main` is a mutable branch — pin to a full commit SHA
✗ medium L10 unpinned-action `actions/checkout@v4` is a mutable tag — pin to a full commit SHA
✗ 5 issue(s) in 1 of 1 file(s) — 2 critical, 2 high, 1 medium
Why
The 2025 supply-chain attacks (reviewdog, tj-actions/changed-files) all rode in through the same door: a workflow that trusted a mutable action tag, so when the upstream tag was repointed at malicious code, every consumer ran it — with a token that could push commits and read secrets. 71% of repos never pin actions to a SHA.
actionlint validates workflow syntax; zizmor does deep dataflow analysis but
wants installation and config. actionsec fills the gap between them: a five-second,
zero-config pass over the highest-impact security checks, small enough to drop in a
pre-commit hook or a one-line CI step.
The checks
| Check | Severity | What it catches |
|---|---|---|
| unpinned-action | high / medium | uses: a mutable tag or branch (@v4, @main) instead of a 40-char commit SHA. Third-party = high, GitHub-owned actions/* = medium. |
| script-injection | critical | ${{ github.event.*.title | .body | .head_ref ... }} interpolated into a run: step, where GitHub substitutes it into the shell before it runs. |
| broad-permissions | high | permissions: write-all — the token gets full read/write across the repo. |
| missing-permissions | low | no permissions: block at all, so the workflow inherits the repo default scope. |
| pull-request-target-checkout | critical | pull_request_target + a checkout of the PR head — untrusted code runs with a privileged token and secrets. |
It is not a YAML validator (use actionlint) and not a deep dataflow analyzer (use zizmor). It's a fast, line-based first pass — which is also why it's zero-dependency: it never needs to parse YAML into a tree.
Usage
actionsec # scan ./.github/workflows
actionsec path/to/repo # scan another repo's workflows
actionsec ci.yml release.yml # scan specific files
actionsec --min-severity high # only high + critical (good for a hard CI gate)
actionsec --format json # machine-readable
Try it on the bundled example after cloning:
python -m actionsec examples # → flags the deliberately-vulnerable demo workflow
In CI
actionsec exits non-zero when it finds issues, so it gates a pipeline directly.
A common setup is to fail only on the serious stuff:
# .github/workflows/security.yml
- run: npx actionsec --min-severity high
| Exit code | Meaning |
|---|---|
0 |
no issues at or above the threshold |
1 |
issues found |
2 |
error (no workflows found, unreadable file) |
Options
--min-severity <sev> low | medium | high | critical (default: low)
--format text|json output format (default: text)
-v, --version
-h, --help
Also available for Node
npx actionsec
Same checks, same severities, same exit codes — actionsec on npm.
Note: actionsec reads workflow files as text, so it works on any repo regardless of which language you install it from.
License
MIT
Metadata
Release files for actionsec 0.1.0
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 |
|---|---|---|---|---|
| actionsec-0.1.0.tar.gz | 12.2 kB | Without provenance | Details for actionsec-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| actionsec-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for actionsec-0.1.0-py3-none-any.whl |
Total release size: 22.8 kB
Release files / actionsec-0.1.0.tar.gz
| Download URL | actionsec-0.1.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
62a6582817f60ab524ff675727600edbc94bc1e77ceda2543b946970b6bdbe76
|
|
BLAKE2b-256 checksum How to use checksums |
511a8b9cb4991c4219f287cb25d06ef4ec2f804af706c5c1f01e610c5d3a7982
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Release files / actionsec-0.1.0-py3-none-any.whl
| Download URL | actionsec-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1af39fd0ab91e56bbd9df89c272416ea5656e423c93279fa32159a4cb1c01ab2
|
|
BLAKE2b-256 checksum How to use checksums |
fbc3397c435f43a70f2bf472c579eabfafd46451b30efa1fee961dc7a0abb920
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.7
|
Security for actionsec 0.1.0
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.