Block a pull request only for narrow cases you can defend: the change introduces a component on the CISA Known Exploited Vulnerabilities list, or a reachable flaw above your threshold. Warn on everything else and track it. Broad blocking trains developers to bypass the gate.
The problem with blocking everything
A gate that fails on any finding sounds strict. In practice it fails on old, inherited issues unrelated to the change, developers cannot fix them in the pull request, and the team ends up with bypass habits or a disabled gate. A narrow gate that always means something is stronger than a broad one that is ignored.
Judge the change, not the whole repository
The gate should look at what the pull request introduces. A new vulnerable dependency added by this change is the author's responsibility. A pre-existing finding belongs in the backlog with an owner and a deadline.
A tiered policy
| Tier | Condition | Action |
|---|---|---|
| 1 | New dependency is on the KEV list, or reachable and above your severity threshold | Block |
| 2 | New dependency has a fix available and a high exploitation probability | Warn with a comment, require acknowledgment |
| 3 | New finding below those lines | Warn quietly, log it |
| 4 | Existing finding not touched by this change | Do not block; track in backlog |
CISA's catalog is a useful hard line because it lists vulnerabilities exploited in the wild. FIRST's EPSS publishes daily exploitation probabilities for every CVE and can support tier two. Choose thresholds that fit your risk appetite, and write them down.
Make the gate explainable
When it blocks, the message should say what was found, why it matters and what to do. Include the component, the dependency path, the fixed version and a link to the policy. Developers accept a clear reason and resent a mystery.
Provide an escape hatch with accountability
Sometimes a release must ship. Allow an override that requires a named approver, a reason, and an expiry date, and record it. Review overrides weekly. If the same override recurs, change the policy or fix the cause.
Roll out in stages
- Observe. Run the gate in report only mode for two weeks and see what it would have blocked.
- Warn. Show comments on pull requests, no failing status.
- Block narrowly. Turn on tier one only.
- Review. Look at overrides and false blocks, then adjust.
Do not forget the scanner failing
Decide in advance what happens when the scanner is down or slow. Failing open with an alert is common for short outages, but make it an explicit decision.
A worked example
A developer opens a pull request that adds two dependencies and updates one. The gate evaluates the change.
| Item | Result | Policy tier | Action |
|---|---|---|---|
| New package A | On the KEV list, reachable | 1 | Block |
| New package B | High EPSS, fix available, reachable | 2 | Warn, require acknowledgment |
| Updated package C | Medium severity, low EPSS, not reachable | 3 | Quiet warning |
| Existing package D, untouched | Medium severity | 4 | No action, already in backlog |
The pull request fails because of package A. The message explains that package A is listed as exploited in the wild, shows the dependency path and suggests a fixed version. The developer swaps to the fixed version and the check passes. Package B appears as a comment, and the author acknowledges it with a note. Nothing else interrupts the merge.
Step by step: tune a gate in four weeks
- Week 1. Run in observe mode on all repositories. Record what would have been blocked.
- Week 2. Review the would be blocks. Which were correct? Which were noise? Adjust thresholds.
- Week 3. Switch to warn mode with comments on pull requests. Collect developer feedback.
- Week 4. Enable blocking for tier one on a few repositories, then expand.
Metrics to watch
| Metric | Why |
|---|---|
| Block rate per week | Too high means rules are too wide |
| Override rate | Frequent overrides signal poor fit |
| Time from block to fix | Shows whether messages are helpful |
| Share of blocks that were correct on review | Confidence in the rules |
Handling special cases
- Emergency releases. Allow an override with approver, reason and expiry, and review it the next day.
- Monorepos. Scope the gate to changed directories so unrelated findings do not block.
- Dev only dependencies. Decide whether they count. Many teams warn only, since they do not ship.
- Scanner failure. Choose in advance whether to fail open with an alert or block, and document why.
- Newly published advisory for an existing dependency. This belongs in the backlog flow, not a pull request gate, since the change did not introduce it.
Keep it explainable
A rule that developers cannot explain to each other will be resented. Publish a one page description of what blocks, what warns and how to request an override. Update it when thresholds change, and announce the change in the team channel.
Try it yourself
Open a sample pull request and see how a gate evaluates a newly added dependency.
Click through it at your own pace, or open it full screen.
Where Safeguard fits
Safeguard provides policies, gates and guardrails that evaluate dependency findings, with reachability analysis to support narrow blocking rules. A free scan is at gold.safeguard.sh/scan.
Quick check
Should a gate fail on existing findings?
Usually not. Gate on what the change introduces, and manage inherited findings through the backlog.
How do I introduce a gate without annoying developers?
Start in observe mode, then warn, then block a narrow tier, and review overrides regularly.
Should the gate also check licenses?
That is a separate policy decision. Keep license rules distinct from vulnerability rules so each has its own thresholds and owners.
Sources
Last reviewed: 19 October 2026.