Skip to main content

Pre-commit security scanner for GitHub Actions workflows

Project description

PipeGuard

CI PyPI Version Downloads License

PipeGuard

Catch GitHub Actions security issues before they reach your runners.

Pre-commit security scanner for GitHub Actions workflows. Catches supply-chain risks, unpinned actions, known CVEs, and secret leaks — before you push.


Demo

Demo

The recording shows a scan of a real workflow file with multiple security issues. PipeGuard detects them all in under a second — no API key, no network call, fully offline:

  • No top-level permissions: block — GitHub grants write access to all scopes by default
  • tj-actions/changed-files@v35 and reviewdog/action-setup@v1 match known CVEs in the bundled database
  • All actions are pinned to tags instead of commit SHAs — a supply-chain risk
  • echo ${{ secrets.DEPLOY_TOKEN }} leaks a secret value to the workflow log
  • 8398a7/action-slack is a third-party action from an unverified publisher

PipeGuard vs. the alternatives

Feature PipeGuard actionlint StepSecurity act
SHA-pinning check
CVE database (offline) ✅ (online)
Permissions analysis ⚠️ syntax only
Secrets-leak detection ✅ (runtime)
Supply-chain audit
Syntax / type checks ✅ via actionlint
Run workflows locally
Runtime hardening
Pre-commit hook
SARIF output
No API key required
Fully offline ⚠️ needs images
Open source
Free ✅ core ⚠️ freemium

PipeGuard fills the gap between authoring and execution: static security analysis, offline, before you push, without any external service.


Installation

Prerequisites: Python 3.11+

pip install pipeguard-cli

Install actionlint (required for syntax checks, optional for other checks):

# Linux
curl -fsSL https://github.com/rhysd/actionlint/releases/latest/download/actionlint_linux_amd64.tar.gz \
  | tar xz actionlint && sudo mv actionlint /usr/local/bin/

# macOS
brew install actionlint

# Ubuntu/Debian (snap)
sudo snap install actionlint

Usage

pipeguard scan [PATH]

PATH can be a single workflow file or a directory. If omitted, defaults to .github/workflows.

Examples

# Scan entire .github/workflows directory (default)
pipeguard scan

# Scan a specific directory
pipeguard scan .github/workflows/

# Scan a single file
pipeguard scan .github/workflows/ci.yml

# JSON output (for scripts / CI pipelines)
pipeguard scan --format json

# SARIF output (for IDE integration, GitHub Code Scanning)
pipeguard scan --format sarif

# Use a custom config file
pipeguard scan --config path/to/.pipeguard.yml

When scanning a directory, pipeguard prints a per-file header and a summary at the end:

Scanning: .github/workflows/ci.yml
  ✓ No issues found

Scanning: .github/workflows/deploy.yml
  ╭─────────┬──────────────────┬──────────────────────────┬──────────────╮
  │ Severity│ Rule             │ Location                 │ Message      │
  ├─────────┼──────────────────┼──────────────────────────┼──────────────┤
  │ error   │ cve-cve-2025-... │ deploy.yml:12            │ Action ...   │
  │ error   │ sha-pinning      │ deploy.yml:15            │ Action ...   │
  ╰─────────┴──────────────────┴──────────────────────────┴──────────────╯

Scanned 2 file(s) — 2 error(s), 1 warning(s), 3 info(s) total.

Exit codes

Code Meaning
0 No errors or warnings
1 One or more errors or warnings found

Info-level findings (action inventory) do not affect the exit code.


Security checks

Errors & Warnings

Rule Severity Description
sha-pinning error Action pinned to a tag or branch instead of a full commit SHA — supply-chain risk (cf. CVE-2025-30066)
sha-pinning-reusable error Reusable workflow called with a tag or branch ref instead of a full commit SHA — same supply-chain risk as unpinned actions
cve-<id> error Action matches a known CVE in the local database (offline, no API)
supply-chain warning Third-party action from an unverified publisher — suppress per publisher or action via .pipeguard.yml
secrets-leak error Secret value echoed or logged in a run: step
secrets-leak-debug error / warning set -x or set -o xtrace in a run: step — shell debug mode prints every expanded command; error when secrets are in env scope, warning otherwise
permissions-missing error No permissions: block — GitHub grants write access to most scopes by default
permissions-write-all error permissions: write-all at top-level or per-job
permissions-excessive warning Sensitive scope (e.g. secrets, workflows) set to write
permissions-id-token-unused warning id-token: write is set but no OIDC-consuming action is present — allows minting cloud credentials unnecessarily
permissions-invalid error Unknown permission level (not read, write, or none)
pull-request-target warning pull_request_target trigger runs with base-repo write permissions and secret access — even for fork PRs
pull-request-target-pwn error pull_request_target combined with checkout of the PR head ref — allows untrusted fork code to run with secrets (Pwn Request)
actionlint error Syntax and type errors (requires actionlint)

Info

Rule Severity Description
action-inventory info Inventory of all third-party actions used — ref(s) and occurrence count

CVE database

PipeGuard ships with a built-in offline CVE database — no API key, no network call during scan. The database is updated daily via NVD and shipped with each new weekly release.

[!NOTE] Last updated: 2026-03-12

CVE Action Description
CVE-2025-30066 tj-actions/changed-files tj-actions/changed-files was compromised in a supply-chain attack. All tag-based refs are potentially affected — pin to a known-good SHA.
CVE-2025-30154 reviewdog/action-setup reviewdog/action-setup was compromised in the same supply-chain campaign as tj-actions/changed-files. Pin to a vetted SHA.
CVE-2023-49291 tj-actions/branch-names tj-actions/branch-names improperly references github.event.pull_request.head.ref and github.head_ref in a run step, allowing a specially crafted branch name to execute arbitrary code and steal secrets or abuse GITHUB_TOKEN permissions.

SHA-pinned refs are not flagged — another reason to always pin to a commit SHA.

To get the latest CVEs, upgrade to the newest release:

pip install --upgrade pipeguard-cli

Configuration

PipeGuard looks for a .pipeguard.yml (or .pipeguard.yaml, pipeguard.yml, pipeguard.yaml) in the current directory and its parents.

Suppress supply-chain warnings for trusted publishers

If you trust a specific publisher or action, add them to the allowlist:

# .pipeguard.yml
trusted_publishers:
  - my-org           # suppresses all warnings for my-org/*
  - some-vendor      # suppresses all warnings for some-vendor/*

trusted_actions:
  - other-org/specific-action  # suppresses warning for this exact action only
  • trusted_publishers matches as a prefix — every action from my-org/* is considered trusted.
  • trusted_actions requires an exact match on the action name (without the @ref).
  • A trailing / in publisher names is optional; PipeGuard normalises it automatically.

The built-in allowlist (GitHub, AWS, Azure, Google, Docker, HashiCorp, etc.) is always active and cannot be removed.


CI integration

Add pipeguard as a pre-push check or CI step:

# .github/workflows/pipeguard.yml
- name: Scan workflows
  run: |
    pip install pipeguard-cli
    pipeguard scan .github/workflows/

Or as a pre-commit hook (.pre-commit-config.yaml):

repos:
  - repo: local
    hooks:
      - id: pipeguard
        name: PipeGuard workflow scan
        entry: pipeguard scan
        language: python
        additional_dependencies: [pipeguard-cli]
        files: \.github/workflows/.*\.ya?ml$

Output formats

Terminal (default) — human-readable table with rule, location, and fix suggestions.

JSON — machine-readable, one object per finding:

[
  {
    "rule": "cve-cve-2025-30066",
    "severity": "error",
    "message": "Action 'tj-actions/changed-files@v35' is affected by CVE-2025-30066: ...",
    "file": ".github/workflows/ci.yml",
    "line": 12,
    "fix_suggestion": "Immediately pin 'tj-actions/changed-files' to a verified safe SHA."
  }
]

SARIF — compatible with GitHub Code Scanning.


License

Apache 2.0 — see LICENSE.

Status

In active development. All Free-tier scanners are functional. Planned: auto-fix PRs (Pro), Maintainer Trust Score (Pro), cloud sandbox testing, IDE plugin.

Free-tier checks: SHA-pinning, CVE database, permissions audit (incl. id-token: write without OIDC), secrets-leak detection, action inventory, actionlint syntax checks.

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

pipeguard_cli-0.1.2.tar.gz (319.8 kB view details)

Uploaded Source

Built Distribution

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

pipeguard_cli-0.1.2-py3-none-any.whl (30.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pipeguard_cli-0.1.2.tar.gz
  • Upload date:
  • Size: 319.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pipeguard_cli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 4264ab4e99440c5bb733383f2366f99a7a7c6d89ef1c42e9297fb45430c3676f
MD5 4c37b524ec595b206e39b081a07b1f25
BLAKE2b-256 b5fc400030ba5e3029ba45ef18fc686be9067a795a70a815dcc508b60b7a5979

See more details on using hashes here.

Provenance

The following attestation bundles were made for pipeguard_cli-0.1.2.tar.gz:

Publisher: deploy.yml on alex-jung/pipeguard-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: pipeguard_cli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pipeguard_cli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 24a29f8932c0e24f37ab41e214c1a520e38fc9f7ea430cc88f0e839afabc76ec
MD5 471ff97bb136f5c89e0b184aa05d2613
BLAKE2b-256 4047e513f5edbe316e368d7b5f627ae8a086c0ad19d6149a10a5ec4bffcf67de

See more details on using hashes here.

Provenance

The following attestation bundles were made for pipeguard_cli-0.1.2-py3-none-any.whl:

Publisher: deploy.yml on alex-jung/pipeguard-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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