Safeguard
Developer Tools•

Monorepo security scans: changed paths or a full scan?

In a monorepo, scan changed paths on pull requests for speed and run a full scan on a schedule. Watch shared libraries, which change many services at once.

Safeguard Security Team
3 min read

In a monorepo, scan only the changed paths on pull requests to keep feedback fast, and run a full scan on a schedule to catch everything else. Treat shared libraries as special: a change there affects many services, so it should trigger scans for every dependent.

Why monorepos need a plan

A monorepo can hold dozens of services and libraries. A full scan on every pull request is slow and floods authors with findings from code they never touched. A scan limited to changed files is fast but can miss the effect of a change on code elsewhere in the repository.

The answer is to use both and to know where the seams are.

The two modes

ModeRuns onStrengthWeakness
Changed pathsEvery pull requestFast, relevant to the authorMisses indirect effects
Full scanSchedule, releaseComplete viewSlow, noisy for authors

Where changed-path scanning goes wrong

  1. Shared libraries. A change under a shared package alters every service that imports it. Map dependents and scan them too, or scan the whole repository when shared paths change.
  2. Lockfiles and manifests at the root. A root-level change can affect everything. Treat root files as triggers for a full dependency scan.
  3. Generated code. If generated files are not committed, a path filter will not see them.
  4. Build configuration. Changes to build scripts or pipeline files can alter what ships without touching service code.

Path filters and required checks

Be careful when combining path filters with required status checks. If a filter prevents the scan job from running on some pull requests, a required check might never report, or the platform may treat it as skipped. GitHub documents that skipped counts as a pass for required checks. The safer pattern is to always run the job and let it decide internally which paths to scan, exiting successfully with a clear message when nothing relevant changed.

Ownership by path

Use a code owners mechanism or an equivalent mapping so findings reach the right team. In a monorepo, one repository does not mean one team, and a single backlog without owners will not shrink.

Steps

  1. Define path groups: each service, shared libraries, root configuration.
  2. Map each group to an owning team.
  3. For pull requests, scan changed groups plus dependents of any changed shared library.
  4. Treat root file changes as a trigger for a full dependency scan.
  5. Run a full scan nightly or weekly and route findings by owner.
  6. Review once a quarter whether the mapping still matches the repository.

Measure the tradeoff

Track how often the full scan finds something the changed-path scan missed. If the number is high, widen the triggers. If it is near zero, your scoping is sound.

Where Safeguard fits

Safeguard's dependency scanning and policy gates can be run per path or for the whole repository from the CLI or CI, and its SBOM output helps map which services use which package. Try a scan at https://gold.safeguard.sh/scan.

Quick check

Should every pull request scan the whole monorepo?

Usually not. It is slow and noisy. Scan changed paths and dependents, and run a full scan on a schedule.

How do I avoid a required check that never reports?

Run the job on every pull request and filter inside it, instead of using workflow level path filters.

Sources

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.