Which security gates belong in the delivery pipeline?
Adding every available scanner to continuous integration produces a slow pipeline and a culture of overrides. Choose gates by what they can decide reliably, and move the rest out of the blocking path.
What a blocking gate is for
A blocking gate has one job: to stop a change that should not reach production, at the moment when stopping it is cheapest. That is a narrow job, and most of what teams put in the blocking path does not do it.
The failure mode is familiar. Security tooling is adopted enthusiastically, every check is set to fail the build, and within a quarter the pipeline takes forty minutes and there is a well-known process for adding the override label. The gates still exist on the diagram. They have stopped deciding anything.
What went wrong is not discipline. It is that checks with different reliability characteristics were given the same authority. A test that deterministically proves this change breaks tenant isolation and a scanner that reports a medium-severity advisory in a transitive dependency are not the same kind of statement, and treating them identically devalues the first.
Three tests a blocking check must pass
Before a check blocks a merge or a deploy, it should pass all three:
- Deterministic. The same input produces the same verdict. A check that fails intermittently trains engineers to re-run rather than read.
- Fast enough to sit in the loop. If the feedback arrives after the engineer has moved on, the gate is not preventing a defect; it is scheduling an interruption.
- About this change. The finding must be attributable to the diff under review. A gate that fails because of pre-existing debt punishes the wrong person and is negotiated away within weeks.
A check that fails any of these is not worthless—it may be the most valuable check you run—but it belongs somewhere other than the blocking path. NCSC’s secure development guidance makes the same argument from the developer’s side: security activity has to fit the way software is actually built, or it gets routed around.
Where each common check belongs
| Check | Deterministic | Fast | This change | Placement |
|---|---|---|---|---|
| Security unit and integration tests | Yes | Yes | Yes | Block |
| Secret detection in the diff | Mostly | Yes | Yes | Block |
| Infrastructure policy on the proposed plan | Yes | Yes | Yes | Block |
| Build provenance and signature verification | Yes | Yes | Yes | Block |
| Static analysis, new findings only | Mostly | Usually | Yes | Block on new, report on existing |
| Dependency vulnerabilities | Yes | Yes | Rarely | Block on a narrow subset |
| Container base image age and known issues | Yes | Yes | No | Scheduled, with a service-level target |
| Dynamic scanning of a deployed environment | No | No | No | Post-deploy, tracked |
| Manual penetration testing | No | No | No | Milestone, not pipeline |
| Fuzzing | No | No | No | Continuous, out of band |
The “new findings only” pattern for static analysis is worth the setup cost. Baselining existing findings and blocking only on what the change introduced converts a tool that developers resent into one they use, and it makes the trend line the thing you manage.
The dependency gate deserves special care
Dependency scanning produces more blocking noise than any other check, because it reports on the transitive graph rather than on your code. Most teams eventually respond by raising the severity threshold, which is a blunt instrument: severity describes the vulnerability, not your exposure to it.
A better gate combines three conditions and blocks only when all hold:
- the vulnerability is reachable from your code, established by call-graph analysis rather than presence in the lockfile;
- it is actionable, meaning a fixed version exists or a configuration mitigates it;
- it is material, which for most products means it appears in CISA’s Known Exploited Vulnerabilities catalogue or scores highly once environmental metrics are applied.
That last point is where CVSS version 4.0 helps, because it separates base severity from threat and environmental modifiers. A base score is a property of the flaw; the number that should influence your pipeline is the one adjusted for your deployment.
Everything else goes to a tracked queue with an owner and a target age. This is not laxity—it is the difference between a gate that stops the three things that matter and a gate that stops everything and is therefore disabled.
Build integrity is a better gate than most scanners
The highest-value blocking checks in a modern pipeline are often not about vulnerabilities at all. They are about whether the artefact being deployed is the artefact the review approved.
Verifying that a deployable was produced by the expected build system from the expected source revision, that its provenance attestation validates, and that its signature chains to a key your platform trusts, are all deterministic, fast and specific. The SLSA framework describes escalating levels of this guarantee, and the early levels are achievable without changing how teams write code.
This class of gate also resists the override problem. An engineer under deadline pressure can plausibly argue that a medium-severity advisory should not block a release. Nobody argues for deploying an artefact whose provenance does not validate.
Give overrides a shape
Some releases genuinely need to proceed with a known finding. A gate set that pretends otherwise gets bypassed outside the system, which is worse than bypassing it inside.
Design the override rather than tolerating it. A workable shape has four parts: a named authoriser who is accountable for the consequence rather than for the deadline, a stated reason recorded against the specific finding, an automatic expiry after which the gate re-applies, and a compensating action for the interval—a feature flag, a narrowed permission, a temporary rate limit, or heightened monitoring with a named recipient.
Expiry is the part teams omit, and it is the part that matters. A permanent exception becomes invisible within a quarter; an exception that re-blocks the pipeline in fourteen days either gets fixed or gets renewed by someone who has to justify it again. Renewals are also the cleanest signal you have about which gates are mis-specified: a finding class renewed repeatedly across teams is usually a gate that is asking the wrong question.
Keep the override record in the release evidence rather than in a chat thread. When a security decision is questioned months later, the useful artefact is not that the pipeline was green—it is that someone specific accepted a specific condition for a stated period.
Put slow checks on their own clock
Removing a check from the blocking path is not the same as deprioritising it. Dynamic scanning, fuzzing and manual testing find defect classes that no fast deterministic check will ever reach, and they need a schedule of their own rather than a place in the merge queue.
Two arrangements work. The first runs the slow checks continuously against a deployed environment that tracks the main branch, so findings arrive within a day of the change that caused them without holding anyone’s merge. The second attaches them to milestones—a significant architectural change, a new external interface, a release that alters the authorisation model—so the depth of testing matches the size of the change rather than its calendar position.
Either way, give the results the same treatment as the tracked dependency queue: an owner, a target age, and visibility when the age is exceeded. The distinction that matters is between blocking and not blocking, not between important and unimportant.
Measure the gates, not the findings
Finding counts are a poor management signal: they go up when you add tools and down when you tune them, with no necessary relationship to risk. Measure the gates instead.
Four numbers are usually enough: the override rate per gate, the median time from finding to fix for the tracked queue, the age of the oldest open item in that queue, and the proportion of production incidents whose root cause a gate should have caught. The last one is the only external validation the gate set has.
The SSDF frames this as reviewing and updating the practices themselves, not only their output. A gate with a high override rate is telling you something about its design. A queue whose oldest item is eleven months old is telling you the queue is a disposal mechanism rather than a work list. Both are more useful to know than how many findings a scanner produced this week.