10 min read
On this page

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

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:

  1. Include a copy of the license
  2. Include a NOTICE file if the original project has one (the NOTICE file contains required attributions beyond the license)
  3. 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.

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

  1. Every open source license has conditions. Violating them terminates your right to use the software and constitutes copyright infringement.
  2. GPL dependencies make your project GPL. This is the most impactful compliance rule and the one most frequently violated.
  3. Use license scanning tools (FOSSA, cargo-deny, license-checker) in CI to catch compliance issues before they reach production.
  4. Generate an SBOM with each release. SBOMs are becoming regulatory requirements in multiple jurisdictions.
  5. When licenses conflict, your options are: remove the dependency, isolate it as a separate process, relicense your project, or obtain a commercial license.
  6. Automate compliance. Manual processes get skipped. CI checks that fail builds cannot be ignored.