Skip to content

destbreso/pygarde

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🐍 PYGARDE (pyw)

Python Supply Chain Security Guardian

PYGARDE is a CLI security tool that scans, audits and hardens your Python package ecosystem against supply-chain attacks β€” before malicious code ever runs on your machine.

β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—   β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•”β•β•β•β•   β•šβ–ˆβ–ˆβ•”β•  β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•
β–ˆβ–ˆβ•‘        β–ˆβ–ˆβ•‘   β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β•šβ•β•        β•šβ•β•    β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β• β•šβ•β•β•β•β•β•β•

Python PyPI License: MIT


Features

Feature Description
Deep scan Download and scan any PyPI package without installing it
Pre-install gate Intercept and scan packages before they touch your environment
Dependency audit Audit all project dependencies against known CVEs and custom rules
RC hardening Detect and fix misconfigurations in pip.conf, poetry.toml and uv.toml
Version diff Compare two package versions and scan the code delta for injected threats
Health check doctor command scores your project's overall security posture

Detection Rules

Rule Detects
install-scripts Malicious setup.py hooks, .pth injection
network-access Suspicious imports and outbound URLs (pastebin, ngrok, hardcoded IPs)
code-execution eval, exec, os.system, subprocess with shell=True, pickle.loads
obfuscation base64.b64decode payloads, marshal.loads, high-entropy strings
data-exfiltration os.environ combined with outbound HTTP, sensitive key access
hidden-chars Zero-width spaces, Trojan Source (CVE-2021-42574), Cyrillic homoglyphs
typosquatting Levenshtein-distance ≀ 2 against 80+ popular PyPI packages

Installation

Recommended β€” global install with pipx

pipx installs Python CLI tools in isolated environments and makes them available system-wide. This is the preferred way to install pyw.

# 1. Install pipx (once)
brew install pipx        # macOS
# or: pip install --user pipx

pipx ensurepath          # adds ~/.local/bin to your PATH (restart terminal after)

# 2. Install pygarde globally
pipx install pygarde

# 3. Verify
pyw --version

After this, pyw is available in any terminal, any project, any virtualenv β€” no activation needed.

Alternative β€” pip (current Python only)

pip install pygarde
pyw --version

⚠️ With plain pip, pyw is only available while that Python's environment is active. Use pipx for a permanent global install.

From source (development)

git clone https://github.com/destbreso/pygarde
cd pygarde
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pyw --version

Requirements: Python 3.10+


Quick Start

# 1. Initialize security config in your project
cd my-project
pyw init

# 2. Scan any PyPI package before installing it
pyw scan requests
pyw scan requests --version 2.31.0

# 3. Install packages with pre-install security gate
pyw install requests flask sqlalchemy
pyw install pytest --dev

# 4. Audit all project dependencies
pyw audit
pyw audit --deep          # also scans source code of each dep

# 5. Health check β€” scores your project security posture
pyw doctor

# 6. Harden your package manager config (pip.conf / poetry.toml / uv.toml)
pyw harden
pyw harden --yes          # auto-apply without prompts

# 7. Compare two versions of a package β€” detect injected code
pyw diff numpy
pyw diff requests --target 2.32.0 --show-diff

Commands

pyw scan <package> [--version]

Deep-scan a PyPI package for security threats without installing it.

pyw scan requests
pyw scan requests --version 2.28.0
pyw scan suspicious-pkg --severity high
pyw scan malware --ci --json

Options:

Flag Description
--version, -v Version to scan (interactive picker if omitted)
--severity, -s Minimum severity to display (low | medium | high | critical)
--page-size Findings per page (default: 20)
--ci Non-interactive, exits with code 1 if threats found
--json Machine-readable JSON output

pyw install [packages...]

Install packages with a pre-install security scan.

pyw install requests flask sqlalchemy
pyw install pytest --dev
pyw install requests --force        # install despite findings
pyw install requests --skip-scan    # bypass scanning

pyw audit [--deep]

Audit all project dependencies.

  • Runs native PM audit (pip-audit, pipenv check, etc.)
  • With --deep: downloads and static-scans each dependency
pyw audit
pyw audit --deep
pyw audit --ci --json

pyw doctor

Security health check. Scores your project 0–100% across:

  • .pygarde.yml present
  • Lockfile present
  • PM config security (via RC analyzer)
  • No dangerous PM settings
  • All detection rules enabled
  • Allowlist not overly permissive

pyw diff <package> [--target]

Compare two versions of a package and scan the diff for injected code.

pyw diff requests
pyw diff numpy --target 1.26.0
pyw diff attrs --show-diff       # show line-level diffs

pygarde highlights:

  • Added / removed / modified files
  • New attack patterns in the diff (eval, subprocess, network calls)

pyw harden [--yes] [--dry-run]

Audit and fix PM security configuration files.

pyw harden
pyw harden --yes              # auto-apply at configured level
pyw harden --dry-run          # show issues only

Harden levels:

Level Scope
minimal Critical + high β€” the non-negotiables
recommended Critical + high + medium β€” solid baseline (default)
strict All findings including low-impact settings

pip.conf settings managed:

Setting Level Why
require-hashes = true critical Prevents MITM/tampered packages
no-binary (avoid for critical pkgs) medium Prefer auditable source
index-url medium Ensure official PyPI registry
trusted-host (danger) critical Disables SSL verification

pyw init

Interactive wizard to generate .pygarde.yml and apply RC hardening.


pyw config [show|edit|reset|path]

Manage configuration.

pyw config show         # display current config
pyw config path         # print config file path
pyw config edit         # open in $EDITOR
pyw config reset        # reset to defaults

Configuration

pygarde reads .pygarde.yml in the project root.

severity:
  threshold: medium       # ignore findings below this level
  fail_ci: high           # exit 1 in CI when findings reach this level

rules:
  install_scripts: true
  network_access: true
  code_execution: true
  obfuscation: true
  data_exfiltration: true
  hidden_chars: true
  typosquatting: true

policies:
  enforce_rc_security: true
  enforce_lockfile: true
  enforce_exact_versions: false
  audit_on_install: true
  registry_url: "https://pypi.org/simple/"
  harden_level: recommended   # minimal | recommended | strict

allowlist:
  - urllib3      # known false-positive
  - certifi

blocklist:
  - malicious-pkg
  - evil-package

Supported Package Managers

PM Detection Install Audit Harden
pip βœ” βœ” βœ” (pip-audit) βœ” (pip.conf)
poetry βœ” βœ” βœ” βœ” (poetry.toml)
uv βœ” βœ” β€” βœ” (uv.toml)
pipenv βœ” βœ” βœ” (pipenv check) β€”
pdm βœ” βœ” β€” β€”
conda βœ” β€” β€” β€”

Running Tests

pip install -e ".[dev]"
pytest
pytest -v tests/test_rules.py
pytest --tb=short

License

MIT β€” see LICENSE

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages