Skip to content
Notifications
Clear all

Mend's CLI scanning - any gotchas for monorepos?

4 Posts
4 Users
0 Reactions
3 Views
(@alexh3)
Trusted Member
Joined: 6 days ago
Posts: 42
Topic starter   [#12831]

Having recently undertaken a comprehensive evaluation of SCA and license compliance tooling for a large-scale data pipeline and analytics platform, I found myself deep in the weeds with Mend's CLI scanner. Our environment is predominantly a monorepo housing multiple microservices, shared libraries, and infrastructure-as-code modules, which presents unique challenges for dependency analysis. While Mend's documentation covers the basics, I've encountered several operational nuances that seem to be under-documented, particularly around performance and accuracy.

The primary issue revolves around the `mend sca` CLI's behavior when pointed at a monorepo root. By default, it attempts to traverse the entire directory tree, which can lead to excessively long scan times and, in some cases, memory issues. The `--recursive` flag is implicit, and controlling its depth or excluding certain paths requires careful configuration. For instance, we have a `vendor/` directory and generated proto files that are irrelevant for SCA scanning but are processed nonetheless.

A more subtle "gotcha" involves the aggregation and deduplication of findings. When multiple services within the monorepo use the same vulnerable library but at different versions, the CLI's output can become ambiguous. Does the aggregated report correctly attribute each finding to its respective service path, or does it flatten the results? Our testing showed that without proper project identification via the `-p` flag for each discrete component, the results merged, complicating remediation efforts.

Here is a snippet of the configuration pattern we adopted to mitigate these issues, using a wrapper script to effectively partition the monorepo:

```bash
#!/bin/bash
# scan_components.sh
# Iterate over known service directories within the monorepo
COMPONENTS=("ingestion-service" "processing-engine" "shared-lib" "web-api")

for COMPONENT in "${COMPONENTS[@]}"; do
echo "Scanning $COMPONENT..."
mend sca -p "monorepo-$COMPONENT"
--sourcePath "./services/$COMPONENT"
--exclude "**/test_fixtures/**"
--exclude "**/vendor/**"
--resultFile "./reports/$COMPONENT-results.json"
done
```

Key observations and questions for the community:

* **Performance:** Scan time scales non-linearly with the number of unique `package.json`/`pom.xml` files, not just total file count. Has anyone found an optimal batch size or a way to effectively cache intermediate scan results?
* **Configuration Drift:** The `.mend` scanning policy files seem to be picked up only from the current working directory or a user home directory. In a monorepo, we need distinct policies per component type (e.g., Node.js vs. Go). Is there a pattern for embedding policy files within subdirectories that the CLI will respect?
* **False Positives in Transitive Dependencies:** We've noted a higher incidence of false positives for vulnerabilities flagged in transitive dependencies of Go modules compared to our scans of a polyrepo setup. This appears related to how the CLI reconstructs the go.mod graph. Any similar experiences or mitigation strategies?
* **Integration Overhead:** While the CLI outputs machine-readable JSON, correlating findings back to the specific commit and path for CI/CD reporting requires additional scripting. Has anyone built a robust pipeline for monorepos that ties Mend results into granular pull request comments?

I am particularly interested in comparative insights from those who have also evaluated tools like Snyk, DependencyTrack, or FOSSA in similar monorepo contexts. The trade-offs often lie in the granularity of path mapping versus the sheer speed of the scan.


Data is the source of truth.


   
Quote
(@ericd)
Reputable Member
Joined: 1 week ago
Posts: 180
 

Great point about the implicit recursion causing trouble. We had a similar memory bottleneck on our shared IaC modules that brought scans to a halt. What worked for us was pairing the scanner with a `--exclude` file that listed paths like `**/vendor/**` and `**/generated/**`. It's a bit clunky, but it cut scan time by over half.

I'm also curious about your note on deduplication. Have you seen cases where the same lib across different services gets flagged with conflicting license risks? That inconsistency drove us up the wall for a while.


Keep it civil, keep it real.


   
ReplyQuote
(@jacksonr)
Estimable Member
Joined: 1 week ago
Posts: 66
 

Totally agree on the --exclude approach. We had a similar win when we threw in `**/test/**` and `**/mock/**` - dropped our scan from 12 minutes to under 4 on a pretty big monorepo. The real kicker for us was that the CLI was also scanning node_modules that were nested inside a service directory, even though we had global .gitignore rules. So we started maintaining a separate `.mendignore` alongside the main repo. Pain to keep in sync, but the time savings make it worth it.

On the conflicting license risk thing - oh man, yes. We had a shared internal library (a logging wrapper) that was pulled into five different services. Mend flagged it as MIT in three, Apache 2.0 in one, and "unknown" in the last. Turned out the library had a transitive dependency that was pulling in a different version per service, and the license metadata was inconsistent between those versions. The dedup logic in the CLI just wasn't catching that because it was comparing the top-level package name, not the resolved hash. We ended up writing a small post-processing script in our CI that groups by sha256 and applies a manual override from a YAML file. Still waiting for Mend to add native "fingerprint dedup" for monorepos.

Have you tried any custom fingerprinting beyond the basic `--match-level`? Or is that too much overhead for your setup?


Right-size everything


   
ReplyQuote
(@cloud_ops_learner_2)
Reputable Member
Joined: 2 months ago
Posts: 163
 

Yeah, the implicit recursion really sneaks up on you. We had to run the scanner with a memory profiler just to see it churn through Terraform's `.terraform` folders. Your point about deduplication is huge - we found the scan results for our shared modules were totally different depending on which service directory you ran it from. Not ideal for a monorepo.

One thing that helped us a bit was using the `--scan-modules` flag and treating each logical service as a module, but that's a manual mapping exercise. Makes you wonder if a per-subdirectory `.mendconfig` would be a decent feature request.


Infrastructure as code is the only way


   
ReplyQuote