Skip to main content

CLI dependency risk scanner for Python projects.

Project description

snake-guard

snake-guard is a CLI dependency risk scanner for Python projects. It helps developers detect vulnerable, suspicious, or risky packages before they become part of a project or CI pipeline.

It aggregates known vulnerability scanners and package-risk checks, then unifies their results into one easy-to-use command-line interface. It builds an inventory from common Python manifests and reports vulnerabilities, suspicious package signals, provenance issues, and safe remediation guidance in one place.

Table of Contents

Features

  • Full project scans for known vulnerabilities using multiple scanners and package-risk checks.
  • Isolated package sandboxing to probe, import, or run commands before trusting a dependency in your local environment.
  • Automatic dependency fix plans for vulnerable direct dependencies, with conservative project edits where safe.
  • Safer install wrapper that scans before installation, sandboxes risky packages, and verifies the project after install.
  • Per-engine pass or fail status so missing tools, scanner errors, and findings are visible instead of hidden behind a clean-looking result.

Installation

Install snake-guard from PyPI:

pip install snake-guard

For local development, install this repository in editable mode:

python -m pip install -e .

Sandbox commands use a container runtime. Docker is the default runtime:

docker --version

Other Docker-compatible runtimes may work when passed with --runtime, but the sandbox command arguments are Docker-style today.

Usage

Scan the current project:

snake-guard scan

Emit JSON for scripts or CI:

snake-guard scan --json

Use verify mode as a policy gate. It exits non-zero when high-risk findings are present:

snake-guard scan --verify

Preview remediation without editing files:

snake-guard fix --plan

Apply available fixes:

snake-guard fix

Run against an example project:

snake-guard scan --root examples/pip_project
snake-guard scan --root examples/poetry_project
snake-guard scan --root examples/uv_project

Use --no-cache when you want a fresh scan, fix, or install run without reusing cached scan results:

snake-guard scan --no-cache
snake-guard fix --no-cache
snake-guard install --no-cache

Fix Plans

snake-guard fix separates real fixes from recommendations:

  • Fix actions are generated for vulnerable packages when a safe target version is known.
  • Pinning recommendations are shown for direct dependencies that use ranges or compatible-release specifiers.
  • Engine status is shown next to the plan, so a clean plan does not hide a failed scanner.

Example:

snake-guard fix --plan

If no actions are required and every engine passed, the output says the project is good to go. If no actions are generated but an engine failed, the output makes that explicit so the result is not treated as clean.

Cache

snake-guard stores scan results in a small JSON cache so repeated scans of the same dependency set can skip engines that already finished.

The cache lives under:

  • ~/.cache/snake-guard/scan-cache.json

If XDG_CACHE_HOME is set, the cache file is stored there instead.

Useful cache commands and flags:

snake-guard cache clear
snake-guard scan --no-cache
snake-guard fix --no-cache
snake-guard install --no-cache
  • cache clear deletes the persisted scan cache file.
  • --no-cache bypasses the scan cache for a single run.
  • install and fix pass the cache setting through to their internal scans, so the full workflow can also run fresh when needed.

Install Wrapper

The installation wrapper runs a pre-scan, optionally sandboxes risky packages, and then delegates to the real installer.

snake-guard install --root examples/pip_project
snake-guard install -r requirements.txt
snake-guard install --dry-run
snake-guard install --manager poetry -- --with dev
snake-guard install --manager uv -- --frozen
snake-guard install --package requests --package flask

Use --dry-run to see what would happen without running sandbox checks or the underlying installer.

Sandbox

Sandbox mode is useful when you want to inspect a package before installing it in your real environment. By default, direct sandbox commands disable networking inside the container.

snake-guard sandbox probe Django --force
snake-guard sandbox exec Django --force -- python -c "import django; print(django.get_version())"
snake-guard sandbox shell Django --force

Available sandbox modes:

  • probe: install a package and attempt a basic import in an isolated container.
  • exec: install a package and run a command inside the sandbox.
  • shell: install a package and open an interactive shell inside the sandbox.

Useful sandbox options:

  • --allow-network enables container networking during package installation.
  • --no-pull-image requires the sandbox image to already exist locally.
  • --image changes the Python container image.
  • --runtime changes the container runtime executable.
  • --docker-arg passes extra Docker-style arguments to the sandbox run.

JSON Output

Most commands support --json for automation:

snake-guard scan --json
snake-guard fix --plan --json
snake-guard sandbox probe requests --force --json

The JSON report includes the dependency inventory, package findings, engine statuses, fix actions, and recommendations where applicable.

Scheduled CI Scans

Dependency risk changes over time. A package that looked clean during install can receive a new advisory or suspicious signal later. You can run snake-guard on a schedule in CI to keep checking the project.

This repository includes a reusable GitHub Actions example at .github/workflows/snake-guard.yml:

Supported Package Managers

snake-guard currently reads these dependency sources:

  • requirements.txt
  • pyproject.toml
  • poetry.lock
  • uv.lock

The installation wrapper can detect or run these package managers:

  • pip
  • poetry
  • uv

snake-guard fix can update vulnerable direct dependencies in requirements.txt or pyproject.toml when a safe replacement is known. For Poetry and uv projects, it rewrites the direct dependency specifier first, then runs poetry lock or uv lock so the checked-in lock file matches the manifest. Use snake-guard fix --plan to preview the manifest diff and the lock refresh command before editing files.

Built With

The core CLI is written in Python and uses:

  • Typer for the command-line interface.
  • packaging for version and requirement handling.
  • tomli on older Python versions for TOML parsing.

Under the hood, scans use these engines:

  • pip-audit for Python vulnerability advisories.
  • guarddog for PyPI malware and suspicious-package heuristics.
  • Built-in provenance checks against PyPI JSON and Integrity APIs.

pip-audit and guarddog are installed with snake-guard.

Contributing

Contributions are welcome, especially around parser coverage, remediation safety, test fixtures, and clearer reporting. Keep changes focused and include an example or test fixture when behavior changes.

Before opening a change, run at least:

python -m compileall -q snake_guard

If your change depends on scan engines, also test real pip-audit and guarddog runs so engine status and failure handling stay accurate.

License

This project is licensed under the Apache License 2.0. See LICENSE for the full license text.

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

snake_guard-0.1.0.tar.gz (65.4 kB view details)

Uploaded Source

Built Distribution

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

snake_guard-0.1.0-py3-none-any.whl (49.0 kB view details)

Uploaded Python 3

File details

Details for the file snake_guard-0.1.0.tar.gz.

File metadata

  • Download URL: snake_guard-0.1.0.tar.gz
  • Upload date:
  • Size: 65.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for snake_guard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 877a9f509c0cf964d0304280c6aefa9624ea1e643fea334e9759d74d5c9fd71e
MD5 cf9d30a9390a1f04d02db87639400713
BLAKE2b-256 66023486fbbf7f44a8bf29d9887fcbddffdf8d3ca611f844c8a56e0495433908

See more details on using hashes here.

Provenance

The following attestation bundles were made for snake_guard-0.1.0.tar.gz:

Publisher: release.yml on Artemooon/snake-guard

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

File details

Details for the file snake_guard-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: snake_guard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 49.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for snake_guard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2a681bda79faaa40ccd5028f8fb89da817f9d268d02dc789dc315d9c3a3f5066
MD5 8bdd8e2a10ea786f958f7188497e0913
BLAKE2b-256 96270a761351d57450d894e3dcef24eb0e3922af2c9bfbc3a86bde49a991ce2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for snake_guard-0.1.0-py3-none-any.whl:

Publisher: release.yml on Artemooon/snake-guard

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