
A Scanner That Reports Everything Has Transferred the Work, Not Done It
Scanner defaults are tuned for the vendor's exposure, not your attention. Enabling every rule buys you a lookup service and hands you the analysis, at estate scale, with no owner.
A scanner in its shipped configuration is not a security control. It is a work generator, and the volume of work it generates was set by a vendor optimising for their exposure rather than your attention.
That is not a complaint about tooling quality. It follows from the incentives. For a vendor, a missed vulnerability is a reputational event. A false positive is an afternoon of somebody else's time. Given that asymmetry, every default in every scanner leans towards reporting. The product ships tuned for recall, you inherit the precision problem, and the handover is easy to miss because the output arrives formatted like an answer.
The asymmetry is structural
Consider composition analysis. An SCA tool resolves your dependency graph, fingerprints each package version, and matches those fingerprints against an advisory feed. That is a set intersection, and it is correct in the narrow sense: the package is present, and the advisory does cover that version range. Whether the vulnerable function is ever called, whether the package is a build-time dependency that never ships, whether any untrusted input can reach the affected path: none of that is in the feed, and most of it is not in the artefact either.
Static analysis has the same shape approached from the other end. A taint engine traces from sources to sinks. Widen the source list and you catch more real injection, and also every handler that passes a validated integer into a query builder. Narrow it and you miss things that matter. No setting gives you both, so the default is wide. The differences between these tool classes, and what each one is actually capable of concluding, are worth reading before you buy a second one to compensate for the first, which is why we wrote up how SAST, DAST, IAST and SCA differ in what they can prove.
Secret detection is the clearest case, because the heuristic is visible. High-entropy string matching cannot distinguish a live API key from a base64 test fixture or a content hash in a minified bundle. Vendors add format-specific rules for known key shapes, which are precise, and keep the entropy rule enabled, which is not. Where you run that detection changes who absorbs the noise, and the choice between pre-commit hooks and CI for secret scanning is mostly a decision about which of those two populations you are willing to interrupt.
What the tool decided, and what it handed you
Every finding carries a set of questions. The scanner answers a couple of them and passes the rest through silently.
| Question about a finding | Can the tool answer it? | What an answer actually requires |
|---|---|---|
| Is this package version in the tree? | Yes | A resolved lockfile |
| Does a published advisory apply to it? | Yes | A current feed |
| Is the vulnerable function reachable in code? | Partly, with call-graph analysis | Build output and known entry points |
| Does the package ship, or die in a builder stage? | Sometimes | Multi-stage awareness and image provenance |
| Can untrusted input reach that path? | No | Your ingress map and architecture |
| Does an existing control remove the precondition? | No | Runtime and network configuration |
| Who is going to fix it? | No | A service catalogue with owning teams |
| Should this block the merge? | No | An agreed, written policy |
The first two rows are the product you bought. The remaining six are the work. An adoption programme that installs the tool, points it at every repository and enables every rule has purchased two rows of lookup and manufactured six rows of analysis, multiplied by the size of the estate. Until someone does that analysis, the deployment returns less than nothing, because it consumes review capacity and produces no decisions.
This is also why finding volume tends to rise during a remediation push, and why the total is a poor thing to report upwards. We have made that measurement argument separately in why finding counts are the wrong metric to manage against.
Suppression is the deliverable, not the embarrassment
Teams treat the ignore list as an admission of defeat, so it gets filled in quietly and never reviewed. It is the opposite. The suppression file is the only written record of what your organisation knows about its own architecture. Everything the scanner could not determine, a person determined, and this is where that determination either lives or is lost.
Which means it has to be maintained like code rather than like an exception log:
- Every entry states a falsifiable claim, not a verdict. "False positive" is worthless. "Advisory affects the XML entity resolver; we call only the date formatter; verified against 2.4.1" can be rechecked the moment the version changes.
- Every entry has an expiry. An unexpiring suppression is a permanent architectural assumption maintained by nobody.
- Path-level exclusions are the dangerous kind. Excluding a vendored directory or an entire test tree removes real findings along with the noise, and nothing in the output tells you it happened.
- Entries are reviewed when the dependency version moves, because that is the moment the claim underneath them can quietly stop being true.
Tuning so the output is a decision
The goal is not fewer findings. It is that every finding reaching a human implies an action. Six steps get most of the way there.
- Separate the gate from the report. Decide which classes of finding block a merge and which accumulate for scheduled work. Conflating the two is how build failures become something people learn to rerun. Which findings should actually fail a build sets out where that line usually belongs.
- Scan artefacts, not repositories. What ships is an image or a bundle. Scanning source trees reports on code that never reaches production.
- Disable rules you will never act on. Suppressing the same rule for the four hundredth time is a configuration failure being paid for by hand.
- Split findings by layer before anyone looks at them. Operating system packages inherited from a base image are a different queue with a different owner from application dependencies, and merging the two makes both unworkable.
- Acceptance-test the scanner itself. Seed a known issue, confirm it is caught, and record how much else the tool reported on the same run. That ratio is the number to take back to the vendor.
- Report unresolved decisions rather than totals. A count of findings nobody has classified is a management signal. A count of findings is inventory.
None of this is a one-off configuration exercise. The tuning, the suppression review and the routing rules are continuing engineering work with an owner, which is the part most tool rollouts leave unfunded, and it is the substance of our DevSecOps implementation work.
Where to start
Take one repository with a large finding count and classify every result by hand, once. Record which questions you had to answer that the tool could not. That list is your configuration backlog, and it will be short and repetitive, which is the useful part: the same six or seven judgements account for most of the volume across the whole estate. Encode those, then turn the tool on everywhere. Doing it in the other order is how organisations end up with forty thousand findings and no decisions.
Fastnexa Security Practice
Cybersecurity Team at Fastnexa. We write from real client work, and we are happy to talk through yours.
Ready to ship this?
Bring this problem to a free 30-minute call with the team that wrote the post.
Book a demoMore from the blog
View all
Nobody Owns a Security Finding, Which Is Why the Backlog Never Moves
Findings are keyed to artefacts. Ownership is a property of deployments. Nothing maintains the map between them, so the queue fills with work that has no addressee and no due date anyone feels.

Install Scripts Are Off by Default Now, and Your Threat Model Has Not Noticed
Package managers closed the postinstall hole. Most supply chain defences still guard it, while the code that actually runs in your build gets imported by your own toolchain with no gate at all.

Your Alert Volume Is a Budget Decision Dressed as a Security Decision
The number of alerts a team can survive is fixed by the analyst hours you bought. Every rule you enable spends that budget, and the decision to enable it is almost never costed.
Related services
Want help putting this into practice? Here is how we deliver it.