SCA tools are good at enumerating licenses. They're significantly less good at explaining what those licenses mean in the context of your specific deployment model. GPL-3.0 showing up in your SBOM is not automatically a legal problem — but it could be, and the difference between "harmless" and "distribution compliance obligation" depends on how your software is packaged, deployed, and monetized. That distinction rarely gets explained in a scan report.
This article is written for engineering leads who get a license risk report from their SCA tooling and don't know what to do with it. It's also written for legal counsel who get escalated tickets from engineers that say "we found a GPL-3.0 dependency" with no further context. Both groups tend to make the same mistake in opposite directions: engineers dismiss the flag, legal teams treat every copyleft dependency as a blocker. Neither response is right.
How Copyleft Propagation Actually Works
The GPL family of licenses (GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, AGPL-3.0) is built around the copyleft principle: if you distribute a derivative work that incorporates a copyleft-licensed component, the derivative work must be offered under the same license. The critical word is distribute. Internal use — software you run in your own infrastructure that never leaves your organization — does not trigger GPL's distribution requirements under the FSF's interpretation of GPL-2.0 and GPL-3.0.
This is the fact that most engineering teams either don't know or get wrong. A GPL-3.0 licensed library used in a backend service that only your own employees call does not, under the standard GPL interpretation, require you to open-source your proprietary service code. You're not distributing the software; you're running it.
When Distribution Occurs
Distribution in the GPL sense includes: shipping a binary to an end user (mobile apps, desktop software, embedded firmware), providing software as a download, and — critically — distributing container images to customers or partners. A SaaS model where customers access your service via API is generally considered "providing a service," not distributing software, and does not trigger GPL's distribution clause.
This is why AGPL-3.0 exists. The Affero GPL was specifically designed to close the "SaaS loophole" in GPL-3.0: AGPL-3.0 requires offering source code to users who interact with the software over a network, even if no binary is distributed. An AGPL-3.0 dependency in your customer-facing web service is a materially different risk than a GPL-3.0 dependency in the same position. Most SCA tools report both as "copyleft" without distinguishing the distribution threshold.
SSPL: The License Most Teams Haven't Analyzed
The Server Side Public License (SSPL) was authored by MongoDB and is used by several popular infrastructure projects. It goes further than AGPL-3.0: if you use SSPL-licensed software to provide a service, you must release the source code of everything used to deliver that service — including your proprietary application layer, management layer, and tooling.
Most legal teams have not reviewed the SSPL clause by clause. Many SCA tools categorize SSPL as "strong copyleft" and surface it with the same severity as GPL-3.0, which significantly understates the risk for SaaS businesses. The SSPL is not recognized as an OSI-approved open source license precisely because of this service-provider scope. If your SBOM contains an SSPL-licensed component and you're running a commercial SaaS product, this warrants legal review independent of how your SCA tool classifies it.
We're not saying SSPL-licensed software is off-limits — many teams use it knowingly, under commercial license agreements that supersede the SSPL terms. We're saying the open-source version of SSPL-licensed software carries compliance obligations that are distinct from standard copyleft, and a "copyleft detected" badge from your SCA tool doesn't convey that distinction.
Where SCA License Detection Falls Short
Modern SCA tools detect licenses by matching SPDX identifiers in package metadata, scanning license files in the package directory, and comparing source headers against known license fingerprints. This works well for directly declared licenses. It works less well for:
- Dual-licensed packages: A package may be available under both a permissive license (MIT, Apache-2.0) and a commercial license. The SCA tool may report only the open-source variant, missing the fact that certain use cases require the commercial license.
- License header inconsistencies: Some packages have mismatched metadata (the
package.jsonsays MIT, but individual source files carry GPL headers). SCA tools vary significantly in how they handle this — some report the metadata license, some report the most restrictive license found, some flag it as ambiguous. - Transitive license propagation: Your direct dependency is MIT. Its dependency is LGPL-2.1. How LGPL-2.1 propagates depends on whether the LGPL code is statically linked (triggers copyleft) or dynamically linked (may not trigger copyleft under LGPL's specific exception). In a compiled Go binary or a bundled JavaScript application, the distinction between static and dynamic linking is blurry. Few SCA tools flag this nuance; most just list the transitive LGPL as a finding.
A Practical Triage Workflow for License Findings
Consider this scenario: a growing B2B data platform team preparing for their first enterprise customer audit ran SCA scanning across their 40-service K8s deployment. The scan surfaced 127 license findings. Of those, 84 were MIT or Apache-2.0 variants — no review needed. 31 were LGPL-2.1 in Python packages used for data processing. 8 were GPL-3.0 in internal build tooling. 4 were AGPL-3.0 in two backend microservices. Zero were SSPL.
The defensible triage path was: clear the 84 permissive licenses immediately, assign LGPL-2.1 to engineering for linkage review (they were imported as Python packages and dynamically loaded — no static linkage concern), escalate the 8 GPL-3.0 build tool cases to confirm they were internal-only tools not distributed to customers (they were), and route the 4 AGPL-3.0 findings to legal for service provider review. The entire review completed in three days because the triage categories were clear from the start.
Without a triage framework, the same 127 findings sit in a backlog for months because no one owns the review process and engineering treats all of them as equally ambiguous.
The Four-Bucket Framework
A practical four-bucket system that works across most K8s-deployed SaaS products:
- Permissive (MIT, Apache-2.0, BSD-2/3, ISC, Unlicense): No distribution obligation, no copyleft propagation. Clear automatically.
- Weak copyleft requiring engineering review (LGPL-2.1, LGPL-3.0, MPL-2.0): Route to engineering. Question is: static or dynamic linkage? If dynamic, typically non-propagating. If static (compiled into a binary), may require source offer.
- Strong copyleft requiring legal review (GPL-2.0, GPL-3.0, AGPL-3.0): Route to legal with the deployment context: is this component distributed to external parties, or internal use only? What is the service delivery model?
- Non-standard or unclear (SSPL, BUSL, custom): Escalate immediately with the full license text. Do not rely on SCA tool classification alone.
What SBOM Generation Adds to License Review
A CycloneDX SBOM captures license metadata for every component in the resolved dependency graph — including transitive dependencies — and outputs it in a format that legal teams and procurement tools can ingest directly. This is more useful than a standalone SCA scan report because the SBOM is version-controlled and regenerated on every build, meaning license risk is continuously tracked rather than point-in-time.
When a new transitive dependency is introduced that carries AGPL-3.0 — because a developer updated a direct dependency that quietly added a new transitive package — the SBOM diff between build N and build N+1 surfaces the license change as a delta item, not buried in a full re-scan. This is dependency drift detection applied to license risk: the question isn't just "what licenses do we have?" but "what changed since the last approved build?"
License compliance is ultimately a combination of engineering (know what's in your dependency graph), legal (understand the specific obligations), and process (have a triage and review workflow that actually routes findings to owners). SCA tooling covers the first part. The teams that avoid unpleasant legal surprises are the ones that built the second and third parts before their first enterprise customer asked for a software composition report.