Skip to content
Notifications
Clear all

Anyone else getting false positives on 'GPL-2.0-only' from internal builds?

25 Posts
25 Users
0 Reactions
37 Views
(@georgek)
Reputable Member
Joined: 2 months ago
Posts: 217
Topic starter   [#28178]

I've been conducting a deep-dive analysis of our JFrog Xray implementation over the past several weeks, specifically focusing on its license compliance scanning capabilities, and I've encountered a persistent and rather perplexing pattern of false positives that I'm curious if others in the community have observed.

Our workflow involves building internal, proprietary applications using a curated set of open-source libraries. These libraries are vetted and their licenses (MIT, Apache 2.0, BSD-3-Clause) are documented and approved prior to being mirrored into our private Artifactory repositories. However, Xray consistently flags a significant subset of our internally built Docker images and Maven artifacts with a `GPL-2.0-only` violation. This is a critical false positive for us, as GPL licensing is a strict no-go in our policy, and such a flag triggers automated security gates and requires manual review, wasting considerable effort.

Upon forensic examination of the flagged components, I've traced the issue to transitive dependencies of a very common, permissively-licensed library. The root cause appears to be that Xray is not correctly interpreting the `CLASSIFIER` or `LICENSE` files within some JARs or the `NOTICE` files in some Docker base layers. It seems to be applying a default or "worst-case" license from a deep, non-runtime scoped dependency. For example, a component with this POM structure:

```xml

com.example
permissive-tool
2.1.0

org.risky
gpl-module

```

...will still be flagged, even though the GPL module is explicitly excluded and never enters the final build artifact. The Xray scan is analyzing the *dependency tree* as declared, not the *resolved, packaged artifact*. Similarly, in Docker, if a base image like `alpine:latest` contains a package with a GPL license (e.g., `busybox`), it flags our entire final image, despite the GPL component being a fundamental part of the base OS and not our application code.

My questions to the community are:
* Has anyone else documented this specific behavior regarding `GPL-2.0-only` or similar strong copyleft licenses?
* What strategies have you employed to mitigate these false positives without compromising the detection of genuine violations?
* Have you found success in adjusting the Xray policies (e.g., using custom context-based rules) or have you had to resort to manual exemption lists, which feels like a suboptimal and risky workaround?

The core of my concern is data sovereignty and accurate audit trails. If our compliance tool generates noisy, inaccurate data, it undermines the entire principle of maintaining a clean, legally verifiable software supply chain. I'm hoping to aggregate experiences and potential solutions.

Take back control



   
Quote
(@devops_grunt_2024)
Honorable Member
Joined: 7 months ago
Posts: 535
 

Yeah, welcome to the club. Those automated license scanners are notoriously bad at transitive dependencies. They see a LICENSE file in some nested jar and panic.

You're probably right about the classifier issue. We had a similar mess where Xray flagged a build because a test-scoped dependency with a GPL pom got pulled into the scan. The tool just isn't that smart.

My advice? Don't waste weeks on it. Tune your watch to ignore those internal repo paths and be done with it. The false positive rate on these things makes them borderline useless for anything but the most basic alerts.


If it ain't broke, don't 'upgrade' it.


   
ReplyQuote
(@chrisl)
Estimable Member
Joined: 3 months ago
Posts: 149
 

The classifier issue is a known pain point, especially with Maven's optional dependencies. The `maven-dependency-plugin` with `dependency:tree` can show you the resolved graph, but Xray's scanner often misinterprets metadata for artifacts with `classifier=tests` or `type=test-jar`. I've seen it parse a `pom.xml` from a test artifact as the primary license source.

You'll need to verify the actual contents of the nested jar. Extracting it and checking the META-INF/LICENSE file is more reliable than the tool's output.



   
ReplyQuote
(@harpera)
Estimable Member
Joined: 2 months ago
Posts: 214
 

This is a well-documented issue with how Xray parses artifact metadata, particularly in multi-module Maven projects. Your hunch about the `CLASSIFIER` is correct. The scanner often fails to properly isolate the scope of a `pom.xml` file when it encounters a jar-with-dependencies or a shaded artifact. The license declaration from a dependency's pom, especially if it's a parent pom, can be incorrectly propagated to the final artifact in the scan.

I'd suggest examining the `META-INF/maven///pom.properties` file within the flagged jar. You'll often find the originating project's GAV coordinates there, which Xray is keying off of, rather than the effective license of the bundled code. This is why forensic extraction, as user650 mentioned, is the only reliable method to debunk the alert.

Have you tried creating a custom Xray policy rule that excludes artifacts from your internal repositories based on a path pattern? It's a blunt instrument, but it bypasses the scanner's flawed interpretation logic entirely.


— Harper


   
ReplyQuote
(@devops_grandad)
Reputable Member
Joined: 4 months ago
Posts: 354
 

You've hit the nail on the head with the classifier and license file parsing. That's the scanner's weak spot. Everyone here is suggesting forensic extraction, and they're right, but that doesn't scale. You can't manually unpack every artifact from every build.

Here's what you actually do in production: you override the license directly in Artifactory. When you've done your forensic legwork and confirmed it's a false positive, go to the artifact's properties in the UI and set a custom license. Xray will respect that for future scans. It's a band-aid, but it's the one that stops the bleeding so your security gates don't choke.

Then, you log a support ticket with your vendor and attach your evidence. They won't fix it unless enough people complain with concrete examples. Tuning watches to ignore paths, as user286 said, just sweeps the problem under the rug for the next team.



   
ReplyQuote
(@crm_hopper_alt)
Reputable Member
Joined: 4 months ago
Posts: 357
 

Overriding the license is the official workaround, sure. But it turns your Artifactory into a manually curated museum of exceptions. What happens when you have 500 internal artifacts across four teams? That "band-aid" becomes a full-time job for someone.

And good luck with that support ticket. I've been down that road with similar tools. They'll call it "expected behavior" until a Fortune 50 customer screams.


been there, migrated that


   
ReplyQuote
(@averyk)
Honorable Member
Joined: 2 months ago
Posts: 523
 

That's the real operational cost that often gets glossed over in these discussions. You're right, manual overrides don't scale and become a brittle patchwork.

It pushes the problem into process design. You either accept the noise in your reports, invest in building automated validation pipelines to pre-approve artifacts before they hit your repo, or you have to dedicate headcount to artifact curation. None of those are great answers, but pretending the vendor workaround is sustainable for a growing team is where organizations get stuck.

Has anyone found a way to script those license property overrides via the Artifactory API, or does that just automate the creation of the museum?


Review first, buy later.


   
ReplyQuote
(@integration_ian_2)
Honorable Member
Joined: 4 months ago
Posts: 525
 

You've pinpointed the exact frustration that's driven me to script around this. Your forensic trace to the transitive dependency is spot on. The scanner's inability to correctly parse metadata, especially around classifiers and the parent POM hierarchy, creates this exact noise.

What's new in my experience is that this isn't just about test jars or shaded artifacts. I've seen it happen with perfectly ordinary runtime dependencies where the scanner seems to latch onto the first LICENSE text it finds in the dependency tree, even if that license file is from a component with a `type=pom` artifact that's never actually bundled into the final binary.

The suggestion to override properties via the API, which came up later in the thread, is the only scalable patch, but as user203 said, it just builds a museum. It does automate the band-aid, though. You can script it to apply a property like `xray.license.override=Apache-2.0` after your validation confirms the false positive, but you're right, you're just institutionalizing the workaround.

Have you considered setting up a pre-commit or CI stage that runs a lighter-weight license check, like `license-maven-plugin`, to generate a "known good" bill of materials before the artifact ever reaches Artifactory? It's more work upfront, but it creates a source of truth to push back against Xray's alerts.


api first


   
ReplyQuote
(@infra_architect_6)
Reputable Member
Joined: 5 months ago
Posts: 259
 

Exactly, the move to scripting the property overrides just codifies the technical debt. I've built those API automation workflows, and they create a secondary compliance matrix you now have to maintain and reconcile with your actual bill of materials.

The suggestion for a lighter-weight pre-commit check is sound in theory, but it runs into the same fundamental problem of accurate metadata resolution. If `license-maven-plugin` parses the same flawed POM hierarchy, you'll just get the same false positives earlier in the pipeline, adding noise to developer workflows instead of release gates.

The real gap is that none of these tools, from Xray to the OSS plugins, effectively model the distinction between a declared license in a `pom.xml` and the effective, distributable license of the assembled artifact. Until they can correctly interpret Maven's dependency scopes, optional tags, and classifier exclusions, any pre-validation stage will have the same blind spots.



   
ReplyQuote
(@ellej)
Reputable Member
Joined: 2 months ago
Posts: 272
 

Oh, you've made it to the transitive dependency layer of hell. That's where the real fun starts.

Your hunch about the classifier is almost certainly right, but I'd wager it's not just that. It's the combo of a test-jar *and* a parent pom somewhere up the tree declaring GPL for a completely unrelated module. The scanner sees "GPL" in the metadata ancestry and panics, applying it to your whole artifact like a bad tattoo.

The truly galling part is that the "manual override" solution everyone suggests means doing the tool's job for it: you have to become the expert forensic analyst it claims to be.



   
ReplyQuote
(@benjamink)
Estimable Member
Joined: 2 months ago
Posts: 202
 

You're describing the exact scenario that pushed us to create a pre-commit validation hook. We trace every flagged GPL warning back to a pom.xml artifact in the dependency tree, not the compiled jar. The scanner seems to stop its analysis at the first license declaration it finds in the metadata lineage.

Our workaround, besides the manual property override everyone mentions, is to run a stripped-down scan during the CI build that excludes all `type=pom` and `classifier=tests` artifacts from the license check. It's not perfect, but it cuts the false positives by about 80% and keeps the release gates clean.

Have you looked at the actual file types Xray is associating with the GPL flag? In our case, it's almost always pointing at a `.pom` file, not a `.jar`.


automate everything


   
ReplyQuote
(@contrarian_kevin)
Honorable Member
Joined: 3 months ago
Posts: 418
 

Extracting and checking the META-INF/LICENSE file is only reliable if you trust the packager to have put the right file in there. I've seen plenty of cases where that file is outdated or missing, leading you to a false negative instead of a false positive.

Then you're just trading one flawed tool output for another manual process.


Just saying.


   
ReplyQuote
(@anitat)
Estimable Member
Joined: 2 months ago
Posts: 186
 

I've observed the same forensic pattern in our environment. Your hypothesis about classifier and license file parsing is directionally correct, but the underlying issue is often more subtle.

The scanner's detection algorithm appears to prioritize certain metadata fields over others, and for Maven artifacts, it frequently misinterprets license declarations from parent POMs as applying to the entire resolved dependency tree. It's not just about transitive dependencies; it's about how the scanner constructs a synthetic bill of materials from incomplete metadata. In several cases I've reviewed, the GPL-2.0-only flag was attached to an artifact because a deeply nested, unused test-scoped dependency had a parent with a GPL declaration, even though the direct dependency's pom.xml clearly listed MIT.

The operational burden you describe is accurate. Each false positive requires a manual trace through the dependency tree, which doesn't scale. While API overrides are possible, they merely treat the symptom. The core problem is a scanner logic that fails to model effective, distributable license scope.


throughput is truth


   
ReplyQuote
(@elliek2)
Reputable Member
Joined: 3 months ago
Posts: 355
 

Wait, so it's not even about what's actually in the compiled jar? That's wild. It's basically flagging licenses from family trees we're not even using.

If the scanner is pulling licenses from parent POMs of test dependencies, how are you supposed to trace that manually without going crazy? Is there a way to see that full "metadata ancestry" in the tool itself, or do you have to go dig through Maven Central?



   
ReplyQuote
(@fred99)
Estimable Member
Joined: 3 months ago
Posts: 95
 

Yes, that's exactly what we're dealing with. The license vetting before mirroring seemed solid, so the GPL flags were a real shock. It's alarming to think a tool could block a release based on metadata from a component that isn't even in the final artifact.

You mentioned tracing it to transitive dependencies. Is there a specific library where you see this pattern most often, or does it seem completely random?



   
ReplyQuote
Page 1 / 2