Skip to content

pip-install — Zero-Trust Python Supply Chain Gate

Intercept malicious PyPI packages before they reach your environment.

greengate pip-install wraps pip install with three independent layers of supply-chain security. It catches typosquatted package names before pip runs, scans installed Python source files after pip finishes, and detects any unexpected executables dropped into your virtual environment.

Usage

bash
greengate pip-install [OPTIONS] [PIP_ARGS...]

All arguments are forwarded verbatim to pip:

bash
# Drop-in for pip install
greengate pip-install requests flask==3.0.0

# Install from requirements file
greengate pip-install -r requirements.txt

# Install with extras
greengate pip-install "fastapi[standard]"

# Upgrade a package
greengate pip-install --upgrade django

Options

FlagDefaultDescription
--pip <PATH>pipPath to the pip executable to use (e.g. pip3, .venv/bin/pip)
--no-failReport findings to stderr but exit 0. Useful for audit-only pipelines.

Three-layer architecture

Layer 1 — Typosquat detection (pre-install)

Before pip runs, each package name in the install arguments is compared against the 60 most-downloaded PyPI packages using Levenshtein distance. If the edit distance is ≤ 2, the install is halted before pip executes.

greengate pip-install reqeusts

Error: Possible typosquat: "reqeusts" is 2 edit(s) away from "requests".
       Verify the package name is correct before installing.

This catches attacks like requets, reqeusts, djang0, flaskk, boto3_, etc.

Layer 2 — Post-install source scan

After pip installs the package, greengate reads the .dist-info/RECORD file to discover every file the package installed. Python source files (.py) are scanned for 25 suspicious signals:

CategorySignals
Dynamic code executioneval(, exec(, compile(, __import__
Obfuscation / encodingbase64.b64decode, codecs.decode, zlib.decompress
Network exfiltrationurllib.request, http.client, socket.connect, requests.post
Subprocess / shellsubprocess.run, os.system, os.popen, pty.spawn
Env var accessos.environ, os.getenv
High entropy stringsShannon entropy > 4.8 over any 64-char window

Layer 3 — Executable-drop detection

After install, greengate checks your virtual environment's bin/ (Unix) or Scripts/ (Windows) directory for new executables that were not present before the install. Legitimate packages create named entry points — unexpected binaries or scripts are flagged.

Example output

Typosquat detected (Layer 1):

Error: Possible typosquat: "reqeusts" is 2 edit(s) away from "requests".
       Verify the package name is correct before installing.

Suspicious source file (Layer 2):

⚠️  Supply chain scan found 1 suspicious file(s):

  [SUSPICIOUS] malicious-sdk/exfil.py
    Signals: requests.post, os.environ, base64.b64decode
    Entropy: 5.12 (threshold 4.80)

Error: Supply chain gate: suspicious Python source found after install.

Clean install:

✅ pip-install: no typosquats, suspicious source, or executable drops detected.

Configuration

toml
[supply_chain]
# PyPI package names exempted from typosquat and source scanning.
# Use for internal packages whose names are intentionally similar to popular ones.
allow_pip_packages = [
  # "my-internal-requests-wrapper",
]

CI usage

yaml
- name: Zero-trust pip install
  run: greengate pip-install -r requirements.txt

# With a specific pip
- name: Zero-trust pip install (venv)
  run: greengate pip-install --pip .venv/bin/pip -r requirements.txt

# Audit-only (non-blocking)
- name: Supply chain audit
  run: greengate pip-install --no-fail -r requirements.txt

Pairing with audit

pip-install and greengate audit are complementary:

ToolWhat it catches
greengate auditKnown CVEs in installed packages (via OSV database)
greengate pip-installTyposquats, obfuscated source, exec-drops — behaviour CVE databases cannot see

Run both:

bash
greengate pip-install -r requirements.txt   # zero-trust gate
greengate audit                             # known CVE check

Released under the MIT License.