Skip to main content

vendorcheck

CI PyPI License: MIT

Is the Python library bundled inside your app, add-on or extension byte-for-byte the official PyPI release?

Point it at a folder or an archive (.zip, .xpi, .vsix, .fda, .whl, any app bundle that is a zip). It finds the embedded Python packages, downloads the official release from PyPI, verifies the download against PyPI's published SHA-256, and compares file by file.

$ vendorcheck lib/ -v          # idna with one file edited and one file added
idna 3.7: 8 files identical, 1 modified, 1 extra.
    [modified] idna/core.py
    [extra] idna/evil.py

Real run on a clean pip install --target of yt-dlp:

$ vendorcheck lib/
yt_dlp 2026.8.19: 1049 files identical, 0 modified, 0 extra.

Why

Software supply-chain attacks often hide in copies of popular libraries: a vendored package that was quietly patched, or has an extra file dropped in. Lockfiles, pip-audit and signature checks look at what PyPI serves, not at the copy shipped inside your artifact. vendorcheck closes that gap.

Install

pip install vendorcheck
# or just download vendorcheck.py - it is a single file, stdlib only, Python 3.9+

Usage

vendorcheck PATH [-v | -vv] [--json] [--lang en|tr] [--only NAME ...] [--ignore GLOB ...]
                 [--no-nested] [--cache DIR] [--allow-empty]
Option Meaning
-v list every modified / extra / missing file
-vv additionally print a unified diff (official → embedded) for modified text files
--json machine-readable output (includes diffs with -vv)
--only NAME ... check just these packages
--ignore GLOB skip files matching the glob (relative to the package dir, e.g. yt_dlp/version.py); repeatable. For intentional local patches
--no-nested don't open archives found inside the input
--cache DIR reuse downloaded official releases
--allow-empty exit 0 if no embedded package is found (default: exit 2, so CI can't pass by checking nothing)
--lang tr Turkish output

Archives nested inside the input (.zip .whl .egg .xpi .vsix .fda .pyz, up to 2 levels, 2 GiB guard) are opened automatically and reported as pkg 1.0 [inner.xpi!/].

Exit codes: 0 identical · 1 differences found · 2 error / nothing checked.

In GitHub Actions the result is also written to the job's step summary as a table.

GitHub Action

- uses: actions/checkout@v4
- uses: Ferdi-krbk/vendorcheck@v1
  with:
    path: build/addon      # folder or .xpi/.vsix/.zip
    # only: "yt-dlp requests"

The job fails when embedded code differs from the official release. The repo's own CI proves it: a clean vendored tree must pass and a tampered one must fail.

Real-world origin story: Auditing an extension

vendorcheck was built out of a real supply-chain audit: inspecting a popular Free Download Manager (FDM) extension package (Elephant.fda) that embedded its own Python runtime and bundled libraries like yt-dlp.

Instead of manually unzipping releases and writing one-off scripts, vendorcheck automates inspecting whole directories or extension packages in seconds:

$ vendorcheck Elephant.fda -v
yt_dlp 2026.8.19 [python/lib/site-packages!/]: 1049 files identical, 0 modified, 0 extra.

How it works

  1. Detect embedded packages through:
    • *.dist-info/METADATA or *.egg-info/PKG-INFO
    • version.py, _version.py, or __init__.py (__version__ = "...")
  2. Fetch official release metadata from PyPI:
    • Prefers pure Python wheels (-none-any.whl).
    • Intelligently matches compiled platform wheels for the host OS/Python (via packaging.tags).
    • Falls back to official source distributions (sdist).
    • Validates cryptographic SHA-256 against PyPI's published digest.
  3. Compare each file's SHA-256 digest:
    • Normalizes text line endings (CRLF vs LF git differences won't falsely flag).
    • Automatically ignores __pycache__ and bytecode (.pyc).
    • Computes unified diffs (-vv) for modified code.
  4. Report identical, modified, extra, or missing files.

Archives are extracted safely with strict directory traversal (zip-slip) protection; zero audited untrusted code is executed.

Limits

  • Packages completely stripped of all version indicators require metadata or a version attribute.
  • In cases where only sdist is available for C-extensions, build artifacts not present upstream may appear as "extra".
  • Archives nested deeper than 2 levels are not opened.
  • It proves your copy equals what PyPI serves, not that the PyPI release itself is benign. Combine with tools like pip-audit.
  • trustcheck verifies provenance/signatures of PyPI releases, not embedded code.
  • vendoring automates creating vendored trees; vendorcheck audits them.

License

MIT

Metadata

Release files for vendorcheck 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vendorcheck 0.3.1
File Size Uploaded
vendorcheck-0.3.1.tar.gz 12.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vendorcheck 0.3.1
File Interpreter ABI Platform
vendorcheck-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 24.6 kB

Release files / vendorcheck-0.3.1.tar.gz

Download URL vendorcheck-0.3.1.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cb3d5e0d8e6465a840c9be49a950e554f60029de81f29e8f250cd0f4dba78f2d
BLAKE2b-256 checksum
How to use checksums
b6fbe83d21be09e411cb90d1d1c9ab7c6eefa516e3fb1bb464a28d9bb83997b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.0

Release files / vendorcheck-0.3.1-py3-none-any.whl

Download URL vendorcheck-0.3.1-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
09cc3f0d0d8c26ae8c13a07c34f20ca768a8c5528b178f10f2eb937f06fd11e9
BLAKE2b-256 checksum
How to use checksums
904d89b352e650491ecce3025c9122024668f305bcc285b1aa9a8a1fd23267ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.0

Release history Release notifications | RSS feed

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page