Open-Source Compliance

FOSS License Risk in the Software Supply Chain

Luca Bertrand 12 min read
Abstract supply chain of open-source software components

License risk in the software supply chain is a distinct category from contributor IP risk — and conflating the two is one of the most common errors in early-stage compliance programs. CLA management addresses the rights you receive from contributors who add code to your project. License compliance addresses the obligations you inherit when you depend on code that other people have already written and released.

Both matter. They operate on different timescales and require different tooling, but they inform each other in ways that make understanding both necessary for a coherent compliance posture.

How License Risk Actually Accumulates

In a typical enterprise software project, the direct dependency count is manageable — maybe 50 to 150 packages declared in your package.json, pom.xml, or go.mod. The total transitive dependency count is often 10-20x that. A modest Node.js application with 80 direct dependencies may have 900+ transitive dependencies once you trace the full graph.

Every one of those transitive dependencies carries a license. Some of those licenses impose obligations on how you distribute the software that depends on them. The license risk isn't in the obvious GPLv3 package you knowingly chose — it's in the transitive dependency three levels deep that changed licenses between minor versions, or in the dependency whose license file is inconsistent with its SPDX identifier in the package manifest.

The SPDX (Software Package Data Exchange) specification, maintained by the Linux Foundation, provides a standardized format for expressing license information in software packages. SPDX identifiers like Apache-2.0, MIT, GPL-2.0-only, and LGPL-2.1-or-later are machine-readable and unambiguous. The problem is that not all packages use SPDX consistently, and the license field in many package manifests is a free-form string that was never validated against the SPDX vocabulary.

The License Compatibility Matrix

License compatibility determines whether you can legally combine code under different licenses in a single distributed work. The interaction rules are complex and context-dependent, but the broad categories are:

  • Permissive licenses (MIT, BSD-2-Clause, Apache-2.0): Generally compatible with each other and with proprietary software. Apache-2.0 adds a patent termination clause absent from MIT/BSD; this is typically not a practical concern for most use cases but can matter in specific patent-sensitive contexts.
  • Weak copyleft (LGPL, MPL-2.0): The copyleft obligation applies to modifications of the licensed component itself, but does not extend to software that links against or uses the component without modifying it. The boundary between "modification" and "use" is where most compliance questions arise with LGPL.
  • Strong copyleft (GPL-2.0, GPL-3.0): Any work that incorporates GPL-licensed code and is distributed as a single combined work must be distributed under GPL-compatible terms. "Distributed" is the operative word — software running internally without distribution to third parties typically doesn't trigger GPL obligations, though this is jurisdiction-dependent.
  • Network copyleft (AGPL-3.0, EUPL-1.2): The copyleft obligation extends to software that is made available over a network (not just distributed as a binary). This is the category that most frequently surprises organizations running AGPL-licensed databases or services in their stack.

We're not saying GPL-licensed dependencies are categorically problematic — in many contexts, particularly internal tooling or infrastructure where no distribution occurs, GPL packages are used without issue. The question is whether your specific use case triggers the distribution conditions, and whether you have an exception or alternative licensing arrangement if it does.

The Software Bill of Materials (SBOM)

An SBOM is a machine-readable inventory of all software components in a given product, including their version, license, and provenance. SBOM generation is the prerequisite for meaningful license compliance analysis — you can't assess license risk across a dependency graph you haven't enumerated.

Two standard formats have emerged:

  • SPDX (ISO/IEC 5962:2021): The Linux Foundation's standard, mature and widely supported. SPDX documents can express license expressions, relationships between packages, and package checksums.
  • CycloneDX: OWASP's SBOM standard, with a focus on security and supply chain risk. More actively developed in terms of vulnerability data integration.

Both standards are supported by the major SCA (Software Composition Analysis) tools and are required for US federal software procurement under Executive Order 14028 and the associated NTIA minimum SBOM elements guidance. If any of your customers are US government agencies or government contractors, SBOM generation is no longer optional — it's a contract deliverable.

Where License Risk Intersects with CLA Management

The intersection between license compliance and CLA management appears most clearly in two scenarios:

Relicensing and contribution history. When you want to change your project's license — moving from AGPL to Apache-2.0 to enable commercial use, for example, or dual-licensing for a commercial offering — you need either: (a) copyright ownership of all contributions, (b) sufficiently broad license grants from all contributors, or (c) the ability to contact and get explicit relicensing consent from all significant contributors. A well-maintained CLA program with a broad license grant clause makes (b) possible. Without it, relicensing requires tracking down every contributor who ever submitted a meaningful patch — a process that becomes exponentially harder as the project ages.

Inbound contribution license compatibility. Your project's inbound contribution policy should specify what license terms govern contributions. If your project is Apache-2.0 licensed and your CLA grants you rights under Apache-2.0-compatible terms, you need to verify that contributors aren't themselves incorporating GPL-licensed code into their contributions. This is where contributor code review and CLA scope interact: the CLA grants you rights, but only to the extent the contributor actually has those rights to grant.

Supply Chain Attack Surface: License Mutations

A less-discussed supply chain risk is license mutations — packages that change their license between versions. The historical pattern was permissive licenses evolving toward more restrictive terms as projects became commercially significant. Several infrastructure packages have undergone license changes from permissive to server-side-public-license or similar non-OSI-approved terms.

From a compliance operations standpoint, this means your dependency license inventory can go stale not only when you add new dependencies but when existing dependencies release new versions. A dependency approval process that operates only at adoption time misses the drift that occurs over the life of the project.

Consider a growing fintech engineering team that audited their microservices stack and found that a database driver they'd been using since their early days had changed its license to a Commons Clause-encumbered license in a minor version update two years prior. Their automated dependency updates had been picking up the newer versions without any license review trigger. The Commons Clause addition wasn't visible in standard SCA scans that only looked at SPDX identifiers — the identifier was unchanged, but the effective terms had changed. Their compliance team only discovered it during a customer security questionnaire review that happened to ask about license terms for critical data layer dependencies.

This scenario isn't a hypothetical edge case — it reflects a pattern that's played out with enough real packages that any serious compliance program needs license-change alerting as a standard component.

Building a Practical License Review Process

The goal is a process that doesn't create a bottleneck for every dependency adoption but catches the cases that actually matter. The practical structure:

  1. Approved license list: Maintain a list of license categories that are pre-approved for your use case (typically: MIT, BSD-2-Clause, BSD-3-Clause, Apache-2.0, ISC — the standard permissive set). Packages under these licenses can be adopted without individual review.
  2. Review-required list: Licenses that require human review before adoption (LGPL, MPL-2.0, CDDL, EUPL). Legal review the specific use case rather than categorically blocking.
  3. Blocked list: Licenses that are categorically incompatible with your distribution model or business requirements (typically strong copyleft if you distribute proprietary software, or AGPL if you operate SaaS without wanting to open-source your stack).
  4. License change monitoring: Automated alerts when a dependency in your lock file changes its declared license between versions. This is the gap most SCA tools don't cover without explicit configuration.

The approved/review/blocked triaging framework exists in some form in most mature OSPOs. The gap is usually in step 4 — the reactive monitoring that catches drift after initial adoption. Getting that monitoring in place is the difference between a compliance program that handles the common cases and one that catches the incidents before they escalate.