Your Scanner Found 4,000 Findings. It Made Zero Decisions.
On this page
Three weeks ago we published the five security findings that show up in every real cluster review, and we were rude about vulnerability scanners on the way past. The exact phrasing was that CVE scanners producing four-digit finding counts are “layer-seven answers bought by teams that have not done the layer-one work.” Then we went away and built one, and it is now live in Ankra as the Security Center.
That needs an explanation, and “we changed our minds” is not it. The original point still stands. A tool that greets you with four thousand findings has not reduced your risk by a single CVE, and buying one before you have dealt with unmaintained ingress controllers and static kubeconfigs is displacement activity with a dashboard attached. What we got wrong was treating that as an argument against scanning. It was really an argument about everything that has to happen after the scan.
Scanning is not the hard part. Trivy will tell you every CVE in every image you run, for free, by lunchtime. The hard part is that a scanner produces observations while running a cluster requires decisions, and almost nothing in the usual toolchain turns one into the other or remembers that you already did.
The triage you do twice
Watch what actually happens to a scanner report. Someone exports it, sorts by severity, and starts working down the list. Two hours in they hit a critical in a base image they do not control, with no fixed version published. There is nothing to do about it today, so they make a decision: we accept this one, we will look again when Debian ships a patch. That decision gets recorded in a Slack thread, or a Jira ticket, or nowhere.
The scanner runs again that night and the finding comes back, because the finding was always true. It is still critical, still unfixable, still at the top of the list, and the next person to open the report starts the same two hours over. Multiply by every cluster running that image, because the report is per cluster, and the same base image is under half your services.
This is the actual failure. Not that the scanner found four thousand things, but that it will find them again tomorrow with no memory of the judgement you already applied, and it has no way to tell the difference between four thousand problems and forty problems that appear in a hundred places each.
Deduplication fixes some of that arithmetic. Ankra collapses occurrences into logical findings, so a CVE in a shared base image is one row that says how many workloads and how many clusters it touches, rather than a hundred rows that say the same thing. But dedup only makes the list shorter. It does not make it a set of decisions.
What a decision has to carry to survive
A decision that survives the next scan needs three things the average triage spreadsheet does not have.
It needs a reason, written at the moment you had the context, because in four months nobody will remember why this one was fine. It needs a review deadline, because “we accept this” without a date is not an acceptance, it is forgetting with extra steps. And it needs a scope that outlives the thing that triggered it, because the pod that surfaced the CVE will be replaced on the next deploy and the risk will not.
So in Ankra a finding does not get ticked off, it gets a disposition. You can acknowledge it, which means seen, understood, still ours to fix. Or you can accept the risk, which requires a written reason and a review date that cannot be more than a year out, and which can optionally expire itself the moment a fixed version becomes available. There is no permanent dismissal, and policies are revoked rather than deleted, so the history of what you decided and when stays intact for the person who inherits the cluster.
The distinction between those two is deliberate and worth stating plainly, because most tools blur it. Acknowledged findings are still counted as actionable in Ankra. Acknowledging is not a way to make a number go down, it is a way to say you have read it. Only accepted risk leaves the actionable count, and only with a reason and an expiry attached. When we say a fleet has eighteen actionable findings, that number includes everything anyone has merely looked at.
One decision, the whole fleet
The part that makes this more than bookkeeping is where the decision attaches.
Ankra deploys your add-ons, so it knows which add-on shipped which image, which means it can attribute a CVE back to the thing that introduced it rather than to the pod that happens to be running it. Accept a risk on a finding attributed to an add-on, and the acceptance applies across your whole organisation for that add-on, on every cluster you have now and every cluster you create next month. You decide once. The fleet inherits it.
That attribution is also why the acceptance controls are sometimes greyed out, which surprises people the first time. Ankra only lets you write an org-wide policy off an occurrence it can attribute to a specific add-on with high confidence. If the finding is floating in a cluster with no clear owner, the button stays disabled and the UI tells you why, because an organisation-wide risk acceptance keyed to a guess is worse than no policy at all.
Before anything is written, the platform previews it: how many occurrences, findings, clusters, and add-ons the policy will touch, which ones it will deliberately exclude, whether it overlaps a policy you already have, and exactly what your actionable count will be afterwards. You see the blast radius of the decision before you commit it, which is the same drafts-and-approvals discipline we apply to every other write in the platform.
The axis a CVE count cannot see
Here is the finding that our original list should have included and did not.
Every CVE score in your report describes how bad a vulnerability is in the abstract. None of them describe what an attacker reaches from the compromised pod, and that second number is usually the one that decides whether an incident is an inconvenience or a very long weekend. A medium-severity bug in a workload that can open a connection to anything in the cluster is a worse day than a critical in a pod that can talk to one database and nothing else.
Almost nobody measures this, because it is not in the scanner output. It is in your NetworkPolicies, or in the fact that you do not have any.
So the Security Center scores it directly. The Network Exposure tab rates each cluster on NetworkPolicy over-privilege, separately for ingress and egress, and tells you how many workloads are not covered by a policy at all and how many of the rules that do exist are so broad they admit effectively everything. Each finding names the namespace, the workload, and the rule, and says what to tighten. It is the least fashionable tab and probably the most useful one, because unlike a CVE count it maps onto a question you can actually answer: if this pod is owned, what does the attacker get next?
Compliance as evidence, not a score
The other thing a scanner alone cannot give you is the artefact somebody eventually asks for.
Ankra reads the CIS Kubernetes and NSA/CISA benchmark results Trivy publishes, plus Trivy’s configuration audit as a second axis, and renders them as pass rates per cluster per framework rather than a single meaningless fleet percentage. New frameworks appear on their own as Trivy publishes them, because the list is discovered rather than hardcoded.
More usefully, the whole thing exports as a compliance evidence report in CSV or JSON over a date window, and it is not just a findings dump. It carries posture snapshots per cluster over time, the disposition policies with their reasons and review dates and who created them, a summary of the audit log, the benchmark results, and an attestation section recording whether MFA is required, whether SOPS is initialised, and whether the security baseline is installed on each cluster. That is the difference between telling an auditor you manage vulnerabilities and showing them the decisions, the dates, and the names.
Because that report is evidence, it is gated harder than the rest of the product. Reading the Security Center needs security.read. Acknowledging needs security.triage. Writing accepted-risk policies needs security.manage. Exporting the evidence report needs security.read and audit.read together, enforced on the backend rather than by hiding a button.
What the AI is actually for
We did not put AI in here to summarise a CVE description, which you can already read.
The useful version is ordering. Four thousand findings do not have a natural sequence, and the sort-by-severity-desc default is usually wrong, because a fixable high in something you deployed yesterday beats an unfixable critical in a base image you are stuck with. So the fleet overview has one button that hands the top remediation candidates to the AI with the fleet context attached and asks it to produce a plan: what to fix first, on which clusters, and how to verify each fix. Individual findings have an Ask Ankra AI action that opens the chat already grounded in that finding and the cluster it was seen on, and failing compliance checks have a Fix with AI action that can propose and apply the change through the normal approval path.
One detail we are quietly pleased with. The product telemetry around all of this runs through an allowlist that drops anything not explicitly permitted, so CVE identifiers, finding titles, prompts, and workload names never reach our analytics. We can tell how often the feature is used. We cannot tell what is wrong with your cluster.
Turning it on
The Security Center needs a scanner in the cluster, and rather than make you assemble one there is a single action that installs a curated baseline: Trivy Operator for image CVEs, benchmarks and config audit, plus Kyverno with the pod-security baseline policy set. Every chart version is pinned, and Kyverno goes in with validationFailureAction: Audit, so the policy violations surface lights up without blocking a single workload. Switching a cluster to enforce is a separate, deliberate action you take when you are ready, cluster by cluster.
Then the fleet overview gives you the one number worth putting on a wall: what share of your scanned clusters have no actionable critical or high findings at all, with a plain-language verdict next to it rather than a grade.
None of this changes the advice from three weeks ago. If you are running a retired ingress controller with static kubeconfigs and a plaintext secret in Git, close those doors first, and no amount of scanning will substitute. But once they are closed, the scanner stops being displacement activity and starts being the inventory you work from, and at that point the thing that matters is whether your tooling can hold a decision. Findings are cheap. Decisions are the product.
The Security Center is available now on every Ankra organisation.
Get started: Create a free account on Ankra.
Join our community: Slack
Follow us on: LinkedIn | GitHub
Contact us: [email protected]
Get the next post in your inbox
Related Posts
Ankra is now ankra.ai: Rewritten in Go, Ready for What's Next
A new name, a new engine, and the biggest release we have ever shipped: the Go rewrite, an AI that owns the incident loop, passkey security, European multi-cloud, and Ankra on your phone.
Secrets Belong in Git. Plaintext Does Not.
Every GitOps rollout stalls on one question: where do the secrets go? A practical guide to SOPS and AGE encryption in Ankra, so credentials live in Git safely and AI-generated config never leaks a key.