Apply a strict pull request gate to new services from day one, and apply a ratchet to the legacy app: block any new vulnerable dependency, record existing findings as a baseline, and lower the allowed count over time. This keeps old debt from blocking work and stops it from growing.
The problem with one standard
If you set a strict gate on the monolith, every pull request fails because of old findings, and people start ignoring or bypassing the gate. If you set a loose gate everywhere, the new services inherit bad habits. Two policies solve both problems.
Policy for new services
- Fail the pull request on any new vulnerable dependency at or above the severity you set.
- Fail on any component known to be exploited, using CISA's Known Exploited Vulnerabilities catalog as an input, which CISA recommends using for prioritization.
- Require a lockfile, so builds are repeatable.
- Require an owner on the repository.
- Allow exceptions only with an expiry date and an approver.
Policy for the legacy app: the ratchet
- Record the baseline. Save today's findings as accepted debt, with the date.
- Block regressions. A pull request may not add a finding that is not in the baseline.
- Block known exploited issues that are reachable, even if they are in the baseline.
- Lower the ceiling. Each quarter, the allowed baseline shrinks. Fixed findings are removed from it and cannot return.
- Report the trend to the owner of the app and to leadership.
| Rule | New service | Legacy app |
|---|---|---|
| New finding at set severity | Block | Block |
| Existing finding | Not applicable | Allowed until its date |
| Known exploited and reachable | Block | Block |
| Exceptions | Expiry and approver | Expiry and approver |
| Baseline | None | Shrinks quarterly |
Making the ratchet work
The baseline must be specific. Record component, version and advisory, not just a count. Otherwise a new vulnerable library can hide behind a fixed old one, keeping the total flat.
Pick the unit of enforcement as the pull request, not the nightly scan. A gate that runs when a change is proposed gives fast feedback to the author, who knows the code.
Handling pushback
Developers working in legacy code often say the gate is unfair, because they did not create the old findings. The ratchet answers that. They are never blocked by old debt, only by what they add.
Teams also worry about slow scans. Scan only the changed manifests on pull requests and run the full scan on a schedule.
Try it yourself
Click through it at your own pace, or open it full screen.
See how a pull request is checked against policy and what a block looks like to the developer.
Safeguard policies, gates and guardrails support per repository rules like these, so new services and the legacy app can have different settings. Related reading: legacy SAST debt burn down plan by sprint.
Quick check
Should the legacy app have any gate at all?
Yes. Block regressions and reachable known exploited issues, even while the baseline stays.
How fast should the ceiling fall?
Set it by what your teams can fix, and review it every quarter.
Sources
Last reviewed: 19 October 2026.