License compatibility checker for Python, JS/TS, Rust, Go, Java/JVM, .NET, PHP, Ruby, Elixir/Erlang, and R dependencies
Project description

licenseal
Fast cross-ecosystem license compatibility checker for CI, audits, and enterprise adoption.
| Prevent release blockers Catch dependency-license problems before release, approval, or audit. |
10 ecosystems Scan Python, JS/TS, Rust, Go, Java/JVM, .NET, PHP, Ruby, Elixir/Erlang, and R. |
Document reviews Use the Claude Code skill to investigate findings and record decisions. |
| Package |
|
| Quality |
|
| Tooling |
|
licenseal is a fast license compatibility checker for dependency trees across language ecosystems. It makes that compliance check cheap enough to run in CI: scan manifests, lockfiles, and public registry metadata, then tell you whether your dependency licenses are compatible with the license you ship under. It does not install dependencies, run package-manager commands, execute build scripts, or download package archives.
uvx licenseal check
Not legal advice. licenseal automates dependency-license discovery and compatibility classification. It is a CI/audit aid, not a substitute for legal review.
🧭 Why This Matters
License non-compliance is a quiet delivery risk: it usually does not break the build, but it can block a shipment, customer approval, funding round, or acquisition when discovered late. The problem usually surfaces when a customer, investor, legal reviewer, or procurement team asks what is inside your dependency tree:
| Blocker | What can happen |
|---|---|
| Enterprise adoption | Security and procurement teams ask for an open-source license report before approval. |
| Due diligence | Investors, acquirers, or partners flag copyleft, source-available, or unknown-license dependencies late. |
| Release timing | A problematic dependency forces a replacement, upgrade, or architecture change when the team is trying to ship. |
| Hidden transitives | The risky license is several levels down, pulled in by a package that looked harmless. |
| Product obligations | GPL, AGPL, SSPL, BUSL, Elastic, non-commercial Creative Commons, and similar terms may be incompatible with how you distribute or host the product. |
| Audit trail | Review decisions need to be explicit and checked in, not buried in a spreadsheet or chat thread. |
licenseal turns that hidden risk into fast CI feedback: it scans the transitive dependency tree, flags compatibility issues, and records reviewed decisions for cases that need human judgment. It is designed for PR gates, using manifests, lockfiles, and registries without install or build steps.
[!IMPORTANT] In a benchmark of 50 widely used open-source repositories across ten ecosystems, licenseal flagged 485 license-compatibility issues at default settings — 405 warnings and 80 outright violations, spanning 9 of the 10 ecosystems — each a dependency whose license needed compatibility review against the project's own declared license. Inventory-only license tools surface none of these.
Why this is not hypothetical
Public engineering policies and case history show why dependency-license checks matter. Google and Power publish restrictive guidance for licenses such as AGPL and SSPL, while Salesforce and Uber have written about license review in production software governance. GPL enforcement cases such as Artifex v. Hancom and Software Freedom Conservancy v. Vizio also show that dependency-license obligations can become real delivery and legal risk.
⚙️ How It Works
| 1. Read | 2. Resolve | 3. Classify | 4. Report |
|---|---|---|---|
| Manifests and lockfiles | Transitive dependency tree plus public registry license metadata | Project license vs dependency license compatibility | CI verdict, Markdown/JSON report, and checked-in review overrides |
🚀 Quick Start
Install-free one-shot:
uvx licenseal check
Persistent install:
uv tool install licenseal
# or
pipx install licenseal
Inside a Python project:
uv add --dev licenseal
# or
pip install licenseal
Example output:
The exit code is non-zero when there are unreviewed violations, warnings, unknown licenses, or analysis gaps. See USAGE.md for every flag and report format.
✨ What It Does
| Compatibility verdict Checks dependencies against your project license. |
Transitive by default Finds risks several levels down. |
Install-free Reads manifests, lockfiles, and registries only. |
| Agent-assisted review Claude Code skill investigates flagged findings and asks verdict-aware questions. |
Cross-ecosystem One scan for polyglot repos. |
CI-ready speed Seconds-scale scans in benchmark runs, with strict exits and JSON/Markdown output. |
🌐 Supported Ecosystems
Supported registries include PyPI, npm, crates.io, deps.dev, proxy.golang.org, Maven Central, NuGet.org, Packagist, RubyGems, Hex, and CRAN. See USAGE.md for manifest and lockfile details.
📊 How It Compares
Comparison last reviewed: June 2026. Tool capabilities change; check each project before making a buying or compliance decision.
CI license-compatibility workflow
| Capability | licenseal | pip-licenses | license-checker | LicenseFinder | fossa-cli |
|---|---|---|---|---|---|
| Project-license compatibility verdict | ✓ | - | - | ~ | ~ |
| Transitive discovery before install | ✓ | - | - | - | ~ |
| No successful install/restore required | ✓ | - | - | - | ~ |
| No dependency install/build step | ✓ | - | - | - | ~ |
| Fast, seconds-scale CI path | ✓ | ~ | ~ | - | - |
| Agent-assisted flagged-finding review | ✓ | - | - | - | - |
| Manual review override file | ✓ | - | ~ | ✓ | ~ |
Coverage and artifacts
| Capability | licenseal | pip-licenses | license-checker | LicenseFinder | fossa-cli |
|---|---|---|---|---|---|
| Multiple ecosystems in one tool | ✓ (10) | - | - | ✓ | ✓ |
| Dependency license report | ✓ | ✓ | ✓ | ✓ | ✓ |
| Local-only full workflow, no hosted service | ✓ | ✓ | ✓ | ✓ | - |
| Offline operation | - | ✓ | ✓ | ~ | - |
| Standards SBOM export (CycloneDX / SPDX) | - | - | - | - | ✓ |
✓ supported · ~ partial · - not supported
No tool clears every row. The discovery rows are about source-tree analysis: manifests, lockfiles, and registry metadata before a successful package-manager install is assumed. Some tools can produce broader inventories after installation or hosted analysis; licenseal is optimized for transitive dependency coverage in CI without that prerequisite. ~ means the capability exists, but with a different workflow, hosted service, package-manager prerequisite, or policy model. The speed row reflects benchmark runs on public repositories, not a vendor guarantee. Pair licenseal with an SBOM generator, hosted compliance platform, or installed-metadata scanner when those are the artifacts or workflows you need.
🧰 Important Defaults
| Default | Meaning |
|---|---|
--transitive |
Scans the transitive dependency tree by default. Use --no-transitive for direct deps only. |
--no-dev |
Dev dependencies are excluded unless --dev is set. |
--strict |
Warnings, unknowns, and analysis gaps fail CI in addition to violations. |
| Violations always fail | --no-strict demotes warnings, unknowns, and gaps only; definite incompatibilities still fail. |
Missing project license -> Proprietary |
If no project license is detected, licenseal labels the project Proprietary and checks dependencies as if it were permissively licensed — copyleft dependencies are still flagged, so the default errs strict, not lenient. |
| Registry-only resolution | No installs, builds, package archive downloads, or source-prose license extraction. |
🎯 Scope
licenseal is intentionally narrow:
- It is a license compatibility checker, not a legal approval workflow or policy-exception manager.
- It checks published dependency license metadata, not vulnerability status, provenance, or SBOM completeness.
- It reads manifests, lockfiles, and public registry metadata endpoints only. It does not honor private registry declarations from scanned manifests, because that would expand the network trust boundary.
- It does not infer dependency licenses by pattern-matching local
LICENSEfiles or source comments. Free-form license text is easy to misread, spoof, or partially match; missing structured metadata is reported asUNKNOWNand routed to manual review instead. - It produces Markdown/JSON dependency license reports, but not standards-compliant CycloneDX or SPDX SBOMs; use a dedicated SBOM tool when you need that artifact.
- Manual review can override flagged findings when a maintainer has better information, but the review file is an audit record, not hidden legal sign-off.
The full trust boundary and network allowlist are documented in SECURITY.md.
✅ CI Integration
GitHub Actions:
# .github/workflows/licenseal.yml
name: License compatibility
on: [push, pull_request]
jobs:
licenseal:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v6
- run: uvx licenseal check
README badge:
[](https://github.com/OWNER/REPO/actions/workflows/licenseal.yml)
Preview:
Use the workflow status badge as the primary signal: it shows that license compatibility is checked in CI and that the latest run passed.
For a PR comment or audit artifact, write Markdown or JSON. The file is saved before the gate runs, so CI can publish it even on a failing check:
licenseal check -f markdown -o LICENSES.md # PR-comment-friendly audit
licenseal check -f json -o report.json # stable machine-readable schema
For projects that want a checked-in audit trail, commit the generated Markdown report as LICENSES.md. This repository follows that convention in LICENSES.md.
The JSON schema is documented in JSON_OUTPUT.md.
🧾 Manual Review Overrides
When a dependency is flagged but you have better license information than the resolver, record the reviewed license in a checked-in licenseal.review.toml:
[[review]]
ecosystem = "python"
package = "mystery-lib"
version = "1.0.0"
license = "MIT"
note = "reviewed packaged LICENSE file"
Workflow:
licenseal check -f json -o report.json # 1. capture flagged deps
licenseal init-review-file --from-report report.json # 2. scaffold blank entries offline
# 3. fill in `license` and optional `note` for each entry
licenseal check # 4. overrides apply
Reviews can only override flagged dependencies, never compatible ones. A reviewed dependency passes strict mode while staying visible in its warning, violation, or unknown bucket with both the detected and reviewed licenses shown.
licenseal also ships a Claude Code skill (licenseal install-skill, then /licenseal-review) that walks through unknowns, warnings, and violations interactively. It can inspect package links, license links, and project context, then ask the questions that matter for how your software is distributed, hosted, or modified. Full review rules are in USAGE.md.
🧩 How Licenseal Decides
licenseal classifies each dependency license into a risk level and compares that risk against the detected project license.
| Project \ Dependency | Permissive | Weak Copyleft | Strong Copyleft | Network Copyleft |
|---|---|---|---|---|
| Permissive | OK | Warning | Violation | Violation |
| Weak Copyleft | OK | OK | Violation | Violation |
| Strong Copyleft | OK | OK | OK | Warning |
| Network Copyleft | OK | OK | OK | OK |
When --dev is set, copyleft violations on dev dependencies are downgraded to warnings — licenseal treats dev deps as lower risk because they usually do not ship with the project.
| Risk level | Examples | Meaning |
|---|---|---|
| Permissive | MIT, BSD, Apache-2.0, ISC | No significant restrictions |
| Weak Copyleft | LGPL, MPL-2.0, EPL, CDDL | File-scope reciprocity; linking from other files is usually allowed |
| Strong Copyleft | GPL, OSL, EUPL, CC-BY-SA | Share-alike obligations can extend to the derivative work |
| Network Copyleft | AGPL-3.0-only | Strong copyleft with network-use source-offer obligations |
| Unknown | SSPL, BUSL, Elastic, CC-BY-NC; missing or unrecognized licenses | Cannot be auto-classified; routed to manual review |
A dependency is Unknown when the registry returns no license, a non-SPDX string, or a source-available / use-restricted license (SSPL, BUSL, Elastic, FSL, Parity, PolyForm, CC-BY-NC* / CC-BY-ND*) whose custom terms are not auto-evaluated. The full matrix rationale is in USAGE.md.
Learn More
- USAGE.md - full CLI reference, transitive-resolution behavior, per-ecosystem detail, review-file rules, and the Claude Code skill
- SECURITY.md - the manifest-and-registry trust boundary and exact network-egress allowlist
- JSON_OUTPUT.md - stable machine-readable schema
Contributing
See CONTRIBUTING.md for development setup and guidelines.
If licenseal helps your project, star ⭐ this repo to help other teams find it too.
License
Apache-2.0. See LICENSE for the full text and NOTICE for attribution.
More from shcherbak_ai
| Project | What it does |
|---|---|
| 💎 ContextGem | Structured extraction from documents with LLMs. |
| 🪁 tethered | Network egress control for CLI tools and agent workflows. |
Connect
Questions or collaboration ideas? Reach out on LinkedIn or X.
Built with ❤️ in Oslo, Norway.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file licenseal-0.1.2.tar.gz.
File metadata
- Download URL: licenseal-0.1.2.tar.gz
- Upload date:
- Size: 270.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9bdb8f472600311dd137a57ca2d3dee0a57777ccb05537a5be4dc391e870fad
|
|
| MD5 |
ae9e276665c4e8f0a56463e8bba704da
|
|
| BLAKE2b-256 |
54a0ddac3c3582e3fd770feea174cf43d4c3234b3283e42dbbffbc184642054b
|
Provenance
The following attestation bundles were made for licenseal-0.1.2.tar.gz:
Publisher:
publish.yml on shcherbak-ai/licenseal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
licenseal-0.1.2.tar.gz -
Subject digest:
d9bdb8f472600311dd137a57ca2d3dee0a57777ccb05537a5be4dc391e870fad - Sigstore transparency entry: 1736290071
- Sigstore integration time:
-
Permalink:
shcherbak-ai/licenseal@fd4b8af40852aeb6f87208285a5540f16e708e0c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/shcherbak-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fd4b8af40852aeb6f87208285a5540f16e708e0c -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file licenseal-0.1.2-py3-none-any.whl.
File metadata
- Download URL: licenseal-0.1.2-py3-none-any.whl
- Upload date:
- Size: 322.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd77096a90126cbb173348dfb0cd4c2c5662df4095dea4dde6d876b394f8578e
|
|
| MD5 |
86349b3023193a843116a1a07c0f401c
|
|
| BLAKE2b-256 |
c5d33594c494e9e6a0f47fb2b1094c6ccf5384263ffa94181a375e59c93cceaa
|
Provenance
The following attestation bundles were made for licenseal-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on shcherbak-ai/licenseal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
licenseal-0.1.2-py3-none-any.whl -
Subject digest:
fd77096a90126cbb173348dfb0cd4c2c5662df4095dea4dde6d876b394f8578e - Sigstore transparency entry: 1736290163
- Sigstore integration time:
-
Permalink:
shcherbak-ai/licenseal@fd4b8af40852aeb6f87208285a5540f16e708e0c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/shcherbak-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fd4b8af40852aeb6f87208285a5540f16e708e0c -
Trigger Event:
workflow_run
-
Statement type: