Skip to main content

licenseproof

License: MIT Python 3.9+ No dependencies

Your package has a license. Your wheel doesn't say so.

Real case, still reproducible today: protocolbuffers/protobuf#29440. The protobuf-7.36.0 wheel's METADATA says License: 3-Clause BSD License — free text, not an SPDX expression — and carries no License-Expression field at all (Metadata-Version 2.1). To be precise: the wheel does ship a dist-info/LICENSE file, so this is "missing License-Expression (PEP 639)", not "no license at all". A previous fix attempt (#9441) didn't fully fix it; the issue is still open. Any compliance tooling that keys on SPDX expressions sees this wheel as unparseable.

A sharper flavor of the same disease: ag-ui-protocol/ag-ui#1927 — the ag_ui_strands-0.1.9 wheel has License: None, no License-Expression, no License-File, and zero license files anywhere in the archive. The monorepo root is MIT-licensed, but the published artifact inherits none of it (the hatch wheel config only includes src/). Compliance scanners flag it "unknown license", which blocks enterprise adoption outright.

licenseproof checks that a published Python artifact actually carries usable license information — the release-integrity question nobody's CI asks.

This is deliberately not a generic license scanner (pip-licenses, ScanCode already cover that). It answers one narrow question: does this wheel/sdist contain license metadata and license text a compliance tool can use?

Part of the release-integrity series: readmeta (did your README render?), wheeltruth (did your wheel ship complete?), casecrash (will your filenames survive checkout?), tagtruth (does the tag match the release?), wheelreach (can your Python actually install it?), entryprobe (does the installed CLI actually start?), licenseproof (does the artifact say what license it's under?).

Quickstart

pip install licenseproof  # PyPI upload pending rate limits; from source meanwhile:
# git clone https://github.com/hahahahahahahahah6/licenseproof && pip install ./licenseproof
licenseproof check --wheel dist/mypackage-1.0-py3-none-any.whl
source:  dist/mypackage-1.0-py3-none-any.whl
verdict: LEGACY_LICENSE
detail:  License: 'MIT' (free text, not SPDX); no License-Expression (PEP 639)

clean (legacy license info is a warning; use --require-spdx to fail)
licenseproof check --sdist dist/mypackage-1.0.tar.gz
licenseproof check --package mypackage          # installed distribution
licenseproof check --wheel dist/x.whl --require-spdx
licenseproof check --wheel dist/x.whl --format json

Exit codes: 0 clean, 1 problems found, 2 errors (unreadable artifact, bad args).

Verdicts

Verdict Meaning Fails?
LICENSE_OK a License-Expression field is present (presence only — the expression is not semantically validated against the SPDX list); any License-File references exist in the dist no
LEGACY_LICENSE only old-style license info — free-text License: field, trove classifiers, and/or undeclared license text files; no License-Expression only with --require-spdx
MISSING_LICENSE no license metadata and no license text files in the dist yes
LICENSE_FILE_MISSING License-File metadata references files absent from the dist yes

Design notes:

  • LEGACY_LICENSE is a warning by default, not a failure. Most of PyPI predates PEP 639; failing every one of them would be noise, not signal. --require-spdx is the strict mode for projects that have decided to move.
  • A License: field containing UNKNOWN (or blank) counts as absent — that's setuptools' default, not information.
  • License-File values are matched explicitly by layout: wheels/installed dists expect them under *.dist-info/licenses/ (PEP 639) or legacy *.dist-info/; sdists expect them project-root-relative under the top-level <name>-<version>/ directory. No basename-only fallbacks, no .. escapes.
  • An unparseable situation is never a silent pass: a License-File reference that matches nothing is its own failing verdict, not ignored.

What licenseproof does not verify

It checks the presence and machine-readability of license information, not its meaning. A passing result confirms that the expected license metadata fields and referenced files are present — License-Expression is checked for presence, but SPDX identifiers and expressions are not semantically validated. It does not interpret license compatibility (can MIT depend on GPL?) or offer any legal interpretation. For "what does this license obligate me to do", use a real compliance tool — licenseproof just makes sure the artifact gives that tool something to work with.

Metadata

Release files for licenseproof 0.1.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 licenseproof 0.1.1
File Size Uploaded Provenance Actions
licenseproof-0.1.1.tar.gz 13.9 kB Without provenance Details for licenseproof-0.1.1.tar.gz

Built distribution (wheel)

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

Total release size: 24.5 kB

Release files / licenseproof-0.1.1.tar.gz

Download URL licenseproof-0.1.1.tar.gz
Size 13.9 kB
Tags Source
SHA-256 checksum
How to use checksums
c7c6f1585a1af91ae81bde4c863460db4dd76fb368c7c6d22784b62f2ea0d37e
BLAKE2b-256 checksum
How to use checksums
ef10f21c09a9d969dd8512c1c38886c16857be0a1d6a0b937d7ac65d4b497ab4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / licenseproof-0.1.1-py3-none-any.whl

Download URL licenseproof-0.1.1-py3-none-any.whl
Size 10.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
51f9bebbe8c08842e08ea0a9d2d393a76c844e772803504652d3561b3990521b
BLAKE2b-256 checksum
How to use checksums
28044faa2f7167a47760ae8ffbb249fee42042b75e5770c6b591549670a28083
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for licenseproof 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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