Safeguard
Developer Tools•

How do you scan only the changed paths in a monorepo pull request?

Use path filters or a changed file list to scan only what a pull request touches, and keep a scheduled full scan so shared code is not missed.

Safeguard Security Team
4 min read

Filter the scan by changed paths: use your CI system's path filters or a list of changed files, run the scanner only on affected directories, and keep a scheduled full scan for everything else. This keeps pull request checks fast while shared dependencies still get covered.

Why scope the scan

A full scan of a large legacy monorepo can take long enough that developers start to avoid the check. Scoping the pull request scan to what changed brings it back to minutes. The cost is a risk of blind spots, which the steps below handle.

Option one: CI path filters

GitHub Actions workflows can use paths and paths-ignore filters on triggers. The documentation notes that if you define both branch filters and path filters, the workflow runs only when both are satisfied. That detail matters: a workflow limited to a branch and to a path will skip a pull request that matches only one.

A trigger scoped to one service directory looks like this:

on:
  pull_request:
    paths:
      - "services/billing/**"
      - "libs/shared-money/**"

This works well when each service has its own workflow file, but it multiplies files in a big repository.

Option two: compute the changed list

A single workflow can ask git what changed and pass directories to the scanner. Git's diff command can list only file names with its name-only option. Compare the pull request branch against the point where it diverged from the target branch, not against the tip of the target, or you will include other people's recent merges.

  1. Find the merge base of the target branch and the pull request head.
  2. List changed files between that base and the head.
  3. Map files to scan roots, for example the nearest directory holding a manifest.
  4. Run the scan for each root once, even if many files in it changed.

The blind spots

GapHow to close it
A shared library changes, but only its own directory is scannedMap library changes to dependent services
A lockfile at the repository root changesTreat as touching everything it covers
A new vulnerability is published for an unchanged packageScheduled full scan, daily or weekly
Path filter misses a renamed directoryReview filters whenever directories move

The last row is easy to overlook. A newly published advisory affects code that has not changed, so a pull request scan can never catch it. Pair scoped scans with a scheduled full run.

Set a rule for the root files

Define a short list of files that always trigger a full scan: root lockfiles, shared build configuration and the scanner policy itself. Document the list in the repository so people know why a small edit sometimes runs a long check.

Where Safeguard fits

Safeguard policies and gates can block a pull request on what the change introduces, and continuous monitoring covers newly published advisories on code that has not changed. Try the walkthrough below.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch how a pull request gate reports only what the change introduces.

Quick check

Will scoped scans miss transitive dependencies?

Not if you scan the whole service directory that holds the manifest. The risk is mapping files to the wrong root, so test the mapping.

How often should the full scan run?

At least weekly, and daily if you can afford it, because advisories appear without any code change.

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.