Every security gate is a decision about where to put a delay. Put it in the wrong place and you get the two failure modes everyone recognises: a check that blocks the merge queue for the whole team, or a check so permissive that nothing has ever failed it.
The position matters more than the tool. This post is about where in the pipeline each class of check belongs, why, and what to do about the gate that is currently annoying your engineers. Written for platform and DevSecOps engineers at teams shipping many times a day.
The four positions, and what each one can afford
A change passes four places where a check can run. They have completely different time budgets and completely different blast radii.
Pre-commit, on the developer's machine. Budget: about two seconds. Anything slower gets bypassed with --no-verify within a week, and once a team learns that flag you have lost the position permanently.
What belongs here: secret detection on the staged diff. That is close to the whole list. It is fast, it has an obvious rationale, and catching a credential here saves a rotation.
Pull request, on the diff. Budget: a few minutes, running in parallel with review. This is the best position in the pipeline and the most underused.
What belongs here: SAST on changed files, dependency checks on changed manifests, IaC checks on changed templates. Scoping to the diff is the whole trick. It keeps the run fast and it means a developer is never blocked by a finding they did not introduce, which is the single biggest driver of gate resentment.
Merge queue, on the merged result. Budget: minutes, and every minute is multiplied by the depth of the queue. A five-minute check on a queue of eight changes adds forty minutes of latency for the last person.
What belongs here: almost nothing security-specific. The queue exists to prove the combined result builds and passes tests. A security check here is paying the highest latency price in the pipeline for information you could have had at the pull request.
The exception is a check that is only meaningful on the merged result, which in practice means dependency resolution conflicts between two changes landing together.
Post-merge and pre-release. Budget: generous. Nobody is watching a progress bar.
What belongs here: full-repository scans, container image scanning, DAST against a deployed environment, license and SBOM generation, anything needing a built artifact or a running application.
Gate on the diff, report on the repository
The distinction that resolves most arguments: a check that blocks must only consider what this change introduced. A check that reports may consider everything.
A full-repository scan at the pull request fails on the 300 findings that were already there, so the developer whose change happens to be next in line is the one asked to fix them. They will not. They will ask for an exemption, get one, and now the gate is decorative.
Diff-scoped blocking keeps the contract fair: you are responsible for what you added. Repository-wide findings go to a backlog with an owner and a schedule, which is a planning problem rather than a merge problem.
Turning on a gate without a revolt
The sequence that works, and skipping a step is how gates get disabled by management three weeks later:
- Run it in warn mode for two weeks. Collect what it would have blocked. This is the only reliable way to discover your false positive rate on your code, which will not match the vendor's number.
- Read every one of those. If the precision is poor, tune before enforcing. A gate with a 30 percent false positive rate does not survive contact with a deadline.
- Enforce for new findings only. Almost every tool supports a baseline. Take one.
- Announce the threshold before it fires, with the rationale, and with a named owner for exceptions.
- Give it a documented bypass. A gate with no legitimate override gets an illegitimate one, usually a shared admin account. Make the bypass require a reason, log it, and review the log monthly. The review is the control, not the block.
What to block on, specifically
Be narrow. The list of things worth stopping a merge for is shorter than most policies assume:
- A verified live secret in the diff.
- A dependency flagged as malware.
- A known-exploited vulnerability, on the KEV catalogue, introduced by this change.
- A new critical severity finding in code the change touches, where the path is reachable.
Everything else warns. The point is that a block should be rare enough that when it happens, people believe it.
The measurements that tell you it is working
Not findings closed. Findings closed goes up when the tool gets noisier.
- Time from pull request open to all checks green. If this exceeds about ten minutes, developers context switch, and the review cycle stretches for reasons that have nothing to do with security.
- Block rate. If under one percent of pull requests are blocked, the gate is doing nothing. If over five percent, it is miscalibrated and you are about to lose it.
- Bypass rate and reasons. The most informative number you have. A rising bypass rate is the gate failing, several weeks before anyone says so out loud.
- Mean time to fix, by position. Findings caught at the pull request are fixed in hours. The same finding caught post-release takes weeks, because the author has moved on and the context is gone.
The concession
Shifting everything left has a real cost that the phrase "shift left" obscures: you are moving work onto the people with the least context about risk and the most pressure to ship. A developer who sees six security checks on every pull request stops reading them, and a check nobody reads is worse than no check, because it produces a record suggesting the code was reviewed.
Which argues for fewer gates, not more. Two checks a developer trusts beat six they have learned to click past.
The implication
The pipeline already tells you where each check belongs, if you look at what it can afford. Two seconds at pre-commit, a few minutes on the diff, generous time after merge, and near-zero appetite in the merge queue.
Most badly-behaved gates are correctly configured checks in the wrong position. Before tuning a rule set, move the check and see whether the complaint disappears.