Safeguard
Developer Tools•

How do you shard security scans of a large monorepo?

Split a monorepo scan by component, map changed paths to owners, scan in parallel, and merge results so large repositories get fast, attributable findings.

Safeguard Security Team
4 min read

Split the monorepo scan into units such as services or packages, work out which units a change affects, scan those in parallel on separate workers, and merge the results under one check. Attribute each finding to an owning team by path. This keeps time to result flat as the repository grows.

The problem

One scan job for a whole monorepo has three problems. It is slow, because it processes everything. It is fragile, because one failure discards all results. And its output is hard to act on, because findings from forty teams land in one list with no owner.

Sharding addresses all three by treating each component as its own scan unit.

Choose the shard unit

Shard unitGood forWatch out for
Service or application directoryMicroservice monoreposShared libraries used by many services
Package or workspaceLanguage workspaces with a manifest per packageHoisted dependencies in a root lockfile
Build targetRepositories with a build graphNeeds build tool integration
Owner pathOwnership files map teams to directoriesPaths with no owner

Steps

  1. Define the components in a manifest kept in the repository, each with a path pattern, a scan type list and an owner.
  2. For a pull request, compute changed files and map them to components.
  3. Add components that depend on the changed ones, using the dependency graph if you have one. A change to a shared library should trigger scans of its consumers.
  4. Enqueue one job per affected component, each with its own dedupe key.
  5. Run the jobs in parallel with a concurrency cap so one pull request cannot occupy the fleet.
  6. Merge results into one check run on the pull request, grouped by component, with a pass only if all required shards pass.
  7. On merge to the main branch, run the same sharded scan so the baseline stays current.

Dependencies are the tricky part

Many monorepos use one root lockfile for the whole repository. A change to it touches every component. Treat a lockfile change as a change to all components that resolve from it, but use the inventory diff, not the file diff, to decide whether anything really changed: if the new resolved set for a component is identical, skip its match step.

Shared code needs the same care. If an internal library has a vulnerable dependency, the finding belongs to the library owner, but the consumers are exposed. Report the finding once at its source and link affected consumers.

Keep a full scan

Sharding by changed paths is a form of incremental scanning, so keep a scheduled full scan to catch anything the mapping missed. Compare the full scan's findings with the sum of shard results, and investigate differences.

Ownership and routing

Use the owner field to route findings. A finding with no owner goes to a default queue that someone reviews weekly, and the count of unowned paths is a metric worth tracking.

Try it yourself

Click through it at your own pace, or open it full screen. Watch how reachability narrows a long list to the findings that matter, which helps when a monorepo produces many.

Safeguard's reachability analysis helps separate dependency findings that the code actually uses. You can try the free scan at https://gold.safeguard.sh/scan.

Quick check

Do I need a dependency graph to shard?

Not to start. Path based sharding works, but add the graph when shared libraries cause missed scans of consumers.

Should every shard be required to pass?

Usually yes for affected shards. Unaffected shards are skipped, not failed.

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.