Skip to content

liemtv96/pipeguard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PipeGuard

Like a linter, but for CI/CD and DevOps mistakes

Python Typer Rich PyYAML Pytest Ruff License: MIT

PipeGuard is a lightweight Python CLI that scans your repository for risky CI/CD workflows, insecure Dockerfiles, and common DevOps configuration mistakes

It helps catch issues such as:

  • Unpinned GitHub Actions
  • Over-permissive workflow tokens
  • Unsafe pull_request_target usage
  • Dangerous curl | bash commands
  • Docker images running as root
  • Dockerfiles using latest tags
  • Missing Docker healthchecks
  • Committed .env files
  • Committed tokens and private keys
  • Unpinned Python dependencies
  • Python packages with known vulnerabilities from pip-audit
  • Docker OS packages that cannot be reliably image-audited

Installation

Install from PyPI:

pip install pipeguard-scanner-cli

The installed command is pipeguard

For local development, install from the project directory with development tools:

pip install -e ".[dev]"

Built With

Tool Purpose
Python Core language and packaging runtime
Typer Command-line interface for pipeguard scan
Rich Pretty terminal tables and scan reports
PyYAML Workflow and config file parsing
pip-audit Python package vulnerability advisories
Pytest Automated test suite
Ruff Fast Python linting

Usage

Scan the current repository:

pipeguard scan .

Scan a specific repository:

pipeguard scan /path/to/project

Scan a public Git repository:

pipeguard scan https://github.com/owner/repo --ref main

Supported commands

Command Purpose
pipeguard --version Show the installed PipeGuard version
pipeguard scan . Scan the current directory
pipeguard scan <path> Scan a specific project folder
pipeguard scan https://github.com/owner/repo Clone and scan a public Git repository in a temporary directory
pipeguard scan <path> --category cicd Scan only GitHub Actions workflows
pipeguard scan <path> --category docker Scan only Dockerfiles
pipeguard scan <path> --category iac Scan Docker Compose and Kubernetes manifests
pipeguard scan <path> --category repo Scan only repository health checks
pipeguard scan <path> --category secrets Scan only committed secret patterns
pipeguard scan <path> --category vuln Scan dependency and Docker package audit readiness
pipeguard scan <path> --exclude "dist/**" Exclude paths from scanning and reporting
pipeguard scan <path> --docker-image image:tag Scan a Docker image with Trivy or Grype, bootstrapped automatically when missing
pipeguard scan <path> --image-scanner trivy Select the Docker image vulnerability scanner
pipeguard scan <path> --output report.md Export a Markdown report
pipeguard scan <path> --output report.json Export a JSON report
pipeguard scan <path> --output report.sarif Export a SARIF report for code scanning
pipeguard scan <path> --fail-on high Exit with code 1 when high or critical findings exist
pipeguard scan <path> --ignore RULE_ID Ignore a specific rule ID
pipeguard scan <path> --config pipeguard.yml Load a specific PipeGuard config file

Category examples

Scan only GitHub Actions workflows:

pipeguard scan . --category cicd

Scan only Dockerfiles:

pipeguard scan . --category docker

Scan only Docker Compose and Kubernetes manifests:

pipeguard scan . --category iac

Scan only repository health checks:

pipeguard scan . --category repo

Scan only committed secret patterns:

pipeguard scan . --category secrets

Scan only Python package vulnerabilities and Docker package audit readiness:

pipeguard scan . --category vuln

Scan a Docker image with an installed scanner:

pipeguard scan . --category vuln --docker-image python:3.12 --image-scanner auto

When --docker-image is used, PipeGuard first looks for an installed Trivy or Grype binary. If neither is available, it downloads the official scanner installer into a temporary tools directory, runs the scan, and deletes the temporary directory afterward.

Sample output

PipeGuard prints tracking logs, a progress bar, a summary panel, and findings grouped by severity. The examples below are abbreviated from real category scans.

GitHub Actions:

track Scanning GitHub Actions workflows
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 9 | Critical: 0 | High: 2 | Medium: 7 | Low: 0

HIGH
GH_ACTION_JOB_WRITE_PERMISSION    cicd  .github/workflows/release-tag.yml      24   Job grants write token permissions
GH_ACTION_SECRET_IN_PULL_REQUEST  cicd  .github/workflows/python-security.yml  120  Workflow references secrets in pull request context

MEDIUM
GH_ACTION_UNPINNED_ACTION         cicd  .github/workflows/aws.yml              22   GitHub Action is not pinned to a commit SHA
GH_ACTION_WORKFLOW_WRITE_PERMISSION cicd .github/workflows/tag-codebuild-gated.yml 33 Workflow grants write token permissions

Docker:

track Scanning Dockerfiles
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 3 | Critical: 0 | High: 0 | Medium: 2 | Low: 1

MEDIUM
DOCKER_LATEST_TAG       docker  side-jobs/delete-junk-provider-redis-queue/Dockerfile  1  Docker image uses latest or implicit latest tag
DOCKER_RUNNING_AS_ROOT  docker  side-jobs/delete-junk-provider-redis-queue/Dockerfile  -  Dockerfile does not switch to a non-root user

LOW
DOCKER_MISSING_HEALTHCHECK docker side-jobs/delete-junk-provider-redis-queue/Dockerfile - Dockerfile does not define a healthcheck

Repository health:

track Scanning repository health
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 31 | Critical: 0 | High: 0 | Medium: 0 | Low: 31

LOW
REPO_LARGE_FILE             repo  swagger-codegen/swagger-codegen-cli.jar  -   Large file found in repository
REPO_MISSING_ENV_EXAMPLE    repo  .                                        -   Repository is missing .env.example
REPO_REQUIREMENTS_UNPINNED  repo  requirements.txt                         2   Python dependency is not fully pinned

Secrets:

track Scanning committed secret patterns
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 61 | Critical: 61 | High: 0 | Medium: 0 | Low: 0

CRITICAL
SECRET_AWS_ACCESS_KEY  secrets  app/config.py      25  AWS access key appears to be committed
SECRET_PRIVATE_KEY     secrets  certs/badkey.pem   1   Private key appears to be committed

Vulnerability scan:

track Scanning dependency vulnerabilities
track Collecting Python dependency manifests
track Preparing isolated pip-audit virtual environments
track Virtualenv isolation unavailable, using temporary target directories
track Installing pip-audit into temporary tools directory
track Installing target dependencies from requirements.txt
track Running pip-audit against temporary target directory
track Parsing pip-audit advisory results
track Checking Dockerfile package installs
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 28 | Critical: 0 | High: 28 | Medium: 0 | Low: 0

HIGH
VULN_PYTHON_PACKAGE_VULNERABLE  vuln  requirements.txt  18  Python package has known vulnerability CVE-2024-37891
VULN_PYTHON_PACKAGE_VULNERABLE  vuln  requirements.txt  28  Python package has known vulnerability CVE-2025-68616

Docker image vulnerability scan:

track Scanning Docker image python:3.9-slim
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 199 | Critical: 6 | High: 44 | Medium: 85 | Low: 64

CRITICAL
VULN_DOCKER_IMAGE_PACKAGE_VULNERABLE  vuln  python:3.9-slim  -  Docker image package has known vulnerability CVE-2025-15467

HIGH
VULN_DOCKER_IMAGE_PACKAGE_VULNERABLE  vuln  python:3.9-slim  -  Docker image package has known vulnerability CVE-2026-0861

All checks:

track Scanning GitHub Actions workflows
track Scanning Dockerfiles
track Scanning repository health
track Scanning committed secret patterns
track Scanning dependency vulnerabilities
track Scan complete
Scan complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%

PipeGuard Scan Report
Scanned path: /path/to/your-project
Findings: 132 | Critical: 61 | High: 30 | Medium: 9 | Low: 32

Export examples

Export a Markdown report:

pipeguard scan . --output report.md

Export JSON:

pipeguard scan . --output report.json

Export JSON for another project:

pipeguard scan /path/to/flask-app --output flask-app-pipeguard.json

Export SARIF for code scanning:

pipeguard scan . --output pipeguard.sarif

Visible project examples

Scan the bundled unsafe example project:

pipeguard scan examples

Export the bundled unsafe example project to JSON:

pipeguard scan examples --output examples-pipeguard.json

Scan slynk-api:

pipeguard scan /path/to/slynk-api

Export slynk-api to JSON:

pipeguard scan /path/to/slynk-api --output slynk-api-pipeguard.json

Scan Syncraft:

pipeguard scan /path/to/Syncraft

Export Syncraft to JSON:

pipeguard scan /path/to/Syncraft --output syncraft-pipeguard.json

CI and config examples

Fail CI when high-risk issues are found:

pipeguard scan . --fail-on high

Ignore a specific rule:

pipeguard scan . --ignore GH_ACTION_UNPINNED_ACTION

You can also create pipeguard.yml in the repository root:

ignore:
  - GH_ACTION_UNPINNED_ACTION

exclude:
  - examples/**
  - tests/fixtures/**
  - .security-target/**
  - .security-tools/**

fail_on: high

rules:
  DOCKER_MISSING_HEALTHCHECK:
    severity: medium
  REPO_MISSING_ENV_EXAMPLE: off

PipeGuard also looks for pipeguard.yaml, .pipeguard.yml, and .pipeguard.yaml Use --config path/to/file.yml to load a specific config file

See RULES.md for rule IDs, severities, and fixes.

Current checks

GitHub Actions

Rule Severity Description
GH_ACTION_UNPINNED_ACTION Medium Action is pinned to a tag or branch instead of a full SHA
GH_ACTION_MISSING_PERMISSIONS Medium Workflow does not define least-privilege permissions
GH_ACTION_WORKFLOW_WRITE_PERMISSION Medium Workflow grants at least one write token permission
GH_ACTION_WRITE_ALL_PERMISSION High Workflow grants write-all token permissions
GH_ACTION_JOB_WRITE_PERMISSION High Job grants at least one write token permission
GH_ACTION_PULL_REQUEST_TARGET High Workflow uses pull_request_target
GH_ACTION_PULL_REQUEST_TARGET_CHECKOUT_HEAD Critical Workflow appears to use PR head code with pull_request_target
GH_ACTION_SECRET_IN_PULL_REQUEST High Workflow references secrets in pull request context
GH_ACTION_WORKFLOW_RUN_TRIGGER Medium Workflow uses workflow_run trigger
GH_ACTION_CHECKOUT_PERSIST_CREDENTIALS Medium Checkout persists GitHub credentials
GH_ACTION_CURL_BASH High Workflow pipes remote script directly into shell
GH_ACTION_PIP_INSTALL_REMOTE_URL Medium Workflow installs Python package from a remote URL
GH_ACTION_DOCKER_LOGIN_PASSWORD Medium Workflow performs Docker login with a password/secret
GH_ACTION_PYPI_TOKEN_PUBLISH Medium Workflow appears to use a long-lived PyPI token

Dockerfile

Rule Severity Description
DOCKER_LATEST_TAG Medium Base image uses latest or implicit latest tag
DOCKER_RUNNING_AS_ROOT Medium Dockerfile does not switch to non-root user
DOCKER_MISSING_HEALTHCHECK Low Dockerfile does not define a healthcheck
DOCKER_APT_NO_CLEANUP Low apt package lists are not cleaned
DOCKER_COPY_ENTIRE_CONTEXT Low Dockerfile copies the whole context
DOCKER_SECRET_ENV Critical Dockerfile contains a likely secret in ARG/ENV

Docker Compose and Kubernetes

Rule Severity Description
COMPOSE_PRIVILEGED_SERVICE High Compose service runs with privileged mode
COMPOSE_HOST_NETWORK Medium Compose service uses host networking
COMPOSE_RUNS_AS_ROOT Medium Compose service runs as root
K8S_PRIVILEGED_CONTAINER High Kubernetes container runs privileged
K8S_HOST_PATH_VOLUME High Kubernetes workload mounts a hostPath volume
K8S_CONTAINER_RUNS_AS_ROOT Medium Kubernetes container runs as UID 0
K8S_MISSING_RESOURCE_LIMITS Low Kubernetes container is missing resource limits

Repository health

Rule Severity Description
REPO_MISSING_README Low Repository is missing a README
REPO_MISSING_GITIGNORE Low Repository is missing .gitignore
REPO_ENV_FILE_COMMITTED Critical .env style file appears committed
REPO_MISSING_ENV_EXAMPLE Low Repository is missing .env.example
REPO_REQUIREMENTS_UNPINNED Low Python dependency is not fully pinned
REPO_MISSING_PYPROJECT Low Python project may lack modern packaging config
REPO_LARGE_FILE Low Large file found in repository

Vulnerability

Rule Severity Description
VULN_PYTHON_PACKAGE_VULNERABLE High pip-audit reported a known vulnerability for a pinned Python package
VULN_PIP_AUDIT_UNAVAILABLE Medium Isolated pip-audit environment setup or execution failed
VULN_DOCKER_OS_PACKAGE_UNPINNED Medium Dockerfile installs an OS package without an exact version
VULN_DOCKER_IMAGE_PACKAGE_VULNERABLE Low-Critical Trivy or Grype reported a vulnerable package in a Docker image
VULN_DOCKER_IMAGE_SCANNER_UNAVAILABLE Medium Docker image scan was requested but Trivy or Grype could not be found or bootstrapped

Secrets

Rule Severity Description
SECRET_PRIVATE_KEY Critical Private key appears to be committed
SECRET_GITHUB_TOKEN Critical GitHub token appears to be committed
SECRET_AWS_ACCESS_KEY Critical AWS access key appears to be committed
SECRET_STRIPE_KEY Critical Stripe live secret key appears to be committed
SECRET_SLACK_TOKEN High Slack token appears to be committed
SECRET_JWT_TOKEN Medium JWT appears to be committed

Why PipeGuard?

Most teams review application code carefully, but CI/CD workflows, Dockerfiles, and repository setup often receive less attention

PipeGuard gives your repository a quick DevOps health check before small configuration mistakes become production or supply-chain problems

Development

Run tests:

pytest

Run linting:

ruff check .

License

PipeGuard is released under the MIT License

Copyright (c) 2026 Liem Tran

About

The lightweight Python CLI that scans your repository for risky CI/CD workflows, insecure Dockerfiles, and common DevOps configuration mistakes

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages