Most SCA tools report license risk by flagging any dependency with a copyleft license. The resulting report contains hundreds of GPL and LGPL entries. Legal reviews the report, asks engineering to "resolve the GPL issues," and engineers close the ticket by adding the packages to an exceptions list without understanding what they're excepting. Compliance theater completes. The actual legal exposure remains unexamined.
This post is about what legal teams actually care about when they review open source license risk, and how to build a detection and triage model that produces actionable output instead of a long list of SPDX identifiers.
The copyleft spectrum is not a single risk level
SPDX-identified copyleft licenses span a wide range of obligations, and treating them uniformly is the root cause of most license compliance theater. The key distinction is between strong copyleft, weak copyleft, and network copyleft.
GPL-2.0 and GPL-3.0 are strong copyleft: if you distribute a binary that links against a GPL library, you must offer the complete corresponding source code of your combined work. For proprietary commercial software distributed to customers, this is a genuine problem. For internal tooling that never leaves your organization, the distribution clause doesn't trigger and the risk is near zero.
LGPL-2.1 is weak copyleft with an explicit carve-out for dynamic linking: you can use an LGPL library in a proprietary application without triggering the copyleft obligation, provided the user can relink the application against a modified version of the library. In practice, if your application dynamically loads an LGPL library and you're not modifying the library itself, most legal teams treat this as low risk. Statically linked LGPL is more complicated and worth legal review.
AGPL-3.0 is the one that catches teams by surprise. The Affero GPL extends copyleft to network use: if users interact with your software over a network and you've incorporated AGPL code, the distribution clause triggers even without shipping binaries. For SaaS applications, this means an AGPL library in your backend stack can require you to open-source your entire application. This is the genuinely high-risk license for most commercial software companies, and yet many SCA tools flag it at the same priority as a dynamically linked LGPL-2.1 utility library.
Linkage type matters more than the license name
Legal teams that understand this space ask two questions before assessing license risk: what is the license, and how is it linked? A GPL library that's invoked via subprocess with no source-level coupling is a different risk profile than one that's imported and called directly. A dynamically linked LGPL library is a different risk than a statically compiled one.
Most SCA tools, including Dependabot and standard Snyk reports, surface the license identifier without the linkage context. They don't distinguish between a GPL tool called as an external subprocess (low risk) and a GPL library compiled into your distribution binary (genuine obligation). This produces false positives that train engineers to ignore license flags, which is worse than not flagging at all.
Repohelm's license detection reports the SPDX expression from the package manifest, but we're direct about the limitation: we flag based on dependency graph membership and license identity, not binary linkage analysis. Binary linkage analysis requires your build system to be inspectable, which most package manifest scanners don't have access to. What we do provide is the dependency context: whether the package is a direct or transitive dependency, whether it's in a production dependency group or a dev dependency, and the dependency depth. Combined with your legal team's understanding of your build system's linking behavior, that's enough to triage the genuine risks from the noise.
Dev dependencies are almost never the problem
Consider a typical Node.js project: if you run a raw dependency license scan, you'll find a mix of GPL and LGPL packages in the full dependency tree. Run the same scan filtered to production dependencies only, excluding devDependencies, and the GPL count often drops to near zero. The GPL packages that showed up in the full tree were test runners, linters, build tools, and documentation generators. None of them ship with your product.
We're not saying dev dependencies never matter. If your build process statically bundles dev tooling into production artifacts, or if your CI generates outputs that are distributed to customers, the distinction breaks down. But for the common case, any license risk report that doesn't separate production and dev dependency groups is generating noise that obscures the genuine signals.
Repohelm's license policy configuration supports separate thresholds for production and development dependency groups. The default config blocks AGPL-3.0 in production and allows it in dev. Teams can tighten or loosen this per their legal position.
The license expression format is less simple than it looks
SPDX license expressions support compound forms: MIT OR Apache-2.0, GPL-2.0-only WITH Classpath-exception-2.0. The Classpath exception on GPL-2.0 is significant: it permits linking from non-GPL code without triggering copyleft. Java's OpenJDK ships under GPL-2.0 with Classpath exception, which is why it's broadly used in commercial applications.
A SCA tool that parses the license as "GPL-2.0" and flags it as high risk, ignoring the "WITH Classpath-exception-2.0" modifier, is generating a false positive that wastes legal time. Parsing SPDX expressions correctly is not complicated, but many tools don't do it.
When we built Repohelm's license detection, we prioritized parsing the full SPDX expression before making a flag decision. If the expression includes an exception that removes the copyleft obligation in your use case, the policy evaluation should reflect that. This is a small implementation detail that has a disproportionate effect on false-positive rate.
Building an allowlist that actually makes sense
The goal of license policy isn't zero GPL in your dependency tree. It's zero unexpected license obligations in your distributed software. Those are different targets, and the second one is actually achievable.
A practical allowlist for most commercial software companies looks something like this: permissive licenses (MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC) are allowed everywhere. LGPL-2.1 is allowed in production dependencies with dynamic linking assumed. LGPL-3.0 is allowed in production dependencies but requires review for any static linking scenario. AGPL-3.0 is allowed in dev tooling but blocked in production. GPL-2.0 and GPL-3.0 in production are blocked by default but can be individually allowed with a documented rationale.
This allowlist, encoded as a .repohelm.yaml policy, produces a much smaller alert volume than a blanket "flag all copyleft" approach. The remaining alerts are the ones that genuinely need legal attention: an AGPL library that's crept into a production backend, a GPL library imported directly rather than called as a subprocess.
The compliance review that matters is the one that examines ten specific packages with a clear question, not the one that produces a spreadsheet of 400 SPDX identifiers with no context about which ones are real obligations and which ones are test fixtures in your CI environment.