License Compliance
Why Compliance Matters
Every open source license has conditions. MIT requires you to include the copyright notice. Apache 2.0 requires the copyright notice plus the NOTICE file. GPL requires you to distribute source code. AGPL requires source distribution even for network use. Violating these conditions terminates your license, meaning you are using the software without permission — which is copyright infringement.
This is not theoretical. The Software Freedom Conservancy has enforced GPL compliance against companies including VMware. The Free Software Foundation has pursued compliance actions against router manufacturers distributing Linux-based firmware without providing source code. BusyBox developers have filed lawsuits against companies violating the GPL.
If your company ships a product — physical or digital — that contains open source software, compliance is a legal requirement, not a best practice.
Understanding Your Obligations
MIT: Include the Copyright Notice
The MIT license requires that the copyright notice and the license text be included in "all copies or substantial portions of the Software." In practice, this means:
- If you distribute a binary that includes MIT-licensed code, include the license text somewhere accessible (a LICENSES directory, an "About" dialog, a legal page on your website)
- If you distribute source code that includes MIT-licensed code, keep the copyright notice in the files
This is the lightest obligation of any open source license. Most companies comply by maintaining a NOTICES or THIRD_PARTY_LICENSES file that lists all MIT-licensed dependencies with their copyright notices.
Apache 2.0: Attribution & NOTICE File
Apache 2.0 has three requirements:
- Include a copy of the license
- Include a NOTICE file if the original project has one (the NOTICE file contains required attributions beyond the license)
- State any changes you made to the original code
The NOTICE file requirement catches people off guard. If a project includes a NOTICE file with specific attribution requirements, you must reproduce that NOTICE file in your distribution. Simply including the Apache 2.0 license text is not sufficient.
GPL v3: Source Code Distribution
The GPL v3 requires that when you distribute GPL software (in binary or source form), you must also make the complete source code available under the GPL. "Complete source code" means everything needed to build and install the software, including build scripts, installation scripts, and any linked libraries.
The obligations depend on how you distribute:
DISTRIBUTION METHOD OBLIGATION
---------------------------- ---------------------------------
Ship binary on physical media Include source on same media or
provide written offer for source
(valid for 3 years)
Distribute binary via download Provide equivalent access to
source code (same server, same
availability)
Distribute via network (SaaS) No obligation under GPL v3
(but see AGPL)
The "complete corresponding source" requirement is strict. You must include build instructions, scripts, and all modifications. Shipping a tarball of source code that does not compile does not satisfy the GPL.
AGPL v3: Network Use Triggers Distribution
The AGPL adds one critical clause: if users interact with the software over a network, you must provide the source code. This closes the SaaS loophole in the GPL.
If you run an AGPL web application, every user who accesses it must be able to download the complete source code — including your modifications. Many AGPL applications satisfy this by including a "Source code" link in the UI or footer.
LGPL: Dynamic vs Static Linking
The LGPL allows you to use LGPL libraries in proprietary software, but with conditions:
- Dynamic linking: If you dynamically link to an LGPL library (shared library / DLL), your proprietary code does not need to be LGPL. You must allow users to replace the LGPL library with a modified version.
- Static linking: If you statically link an LGPL library into your binary, you must provide the object files or source code necessary for users to relink with a modified version of the library.
In practice, most projects using LGPL libraries use dynamic linking to keep the boundary clean. This is why LGPL libraries (like glibc) are typically distributed as shared libraries.
GPL Dependencies Make Your Project GPL
This is the single most important compliance rule and the one most frequently violated.
If your project depends on a GPL library — and "depends on" means linking, importing, or otherwise incorporating the library into your program — your project must be distributed under the GPL or a GPL-compatible license. This is the copyleft effect: the GPL propagates to derivative works.
YOUR PROJECT (MIT license)
|
+--> depends on Library A (MIT) .......... OK
|
+--> depends on Library B (Apache 2.0) ... OK
|
+--> depends on Library C (GPL v3) ....... YOUR PROJECT
MUST BE GPL v3
This catches companies that do not audit their dependency trees. A single GPL dependency, even transitive (a dependency of a dependency), can change the licensing requirements for your entire project.
There are some important nuances:
- System libraries exception: The GPL excludes "System Libraries" from copyleft. Standard C libraries, system headers, and operating system components do not trigger copyleft even though they may be GPL.
- Separate programs: If your program and the GPL program are truly separate (different processes, communicating over pipes or sockets), copyleft may not apply. But the boundary is legally gray.
- Plugins: Whether a plugin system creates a derivative work is debated. The FSF argues that dynamically loaded plugins are derivative works; others disagree. This is an area where legal advice is warranted.
License Scanning Tools
Manual license auditing does not scale. A typical web application has hundreds of direct and transitive dependencies. License scanning tools automate the process.
FOSSA
FOSSA is a commercial license compliance platform. It scans your dependency tree, identifies all licenses, flags compliance issues, and generates attribution reports. FOSSA integrates with CI/CD pipelines so that license violations are caught before code is merged.
FOSSA handles complex scenarios: dual-licensed packages, license exceptions, and transitive dependencies. It is used by companies that need to demonstrate compliance to customers, auditors, or legal teams.
licensee (GitHub)
licensee is an open source tool (Ruby gem) that identifies the license of a project based on the LICENSE file. It uses fuzzy matching to identify licenses even when the text has been slightly modified. GitHub uses licensee internally to display license badges on repositories.
licensee is useful for identifying a single project's license but does not scan dependency trees.
license-checker (npm)
license-checker scans a Node.js project's node_modules directory and lists every package with its license. It can output the results as JSON, CSV, or plain text, and can flag packages with licenses that are not on an approved list:
USAGE
license-checker --production --json > licenses.json
license-checker --failOn "GPL-3.0;AGPL-3.0"
license-checker --onlyAllow "MIT;Apache-2.0;BSD-2-Clause"
The --failOn option integrates with CI: the build fails if any dependency uses a prohibited license.
cargo-deny (Rust)
cargo-deny is a Rust tool that checks dependencies for license compliance, security advisories, and duplicate crates. It reads a configuration file that specifies allowed and denied licenses:
DENY CONFIGURATION (simplified)
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause"]
deny = ["GPL-3.0", "AGPL-3.0"]
[advisories]
vulnerability = "deny"
unmaintained = "warn"
Running cargo deny check licenses in CI ensures that no one accidentally adds a GPL dependency to a permissively-licensed project.
Other Language Tools
- pip-licenses (Python): Lists licenses of installed pip packages
- license_finder (Ruby): Multi-language license scanning
- go-licenses (Go): Scans Go module dependencies for licenses
SBOM: Software Bill of Materials
An SBOM is a comprehensive list of all components (open source and proprietary) in a software product. Think of it as a nutrition label for software: it tells you exactly what ingredients are in the product.
SBOMs are becoming a regulatory requirement. Executive Order 14028 (May 2021) requires SBOMs for software sold to the US federal government. The EU Cyber Resilience Act includes SBOM requirements for products sold in the European Union.
SBOM Formats
Two standard formats dominate:
- SPDX (Software Package Data Exchange): An ISO standard maintained by the Linux Foundation. Used by many open source projects and government agencies.
- CycloneDX: An OWASP standard focused on security use cases. Widely adopted in the application security community.
Both formats capture the same core information: component name, version, license, supplier, and relationships between components.
Generating SBOMs
Most build tools can generate SBOMs:
SBOM GENERATION
# JavaScript (CycloneDX)
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
# Rust (cargo-sbom)
cargo sbom > sbom.spdx.json
# Python (CycloneDX)
cyclonedx-py requirements > sbom.json
# Go (SPDX)
spdx-sbom-generator
SBOMs should be generated as part of the release process and distributed alongside the software. This makes it easy for downstream users to audit the licenses and security status of all components.
What to Do When Licenses Conflict
Identify the Conflict
The most common conflict: a permissively-licensed project depends on a copyleft library. Your MIT-licensed application imports a GPL library, and now the GPL requires the entire application to be GPL.
Options for Resolution
Remove the dependency. Find a permissively-licensed alternative. This is the cleanest solution. If you need a JSON parser and the one you chose is GPL, switch to an MIT-licensed one.
Isolate the dependency. Run the GPL component as a separate process and communicate via IPC, sockets, or a network protocol. This avoids creating a derivative work (in most interpretations). This is how many proprietary applications interact with GPL tools — they invoke them as separate processes rather than linking against them.
Relicense your project. If the GPL dependency is essential and no alternative exists, you may need to accept the GPL for your project. This is a significant decision with business implications.
Obtain a commercial license. Many dual-licensed projects offer a commercial license as an alternative to the copyleft license. MySQL (GPL + commercial), Qt (LGPL/GPL + commercial), and MongoDB (SSPL + commercial, formerly AGPL + commercial) all offer this option.
Contact the author. For small projects, the author may be willing to grant a license exception or relicense under more permissive terms. This is common — many solo developers choose GPL by default without fully considering the implications and are happy to add a permissive option.
The Legal Risk of Ignoring Licenses
Companies that ignore license compliance face several risks:
Injunctive relief. A court can order you to stop distributing the infringing product. This happened in the BusyBox GPL enforcement cases — companies were required to stop shipping devices until they provided GPL-compliant source code.
Financial damages. Copyright infringement can result in statutory damages, actual damages, and legal fees. The amounts vary by jurisdiction but can be significant.
Customer trust. Enterprise customers increasingly require SBOM disclosure and license compliance documentation. Failing to provide these can cost sales, especially in regulated industries.
Audit costs. Discovering a compliance issue after years of ignoring it means auditing every product version, every dependency, and every customer deployment. Retroactive compliance is far more expensive than proactive compliance.
Building a Compliance Process
A practical compliance process for engineering teams:
LICENSE COMPLIANCE PROCESS
1. POLICY: Define approved licenses (usually MIT, Apache 2.0,
BSD, ISC). Define prohibited licenses (usually GPL, AGPL
for proprietary projects).
2. AUTOMATION: Add license scanning to CI. Fail builds that
introduce dependencies with prohibited licenses.
3. REVIEW: Manually review dependencies with unusual or
unknown licenses before approving.
4. ATTRIBUTION: Maintain a THIRD_PARTY_LICENSES file that
lists all open source dependencies with their copyright
notices and license texts.
5. SBOM: Generate an SBOM with each release. Distribute it
alongside the software.
6. TRAINING: Ensure developers understand license basics.
Most violations are accidental, not malicious.
The most important step is automation. If license checking is a manual process, it will be skipped. If it is a CI check that fails the build, it cannot be ignored.
Common Pitfalls
Assuming All Open Source Licenses Are the Same
"It's open source, so we can use it" is the most common compliance failure. MIT and AGPL are both open source, but their obligations are vastly different. Every dependency needs its license checked.
Ignoring Transitive Dependencies
Your project has 10 direct dependencies, but those dependencies have dependencies, which have dependencies. The actual count might be 500+ packages. A GPL library buried four levels deep in your dependency tree still triggers copyleft. Scan the full tree, not just direct dependencies.
Not Keeping Attribution Up to Date
The THIRD_PARTY_LICENSES file must be updated when dependencies change. If you add a new dependency and do not update attribution, you are out of compliance. Automate this as part of the build or release process.
Confusing Source-Available With Permissive
The Elastic License, Business Source License, and Server Side Public License look like open source licenses but restrict commercial use, SaaS deployment, or competing products. Do not assume that because the source is available, you can use it freely. Read the license terms.
Relying on License Fields in Package Metadata
The license field in package.json or Cargo.toml is informational — it is not the legal license. The actual license is the text in the LICENSE file. Sometimes these do not match. Trust the LICENSE file over the metadata.
Key Takeaways
- Every open source license has conditions. Violating them terminates your right to use the software and constitutes copyright infringement.
- GPL dependencies make your project GPL. This is the most impactful compliance rule and the one most frequently violated.
- Use license scanning tools (FOSSA, cargo-deny, license-checker) in CI to catch compliance issues before they reach production.
- Generate an SBOM with each release. SBOMs are becoming regulatory requirements in multiple jurisdictions.
- When licenses conflict, your options are: remove the dependency, isolate it as a separate process, relicense your project, or obtain a commercial license.
- Automate compliance. Manual processes get skipped. CI checks that fail builds cannot be ignored.