Catalog PyPI
Back to packageRELEASE DETAILS

0.1.5

PyPI

actions-warden

Read-only auditor for risky or injected GitHub Actions workflow config

ci-cddevsecopsgithub-actionsscannersecuritysupply-chainworkflow
Published16 Oct 2026
Direct dependencies1
Transitive dependenciesNot calculated

README

Version 0.1.5 documentation

Actions Warden

Read-only auditor for risky or injected GitHub Actions workflow config.

Current release: 0.1.5

After the 2026 wave of repository-theft attacks, a common post-compromise move is: steal a token, then inject or tamper with a repo's .github/workflows/ so CI exfiltrates secrets or runs attacker code. Actions Warden scans those workflow files for the patterns that enable it.

It does not execute workflows, contact GitHub, modify files, or prove a pipeline is safe. No telemetry, no data storage, no automatic remediation — alerts only.

Part of the Dragon Lady open security kit used alongside package/host scanners during the August 2026 npm/keyv (ChainDrop / Shai-Hulud) emergency tooling updates: when tokens may have been stolen, also audit CI workflows.

Install

pipx install actions-warden
# or
pip install actions-warden
# upgrade:
pipx upgrade actions-warden
# or: pip install -U actions-warden

Python 3.9+. No runtime dependencies.

Usage

actions-warden --version
actions-warden /path/to/repo
actions-warden /path/to/repo --json
actions-warden /path/to/repo --report report.json

It scans .github/workflows/*.yml|*.yaml and composite action.yml|action.yaml files. You can also point it at a single workflow file.

Exit codes:

  • 0: no blocking workflow risks found
  • 1: usage/runtime error or incomplete scan
  • 2: blocking workflow risks found (suitable as a CI gate)

Missing or unsupported targets fail explicitly. Unreadable files/directories, invalid text, and candidate size limits set coverage.complete: false with path/reason entries in coverage.errors. Blocking findings still return 2; otherwise incomplete scans return 1, never 0. Completeness covers only the scanner's selected file types and directory policy, not every repository file.

--report creates a new report exclusively (mode 0600 on POSIX). Existing files, symlinks and hard links are refused, including aliases of scanned inputs. Write failures return 1; a partial newly created report may remain and must not be treated as a successful result. Choose a fresh output path for each run.

What It Flags

RuleSeverityWhat it catches
secret-exfiltrationcriticala secret reference alongside an outbound network command
untrusted-input-injectionhighattacker-controllable github.event.* / head_ref interpolated into the workflow (shell injection in run steps)
remote-code-in-runhigha downloaded script piped straight into a shell
pull-request-target-head-checkouthighpull_request_target running with secrets while checking out PR-controlled code ("pwn request")
checkout-unsafe-pr-opt-outhighactions/checkout explicitly setting allow-unsafe-pr-checkout on privileged PR-adjacent triggers
self-hosted-on-untrustedmediumself-hosted runner reachable by external pull requests
permissions-write-allmediumwrite-all token permissions
oidc-with-writemediumOIDC id-token: write combined with contents: write
deployment-trigger-reviewmediumworkflows triggered by deployment / deployment_status that need GitHub workflow execution protections reviewed
deployment-trigger-privilegedhighdeployment-triggered workflows that also reference secrets, OIDC, or write permissions
unpinned-actionlowthird-party action pinned to a mutable tag/branch instead of a commit SHA
hijacked-actions-cool-tagcriticalactions-cool/issues-helper or actions-cool/maintain-one-comment on a tag, branch, or the known hijacked commit. Stop using the tag. Do not revoke tokens until the monitor and wiper are understood
memtensor-sckit-stage0criticalworkflow text contains both sckit and stage0. Treat the runner and publish tokens as exposed. Do not run the step. Notify-only

The rules are conservative. A finding means "review this workflow," not "this repo is compromised."

GitHub announced safer actions/checkout@v7 defaults for common pull_request_target pwn-request patterns on 2026-06-18, with supported major tag backports planned for 2026-07-16. Workflows pinned to a minor, patch, or full SHA need an explicit upgrade to receive that behavior, and any allow-unsafe-pr-checkout opt-out should be treated as a deliberate high-risk review item.

GitHub's workflow execution protections public preview also lets organizations restrict which actors and event types can trigger workflows. Treat deployment / deployment_status workflows as review items, and treat deployment-triggered workflows that use secrets, OIDC, or write permissions as blocked until the repository or organization restricts that trigger.

Why text-based, not YAML-parsed

A hostile workflow can be written to parse in surprising ways. Actions Warden inspects what is actually on disk rather than a parser's normalized view, and stays dependency-free. The tradeoff is coarser context: some file_all rules flag co-occurrence within a file rather than within a single job.

Scope Limits

This is a narrow CI/CD config scanner. It does not scan dependencies or packages (see a dependency/supply-chain scanner for that), does not resolve reusable or remote workflows, and will not catch every possible injection or obfuscated payload.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 1

Native requirements
1 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
pytest<10,>=8; extra == "dev"runtime

Distribution files

2 collected
actions_warden-0.1.5-py3-none-any.whl

bdist_wheel · 13.17 KB · Python py3

Source file
actions_warden-0.1.5.tar.gz

sdist · 17.49 KB · Python source

Source file

Repository

PENDING
dragon-lady/actions-warden

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 18:34 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:12c577dd004255efff3d5518de6a272ea822f69c0e46dae042f4166b5e9a9770

Other collected versions

View all collected versions →