Skip to main content
Ankra turns Trivy Operator vulnerability and compliance reports into a prioritised security workflow across your organisation, and computes pod-security posture itself from the inventory the agent already streams. The platform reads the operator’s Kubernetes reports through the agent. No scanner runs on Ankra’s side and no image data leaves your cluster.
Security is a read and policy layer over Trivy Operator image CVEs, benchmark compliance, and configuration audits. You install and configure the operator like any other add-on. Ankra surfaces, ranks, explains, and helps remediate what it finds.

Where to work

The dashboard Fleet Security widget summarises actionable severe risk and links into the organisation Security Center.

Prerequisites

Trivy Operator must be running in each cluster you want to assess. If it is not installed, the Security views explain the setup state and link to Settings → Integrations → Trivy Operator.
1

Add the Trivy Operator add-on

From Settings → Integrations → Trivy Operator, or the Stack Builder, add the trivy-operator Helm add-on and deploy it. It scans workloads and writes vulnerability, compliance, and configuration-audit reports.
2

Wait for the first reports

The operator scans images shortly after install. Until reports exist, the integration shows installed_no_reports.
3

Open Security

Use the organisation Security entry for fleet triage, or a cluster’s Security sidebar entry for a scoped view.
4

Optional: publish a software bill of materials

The SBOM tab reads the operator’s SbomReports, which are off by default because they are the largest objects it writes. On a cluster with control-plane headroom, set the security baseline input Software bill of materials per image (trivy_sbom_generation_enabled) to true; the next scan pass fills the tab. A package list, never image content, then leaves that cluster.

Security baseline

ankra-security-baseline is the public stack profile the platform installs on every cluster it provisions, unless the organisation opted out, and the one Enable security baseline installs on an imported cluster’s Security page. Like every profile it is a catalogue entry you can open, copy and fork. From version 5 it carries:
  • Trivy Operator for image vulnerabilities, configuration audits and the CIS benchmark, sized for a small cluster by default.
  • Pod Security Standards, enforced by Kubernetes itself. The profile ships an ankra-pod-security ConfigMap declaring the standard (baseline or restricted), the policy mode and the exempt namespaces. The Ankra agent labels every other namespace for Pod Security Admission, the admission controller built into every API server: pod-security.kubernetes.io/audit and /warn at the standard in Audit mode, and /enforce as well once you switch the cluster to Enforce. Labels are only ever raised, so a namespace you hold at a stricter level keeps it, and the agent records what it set so switching back to Audit restores the previous state exactly.
  • A guard for the enforce label. A ValidatingAdmissionPolicy (Kubernetes 1.30 or newer) refuses lowering the enforce label of a managed namespace below the declared floor for anyone but the agent, so enforcement cannot be switched off with a namespace edit. It fails open: an admission it cannot evaluate is admitted.
No policy engine runs on the cluster. Earlier versions of the baseline carried Kyverno with its Pod Security Standards preset; a cluster that installed one keeps it, receives the new manifests on its next update, and the policy mode toggle drives both mechanisms until you remove the two Kyverno add-ons from the stack. Kyverno remains available as the opt-in ankra-policy-engine profile, in the same safe mode, for image-signature verification and policies of your own.

What runs where

The Security Center’s Policies tab shows both halves per cluster: the platform posture table (every check, how many workloads pass and fail it, and when the inventory it was computed from was last seen) and the Pod Security Admission line (mode, standard, and how many namespaces carry the labels), beside the policy engine’s own reports where one is installed. Enforcement is measured from the namespaces, not assumed from the setting.

Sizing

The platform sizes the baseline from the cluster’s shape. A control plane below 8 GB of memory, or one whose size the platform cannot determine, gets the lite shape: the CIS node assessment is off so no collector job lands on the control plane, and one image scan runs at a time. The cluster carries a notification saying so until the control plane grows. A control plane of 8 GB or more gets the standard shape, and three or more workers let two scans run at once. A cluster you moved to Enforce, or whose exempt list you changed, keeps that across every republish.

Inputs

The policy mode is also on the API: POST /org/clusters/imported/{cluster_id}/security/policy-mode with {"mode": "audit"} or {"mode": "enforce"}, and the per-cluster GET .../security/policy-violations read carries policy_mode beside a platform_posture block with the posture table and the pod_security coverage figures. From the CLI and MCP. ankra security policy-mode audit|enforce --cluster <cluster> switches the mode (both directions confirm; --yes skips the prompt), ankra security violations --cluster <cluster> reads the posture table and the results per policy, and ankra security enable-baseline --cluster <cluster> publishes the baseline stack on a cluster that has none. From chat or the MCP server the same three are set_cluster_security_policy_mode, get_cluster_policy_violations and enable_security_baseline; the two writes are confirmed before they run.

Connection and scanner states


Observed vs actionable risk

Every finding is tracked with two complementary views:
  • Observed — everything Trivy currently reports, including accepted risk.
  • Actionable — findings that still need attention: open and acknowledged. Accepted risk is excluded from actionable totals, remediation queues, and threshold alerts, but remains visible.
Primary KPIs, fleet posture, alerts, scheduled reports, and AI summaries use actionable counts. Observed and accepted-risk totals stay available for context.

Exploitation intelligence (CISA KEV and EPSS)

CVSS severity says how bad a vulnerability could be; it says nothing about whether anyone is exploiting it. The Security Center cross-references every finding with two public feeds so you can prioritise on real-world exploitation:
  • CISA Known Exploited Vulnerabilities (KEV) - the catalog of CVEs with confirmed in-the-wild exploitation. A listed finding carries a KEV marker, the date CISA added it, the federal remediation deadline, and whether it is known to be used in ransomware campaigns.
  • FIRST EPSS - the daily Exploit Prediction Scoring System: the probability the CVE is exploited in the next 30 days, and where that probability ranks among all scored CVEs (for example EPSS 94% · top 1%).
The join happens on the platform by CVE id against the ids already present in your Trivy reports, so no image data leaves your cluster and Trivy Operator needs no extra configuration. The platform refreshes both feeds every six hours; a CVE that first appears between two refreshes has its KEV status immediately (the whole catalog is stored) and its EPSS score after the next pass. Where it appears:
  • The exploited-in-the-wild banner - when CISA lists any of your actionable findings, the Overview, the Findings page, and each cluster’s Security tab open with a red banner naming how many vulnerabilities are being exploited, how many are past CISA’s remediation deadline, and how many CISA links to ransomware campaigns, with Review exploited findings and Fix with AI one click away. It only appears on a synced catalog with a real count - it never renders “nothing exploited” from a catalog that has not been read.
  • Findings - the list opens ranked by Exploitability (KEV listing first, then EPSS, then severity), so the top of the page is what is actually being exploited. Each listed finding shows the KEV marker, CISA’s remediation deadline in explicit tense (deadline passed 2025-04-22 turns red), a ransomware marker where CISA reports ransomware use, and the EPSS probability. The Known exploited (CISA KEV) chip narrows to listed findings. The detail sheet quotes CISA’s own entry - vulnerability name, vendor and product, the deadline, and CISA required action - and shows EPSS and KEV under Advisory details.
  • Overview - a Known exploited scorecard tile with the overdue and ransomware subsets, and remediation candidates ranked known-exploited first with their CISA deadline.
  • Clusters, Workloads, and the add-on security panel - a known-exploited count beside the actionable and fixable counts, in red wherever it is above zero.
  • Alerts - two security_findings metrics: kev (actionable known-exploited findings on a cluster) and new_kev_cves (known-exploited CVEs new since the previous scan). The built-in new-severe-CVE notification also flags KEV listings of any severity.
  • Scheduled reports - a known-exploited banner, KEV markers and EPSS in the top-CVE table, and fix groups that clear a known-exploited CVE listed first.
  • API and MCP - known_exploited, kev_date_added, kev_due_date, kev_ransomware_use, kev_vendor_project, kev_product, kev_vulnerability_name, kev_required_action, epss_score, and epss_percentile on every finding and remediation candidate, a known_exploited filter on the findings and workloads lists, known_exploited counts on the overview, cluster, workload, and add-on reads, and known_exploited_overdue and known_exploited_ransomware finding counts on the overview. Pull them into your own reporting with a personal API token (ankra tokens create) against GET /api/v1/org/security/overview, /findings, /findings/{finding_id}, /workloads, and /clusters on https://platform.ankra.app - for example GET /api/v1/org/security/findings?known_exploited=true&sort=exploitability&order=desc. The AI security context carries the same fields.
  • CLI - ankra security overview (fleet totals, coverage, remediation candidates, and the exploited-in-the-wild summary first), ankra security findings (exploitability order by default, with --known-exploited, --severity, --status, --fixable, --cluster, --addon, --namespace, --sort), ankra security finding <id> (CISA’s entry, deadline and required action above every occurrence) , ankra security advisory <cve> (the platform’s own advisory for a CVE: the parsed NVD/OSV record, CISA’s guidance, affected versions in words, and your organisation’s exposure) and ankra security clusters; every one takes -o json for reporting.
Until the platform has synced the catalog at least once, the overview tile and the findings page say so rather than reporting zero: an unsynced catalog is unknown, not clean.

Advisory pages

Every finding links to an Ankra advisory page for its CVE at /organisation/security/advisories/CVE-... - the Advisory link on each findings row and Open advisory in the finding sheet - instead of sending you to the scanner’s external advisory site. The platform reads the public record itself, from the NVD 2.0 API and OSV, parses it, and renders it in the Security Center’s own vocabulary:
  • Summary - the analyst description, weakness classes (CWE ids), and aliases such as the GHSA id.
  • Exploitation - CISA’s KEV entry when the CVE is listed (catalog name, vendor and product, date added, the remediation deadline in explicit tense, ransomware use, and CISA required action), the FIRST EPSS probability, and CISA’s SSVC decision (exploitation observed, automatable, technical impact) as NVD republishes it.
  • Severity - the lead CVSS score and vector spelled out component by component (attack vector, privileges required, user interaction, impact), with every published assessment - NVD’s own and the CNA’s - one click away.
  • Affected versions - the CNA’s affected products and version ranges from NVD and the ecosystem package ranges from OSV, written as “2.34 before 2.39 (fixed in 2.39)” rather than as commit hashes.
  • In your fleet - the organisation’s current findings for the CVE (one per package, with occurrences, clusters, workloads, and how many occurrences have a fix), each opening the finding sheet.
  • References - the sources’ links grouped by kind: patches and vendor advisories first, then exploits, trackers, and mailing lists.
An advisory has three states and the page says which one it is in. A CVE the platform has not read yet shows Fetching this advisory from NVD and OSV and refreshes on its own - opening the page moves that CVE to the front of the platform’s read queue, and most records arrive within a minute. A CVE neither source holds a record for (a reserved or very new id) says No public advisory record for this CVE yet and is re-checked every two weeks. Only a record both sources actually returned renders as the advisory, with a provenance footnote naming when NVD and OSV were last read and linking to their own pages. The platform reads advisories for every CVE its security findings reference, known-exploited ones first, and re-reads stored records every 14 days so a reanalysed score or a newly published fixed version lands without anyone asking. The same content is available on the API as GET /api/v1/org/security/advisories/{cve_id} with a personal API token and on the CLI as ankra security advisory <cve>; its status field carries the three states (fetched, pending, missing, plus error while a source cannot be read).

Organisation Security Center

The organisation Security Center has eight sections:

Overview

Emphasises what to fix first. When CISA lists any actionable finding, the page opens with the exploited-in-the-wild banner. A fleet scorecard follows: a posture ring showing the share of scanned clusters with no actionable critical or high findings, a plain-language verdict, a Known exploited tile counting findings on the CISA Known Exploited Vulnerabilities (KEV) catalog (with how many are past CISA’s deadline and how many are used in ransomware), and tiles for actionable critical, actionable high, fixable severe, and scanner coverage. Remediation candidates rank known-exploited CVEs first, ahead of CVSS severity. Below it sit the fleet trend, ranked remediation opportunities, and policies nearing review. The page reads from posture rollups the platform keeps current as scans land, so the overview, the findings list, and the cluster posture answer in milliseconds on fleets with millions of recorded occurrences. The fleet posture trend is built from daily snapshots, so you can see whether actionable risk is rising or falling over time rather than only its current level. The same trend feeds scheduled security reports. From the CLI and MCP. One cluster’s snapshots are readable off the browser: ankra security history --cluster <cluster> [--days 90] prints the day-by-day table (findings by severity, fixable severe, workloads and namespaces scanned, risk score, the actionable / acknowledged / accepted-risk split) with a one-line trend; from chat or the MCP server the tool is get_cluster_security_history, and with an API token the route is GET /api/v1/org/clusters/imported/{cluster_id}/security/trivy/history?days=. A cluster without snapshots yet answers an empty list, not zeros. Fix top findings with AI hands the highest-ranked remediation candidates to Ankra AI with fleet context attached and asks for a prioritised plan. See Ask Ankra AI.

Findings

Server-paginated inventory of logical findings, deduplicated across clusters and workloads. Status filter chips carry live counts: Actionable (open and acknowledged, the default view), Open, Acknowledged, Accepted risk, and Resolved. Filter further by severity, fixability, Known exploited (CISA KEV), cluster, add-on, and namespace. Each finding carries its exploitation intelligence: a KEV marker when CISA lists the CVE as exploited in the wild, CISA’s remediation deadline, a ransomware marker where CISA reports it, and the FIRST EPSS probability and percentile. The list opens sorted by Exploitability (KEV listing, then EPSS, then severity); every other sort is one click away. The detail sheet lists occurrences and matching policies, quotes CISA’s required action for a listed CVE, and carries the disposition actions plus Ask Ankra AI. Every number on a row opens the rows behind it. The Occurrences chips (Open · 7, Resolved · 2) count occurrences - one per workload, container and image, so a workload can carry several - and selecting one opens the sheet on exactly that status: the live statuses filter the remediation plan, and Resolved shows the occurrences the scanner no longer reports, most recently resolved first, with the workload, image and when each was resolved. The Affected cell (7 clusters · 7 workloads) opens the sheet’s Affected clusters table, one row per cluster with its live workloads, the same four status counts, and when it last reported the finding; each cluster name deep-links into that cluster’s Security tab with the finding already open, so a fleet-wide count can be followed down to one cluster’s rows. A cluster that has since been deleted keeps its row (its occurrences are still part of the totals) but is marked deleted and not linked. The counts and the lists are computed by the same query, so a chip never claims a row the sheet cannot show. The API exposes the same views as clusters on GET /api/v1/org/security/findings/{finding_id} and the paginated GET /api/v1/org/security/findings/{finding_id}/occurrences?status=resolved&cluster_id=…. When an occurrence becomes resolved. Deleting a workload, or the VulnerabilityReport trivy-operator wrote for it, does not retire its occurrences on the next pass. The platform re-evaluates findings every five minutes, but it counts an occurrence as missing only once per completed full resource sync of the vulnerability-report kinds, and retires it after it has been missing on two consecutive full syncs, so a partial or interrupted sync can never read as a clean bill. Full syncs run about once an hour, which means an image that stopped running stays Open for one to two hours before it moves to Resolved and the cluster’s and namespaces’ actionable, critical and known-exploited totals drop with it. To bring that forward, run Full Sync from the cluster’s Settings → Kubernetes tab twice, letting the first finish before starting the second; the evaluation that follows the second sync retires the occurrences.

Clusters

Per-cluster actionable posture, observed/accepted context, scanner freshness, and a deep link into that cluster’s Security view.

Workloads

The fleet broken down the way a platform team owns it: cluster, then namespace, then workload, then pod. Each row is one namespace on one cluster with its scanned workloads and images, the pods the cluster runs there right now, the actionable findings by severity, the known-exploited count, fixable severe findings, and the last scan. Cluster-scoped reports (node and control-plane images) keep a row of their own, labelled Cluster-scoped, so the rows still add up to the cluster’s totals. Search by namespace or cluster, scope to one cluster, and sort by actionable findings, severity, known exploited, workloads, or pods. A namespace is where the drill-down starts, because it is usually how a team owns its workloads. Every row carries the way down: Findings, Bill of materials and Containers open the Findings and SBOM tabs already narrowed to that namespace on that cluster, and every figure on the row is a link to the list it counts - the actionable total to those findings, the known-exploited count to the KEV-listed ones, the image count to the images running there, the pod count to the running containers. Rows also say how many of their images have a bill of materials, with a link to the containers running without one. Once narrowed, a scope bar at the top of the Findings, Workloads and SBOM tabs names the cluster and namespace, offers the same scope on the other surfaces, and drops it in one click; the tab bar carries the scope across too, so switching tabs never falls back to the fleet. Show workloads on a row lists the scanned workload images in that namespace, riskiest first, each linking to its live Kubernetes page and to the bill of materials of the containers it runs. Show pods under a workload lists the pods it owns right now - resolved through the owner chain, so a Deployment’s report on its ReplicaSet reaches the pods - with every container joined to the findings of the workload container behind it: critical and high counts, known-exploited markers, readiness and restarts, and the running image digest. A container the scanner has no report for is marked Not scanned, never shown as clean, and a pod nobody scanned reads Not scanned rather than healthy. A namespace with more than 2,000 pods says the listing is capped. The API exposes the same three levels: GET /api/v1/org/security/namespaces?cluster_id=&search=&sort=&order=, the existing GET /api/v1/org/security/workloads?cluster_id=&namespace=, and GET /api/v1/org/security/pods?cluster_id=&namespace=&workload_uid= (or workload_kind + workload_name). From the CLI and MCP. ankra security namespaces [--cluster], ankra security workloads (the findings filters plus --sort risk_score) and ankra security pods --cluster <cluster> --namespace <namespace> [--workload-kind --workload-name] walk the same three levels, and ankra security finding <id> --status resolved --cluster <cluster> lists one finding’s occurrences instead of the summary. From chat or the MCP server the tools are list_security_namespaces, list_security_workloads, list_security_pods and list_security_finding_occurrences.

SBOM

The fleet’s software bill of materials: every package the scanner found in every container image, where it runs, and whether a finding names it. It answers the question a new CVE raises - where do we run this package - without waiting for a rescan. Components lists one row per package name, version and ecosystem across every image that carries it: its licences and their licence risk tier, how many images, workloads and clusters carry it, and the findings that name that exact package and version on those images (with actionable and known exploited counts; the findings count links to the Findings tab searched for the package). Search by name or package URL, filter by ecosystem or licence tier (the chips carry live counts), keep only packages with or without findings, and scope to one cluster or namespace.

Licence risk

Every component’s licences - the SPDX identifiers, expressions or names the scanner recorded - are classified into one of six tiers, ordered by what they oblige of the code that links the package. The classification follows SPDX semantics: an OR expression lets you pick the least consequential alternative, an AND binds every term, and a package that names several licences is taken to be under all of them. The SBOM summary counts the packages under the two tiers that reach the hosting service (Licence obligations) and breaks every view down by tier; each figure links to the list it counts, and the tier chips narrow the component list the same way the ecosystem chips do. An image’s row and its detail page carry the same per-tier counts, and the CSV export gains a license_risk column. Classification happens once, when the bill of materials is stored, so the fleet-wide “every AGPL package we run” read is an indexed filter rather than a rescan; rows stored before the tier existed are classified in the background within a few minutes of a deploy. Isolating a network-copyleft component behind its own service, reached over REST or gRPC rather than linked into your code, keeps the obligation with that service alone; the tier is the same either way, so the filter is the place to check that no such package sits in an image of your own application. Every figure in a component row opens the list it counts. The package name opens the package page: the images whose bill of materials name that exact name, version and ecosystem, every workload container currently running those images (cluster, namespace, workload, container, image, last seen), and the clusters they run on with per-cluster workload and image counts. The images, workloads and clusters figures in Where it runs open that page scrolled to the matching section, and each entry there links onward - an image to its bill of materials, a workload to its live Kubernetes page, a cluster to its security tab, a per-cluster count to the same page narrowed to that cluster (each cluster row reads N workloads in M containers) - so the trail from a licence tier to the place it runs never dead-ends. The lists cap at 200 images and 500 containers and say so when they do. The same read is GET /org/security/sbom/component?name=&version=&package_type= (add cluster_id= to narrow it to one cluster), ankra security sbom component <name> --version <v> --type <ecosystem> [--cluster <name>], and the get_security_sbom_component AI tool. Images lists every image with a bill of materials: OS, component count, its licence risk (the obliging tiers it carries), the workloads, clusters and namespaces running it, the actionable findings attributed to it, and when the bill of materials was generated. Opening an image shows its identity (reference, digest, registry, CycloneDX version), the workload containers running it, its Vulnerabilities - every CVE the scanner names on the image, one row per CVE and installed package version across every container running it, with the fixed version, the CISA KEV listing and EPSS probability, the worst disposition across its occurrences and where it runs, each opening the finding for its advisory and remediation plan - then its full component list with the same search, ecosystem and findings-first controls, and two Download buttons: a CycloneDX 1.5 JSON document (what Dependency-Track, Grype and licence scanners ingest) or a flat CSV, rebuilt from the stored components and complete rather than paged. The counts on the image summary open the lists they count: the component count the components, the findings and known-exploited counts the vulnerabilities, the workload count the containers running the image. Containers starts from the other end: every container the clusters are running right now, init containers included, joined to the bill of materials of its image - or marked No bill of materials when the scanner has none for it. Those rows sort first, because they are the gap to close: a cluster with SBOM generation switched off, a registry the scanner cannot pull from, or a tag that rolled since the last scan. The headline counts running containers, how many have a bill of materials and how many do not, before the status chips or the search narrow the list, so the figure holds while you drill. Column headers sort like every other list in the portal. Every view scopes by cluster, namespace and workload (the resolved Deployment, StatefulSet, DaemonSet or CronJob; a bare pod matches its own name), so “what does this deployment ship” is one filter away. The coverage headline above a scoped list is that scope’s, not the fleet’s, and every figure in it links to the list it counts - components, images, workloads, the packages a finding names, the containers with and without a bill of materials, the clusters publishing one - so a number is never a dead end. An application’s Security section carries the same data per version on its SBOM view: one row per pushed tag of each component’s image, with the bill of materials the scanner holds for it (and the obliging licence tiers it carries), the findings currently attributed to it (known-exploited and fixable-severe counts included), where it is running, and which sources saw it - so a tag nobody deployed, a deployed tag with no bill of materials, and a scanned tag the registry no longer lists stay distinguishable. The CycloneDX and CSV downloads sit on each row. The pane also reads the licences against the application’s own repository. When the repository is private and the newest scanned version of a component links a network-copyleft package, a Licence obligation notice says so in plain terms - hosting that version as-is obliges you to publish its source, or to move the package behind a separate service - and lists the packages, each opening the image’s bill of materials filtered to that tier. A source-available package raises the same notice whatever the visibility, because a managed service needs a commercial licence either way; GPL packages get a quieter note about distribution. A public repository has already met the disclosure obligation and the notice says that instead; a repository the platform has not synced is treated as private until someone confirms otherwise, never as public. The same verdict is on the API (repository.visibility, license_exposure.source_disclosure_required, license_exposure.service_licence_required and the flagged components on GET /org/applications/{id}/security/versions). The bill of materials is opt-in per cluster (see Prerequisites). The tab’s coverage line says how many scanned clusters publish one, and the empty state names the input to turn on, so an empty inventory reads as a switch nobody has flipped rather than a fleet with no packages. Images are keyed by digest and their components stored once, so an image running on ten clusters costs one bill of materials; an image no cluster runs any more keeps its last bill of materials but shows no workloads. The API exposes GET /api/v1/org/security/sbom (components; search, package_type, vulnerable, cluster_id, namespace, workload_kind, workload_name, image, sort, order), GET /api/v1/org/security/sbom/images (the same scope), GET /api/v1/org/security/sbom/image?image=<digest or reference>, GET /api/v1/org/security/sbom/containers (cluster_id, namespace, workload_kind, workload_name, status=present|absent, search; the response carries an inventory block counting the scope), GET /api/v1/org/security/sbom/image/export?image=<identity>&format=cyclonedx|csv (a download), and GET /api/v1/org/security/sbom/image/findings?image=<identity> (the CVEs on one image: search, severity, sort, order, paging; image.sbom_status says whether a bill of materials is stored, and a summary block totals the image before the filters narrow the rows). Every read carries a coverage block with scanned_clusters against clusters_with_sbom, scoped the way the list is. Namespace rows on GET /api/v1/org/security/namespaces carry sbom_images, the distinct images running there with a bill of materials. Per application, GET /org/applications/{id}/security/versions lists the image versions. From the terminal, ankra security sbom, ankra security sbom images, ankra security sbom image <image>, ankra security sbom findings <image> (the CVEs on one image, --severity repeatable), ankra security sbom containers and ankra security sbom export <image> [--format csv] read the same data; every one takes -o json, and the inventories take --cluster, --namespace, --workload-kind and --workload-name. From chat or the MCP server, the tools are list_security_sbom_components, list_security_sbom_images, get_security_sbom_image, list_security_sbom_image_findings and list_security_sbom_containers.

Policies

Organisation-wide disposition rules: active, expiring, fix-available, mitigated, unmatched, expired, and revoked. Edit, renew, or soft-revoke with a fresh server-side match preview. From the CLI and MCP. ankra security dispositions lists the policies (--status and --disposition repeatable, --sort updated_at), ankra security dispositions preview --occurrence <id> --disposition accepted_risk shows what a decision would cover, ankra security dispositions create --occurrence <id> --disposition acknowledged|accepted_risk --reason "…" [--expires-at 2026-12-31] [--expire-when-fix-available] writes it after printing that preview and asking (--yes skips the prompt), --scope workload or --scope image on either records it for a finding no add-on owns (see what a disposition is pinned to), and update <policy-id> / revoke <policy-id> --reason "…" carry the lifecycle. From chat or the MCP server the tools are list_security_dispositions, preview_security_disposition, create_security_disposition, update_security_disposition and revoke_security_disposition; the three writes are confirmed before they run and re-check security.triage or security.manage exactly as the portal does.

Network Exposure

How tightly a cluster’s NetworkPolicies are scoped, in and out. Identity - not port or CIDR - is what excludes an attacker, so a workload with no policy, or an allow-rule broader than a named workload identity, counts as over-privileged. Ingress and egress are scored separately, each from 0 to 100, and each blends two halves: A rule counts as broad unless every peer is identity-scoped. An ipBlock on ingress, a namespaceSelector, an empty selector, or a missing from / to all make a rule broad. Findings list every unprotected workload and every broad rule, ranked by severity with ingress before egress. Filter by flow, namespace, or severity. An unprotected workload is high severity on ingress and medium on egress, because egress default-deny is uncommon enough that its absence is exposure to review rather than an active misconfiguration.
This score reads your policy objects, never your traffic. It cannot tell you whether a policy is safe to apply, and three limits follow from that:
  • Enforcement is not verified. The score reflects how the policies are written, not whether your CNI enforces NetworkPolicy at all.
  • A fully locked-down cluster and a broken one score identically. A default-deny in every namespace with no allow-rules scores 100 out of 100 while blocking every flow in the cluster. Treat a high score as “policy is written tightly”, not “the cluster is healthy”.
  • Coverage is partial. Only Deployments, StatefulSets, and DaemonSets are inventoried, and ports are not scored.
Use it to find workloads nobody has scoped yet. Do not use it to decide a policy change is safe - that needs observed traffic, which this metric does not have.
From the CLI and MCP. ankra security network-exposure --cluster <cluster> prints both scores with their coverage and tightness halves and the ranked findings; the tool is get_cluster_network_policy_overprivilege. Both are live reads through the agent, so an offline cluster answers with a retry hint rather than a stale score.

Compliance

Fleet-wide benchmark scores for CIS Kubernetes, NSA/CISA hardening, and Pod Security Standards, alongside configuration-audit findings and report coverage. Filter for clusters that need attention, compare frameworks, and select a cluster to open its full Security workspace on the Compliance tab. From the CLI and MCP. ankra security compliance is the fleet rollup, ankra security compliance frameworks lists GDPR, ISO 27001, SOC 2 and NIST CSF with each framework’s switch and live score, frameworks enable|disable <key> flips one (--yes skips the prompt), frameworks report <key> [--month 2026-08] reads a report control by control, and ankra security compliance export --format csv|json [--start-date --end-date] [--output-file] downloads the evidence report. Per cluster, ankra security benchmarks --cluster <cluster> lists every failing control with its remediation and benchmarks resources --cluster <cluster> --check <id> [--source config_audit] the objects behind one control. From chat or the MCP server: get_security_compliance_overview, list_security_compliance_frameworks, get_security_compliance_framework_report, set_security_compliance_framework (confirmed, security.manage) and, per cluster, get_compliance_reports.

Cluster Security view

Each cluster Security page shares the same domain model, scoped to that cluster:
  • Quiet scanner/freshness status with refresh and secondary actions (schedule a report, create an alert).
  • Stacks — the cluster broken down the way Ankra deployed it, and the tab the page opens on when the cluster runs stacks. One row per stack with its attribution status, scope (add-ons · manifests · matched workloads · unmatched members), actionable findings with the fixable severe count, the known-exploited count, and how many of its running containers have a bill of materials; a closing Outside any stack row counts the system namespaces, node images and hand-applied objects no stack owns, so the rows add up to the cluster. Every figure opens the list it counts, already narrowed to the stack, and the stack name opens the stack’s own Security tab, where a member drills on to its workloads and pods. The summary strip above the table (actionable in stacks, known exploited, stacks with a gap to close, containers without a bill of materials) links the same way. A stack whose members matched nothing reads Unmatched, never clean. A cluster with no stack opens on the Overview instead, and ?tab= in the URL always wins.
  • Overview — the exploited-in-the-wild banner, the actionable summary, and then the breakdowns: a Known exploited (CISA KEV) card (how many of this cluster’s findings CISA lists as exploited, their share of its actionable occurrences, how many are past CISA’s deadline or used in ransomware, and the exploited findings themselves with their deadlines), the Risk breakdown (severity mix, review state, fix readiness), the ranked remediation list, the cluster’s Application hotspots (workloads ranked by weighted actionable risk), and the trend.
  • Findings — server-side list and detail sheet with acknowledge / accept-risk flows, including the KEV markers, EPSS scores, and exploitability sort.
  • Workloads — risk explorer with namespace and add-on filters. The organisation-wide Workloads tab adds the namespace and pod levels above and below it.
  • Network Exposure - the same NetworkPolicy scoping scores and findings described above, for this cluster alone.
  • Compliance: failed and passed benchmark checks, configuration-audit hotspots, scanner remediation, and Fix with AI actions.
Use the Compliance filters to focus by result, severity, framework, check ID, or remediation text. Failed checks show affected results and scanner guidance. Passed checks stay collapsed by benchmark until you need evidence for an audit.

Stack security

A stack’s detail page has a Security tab built around what makes the stack up: its running pods, each under the add-on or manifest that deploys it, and every container of every pod with its own CVE report, bill of materials and KEV report one click away. The stack is attributed to running objects two ways, one per member kind. An add-on is a Helm release, so every object in the cluster’s resource cache carrying that release’s identity - the meta.helm.sh/release-name annotation with its release namespace, or the app.kubernetes.io/instance label the chart stamped - belongs to it, whether or not the chart is in the add-on catalog. A manifest is the objects its YAML declares, matched by kind, namespace and name. From those objects the scope walks two owner levels down (Deployment → ReplicaSet → Pod, CronJob → Job → Pod), because the scanner reports on the controller that owns the pods, not the object you wrote. The tab has three views, and the view and its filters live in the page URL so a container’s report can be handed to someone as a link:
  • Pods (the default) - a posture strip on top: actionable occurrences by severity, the known-exploited count, the fixable severe count, the component count and how many of the stack’s running containers have a bill of materials, each figure opening the list it counts. Below it the running pods, grouped under the member that deploys each. A pod names its namespace, its owner workload (linked to the workload page), its priority and when it was last seen, then every container and init container: image, scan state, actionable findings by severity, KEV count, bill of materials, and three openers - CVE, SBOM and KEV - into the container’s dedicated view. Search matches pod, namespace, member, workload, container and image; a member chip narrows to one add-on or manifest; a member with no running pod attributed is listed as unmatched, never dropped. A stack past the read’s container cap says the listing is partial.
  • Findings - the stack’s CVEs with the same severity, status, known-exploited and fix-available filters, sorts and detail sheet as the Security Center, and facet counts computed for the stack alone.
  • Components - every package in the images the stack’s pods run, searchable, with a Vulnerable only switch and the findings that name each component.
The pods list is also the way down through Kubernetes. Under a member’s heading, Show workloads lists the workloads that member deploys - the Deployments, StatefulSets, DaemonSets, CronJobs and Jobs its release identity or declared objects resolved to - each with its pods, scan state, severe actionable findings, known-exploited count and how many of its containers have a bill of materials. A workload opens on its own Security tab, its Bill of materials link opens the Security Center’s containers list scoped to that workload, and Show pods lists the pods it runs right now, each opening on the pod’s Security tab. Every link from a security surface to a Kubernetes object lands on that object’s Security tab rather than its overview, so the path cluster → stack → member → workload → pod → container never leaves the security view. The workloads read is GET /org/clusters/imported/{cluster_id}/stacks/{stack_name}/security/workloads; the cluster’s stack list is GET /org/clusters/imported/{cluster_id}/security/stacks, both with /api/v1 twins. On the CLI, ankra security stacks --cluster <cluster> prints the stack list, ankra security stack <name> --cluster <cluster> the stack with its members and their workloads, and ankra security pod <namespace> <pod> --cluster <cluster> one pod container by container; Ankra AI and the MCP server answer the same questions through list_cluster_security_stacks, get_cluster_stack_security and get_cluster_pod_security. The tab never renders an absent answer as a clean one. A cluster the scanner has not reported on reads not scanned and its containers are still listed, each marked Not scanned; a stack whose members resolve to no object in the resource cache reads unmatched (it may not be deployed yet, or its workloads carry no Helm release identity); pods that were attributed but carry no report yet read no reports yet; and when the CISA catalog has not been synced, every known-exploited figure reads unknown rather than zero. The summary is on the API as GET /org/clusters/imported/{cluster_id}/stacks/{stack_name}/security, with /pods, /findings and /sbom lists beside it and /api/v1 twins for API tokens.

The container view

Every container - opened from the stack’s pods, from the pod’s Security tab, or by link - has one dedicated view with three sections named in the URL (section=cve, sbom or kev):
  • CVE report - every CVE the scanner names on the container’s image, one row per CVE and installed version, with severity, exploitation (CISA listing and EPSS), installed and fixed versions, disposition and where else the image runs; each opens the finding and its advisory.
  • Bill of materials - the image’s components with the findings that name each exact version, searchable and filterable by ecosystem, with the CycloneDX and CSV downloads. A container whose image has no stored bill of materials says so as a state to act on, with the opt-in guidance, rather than showing an empty list.
  • KEV report - the same CVE list filtered to the CISA Known Exploited Vulnerabilities catalog, with the remediation deadline each carries. While the catalog has not been synced the report reads unknown, never empty.
Around the reports is the ring of links that closes the circle: the pod’s Security tab, the stack and the member that deploy the pod, the owning workload’s page, the image in the Security Center’s SBOM tab, every container running the same image, and the findings of the namespace. A container no report covers is marked Not scanned in the view’s header, and the CVE figure reads not scanned rather than zero.

Pod security

A pod’s detail page has a Security tab (shortcut s) that reads the pod container by container: every container and init container it runs, each with the CVEs the scanner attributes to the workload container behind it and the bill of materials of its image. The owner chain is walked the way the namespace breakdown walks it (Pod → ReplicaSet → Deployment, Pod → Job → CronJob), so a Deployment’s report on its ReplicaSet reaches the pod. When one of the cluster’s stacks deploys the pod, the tab says which stack and which add-on or manifest, linked back to that stack’s pods. The summary shows the pod’s actionable occurrences by severity, how many of its containers the scanner covers, the known-exploited and fixable-severe counts, and how many containers have a bill of materials with the component and image totals. The By container table lists init containers first with the image, readiness and restarts, the scan state, actionable findings by severity, the KEV count and the bill of materials (components and OS, or Absent), and the same three openers as the stack’s pods - CVE, SBOM, KEV - into the container view described above, named in the URL (container= and section=) so it can be linked to directly. Nothing absent reads as clean: a container no report covers is marked Not scanned, a container whose image has no stored bill of materials reads Absent and its SBOM view explains what is missing, a pod with neither reads no report yet, an unscanned cluster says so, an unsynced CISA catalog leaves the known-exploited figure unknown, a pod nothing in a stack deploys simply carries no stack line, and a pod whose stacks’ members could not be read says the stack is unknown rather than pretending there is none. The same read is on the API as GET /org/clusters/imported/{cluster_id}/security/pods/{namespace}/{pod_name} - its stack field names the deploying member or is null, and stack_attribution says what that null means (attributed, none or unknown) - with an /api/v1 twin for API tokens.

Add-on security posture

On a stack add-on’s Overview, a compact Security panel shows:
  • Actionable critical/high counts, the known-exploited (CISA KEV) count, and the accepted-risk count
  • Affected images and workloads
  • Scan freshness and scanner setup states
  • Partial-attribution warnings when ownership cannot be proven for every report
Cluster-scoped and ambiguous reports are not attributed to an add-on. The panel’s Open in Security action deep-links into the cluster Security view filtered by that add-on’s slug. A security API failure never blocks the operational add-on overview. From the CLI and MCP. ankra security addon <addon-name> --cluster <cluster> reads the same panel, and get_cluster_addon_security is the tool. Per application, ankra application security-versions <application> [--component <name>] and get_application_security_versions list every pushed image version with its bill of materials, findings and licence exposure.

Acknowledge vs accept risk

Two distinct dispositions are available for a finding: Accepted risk requires:
  • A reason
  • An actor (recorded in audit)
  • A review deadline, maximum one year
  • Optionally, automatic expiry when a fix becomes available
Matching uses a deterministic selector: organisation + CVE + package type + package name + what the disposition is pinned to. Creation always shows a server preview of affected findings, clusters, ambiguous exclusions, and the observed→actionable count change. Policies are never hard-deleted; they can be revoked, expire, mitigate when no matches remain, or reopen if findings return.

What a disposition is pinned to

A disposition is created from one occurrence of a finding, and its scope decides what it covers: Some images belong to no add-on: pods an operator creates from a custom resource (a CloudNativePG Cluster, for example), workloads from plain manifests, control-plane pods, and charts the add-on catalogue does not know. The default scope refuses those, and the refusal names the two scopes that work. Use workload to decide for one place, or image to decide once for an image that runs in several namespaces or clusters:
An image-scoped disposition follows the digest, so it stops matching when the image is rebuilt or upgraded and the finding returns for a fresh decision. From chat or the MCP server, pass the same scope to preview_security_disposition and create_security_disposition.
Expiry or fix availability can make findings actionable again and may fire threshold alerts. It does not emit a false “new CVE discovered” notification — “new” means newly observed in raw scan data and currently actionable.

Permissions

Custom roles may grant these permissions. Backend enforcement is authoritative; the UI only gates controls. All disposition mutations are audited and write append-only policy events in the same transaction.

Ask Ankra AI

The AI assistant can read the same vulnerability and compliance data. Three entry points open chat already grounded in what you are looking at: The agent can inspect affected Kubernetes resources, propose or apply safe changes, and verify the result. Risky or disruptive changes still require confirmation.
Product analytics for these actions record only that an AI action happened, through a strict allowlist. CVE identifiers, finding titles, prompts, and workload names are never sent.
The assistant distinguishes observed, actionable, acknowledged, and accepted-risk findings. Accepted risk is never treated as “gone.”

Add-ons

Install Trivy Operator and other add-ons.

Roles and access

Grant security.read, security.triage, and security.manage.

AI Assistant

Triage vulnerabilities in chat.

AI Insights

Proactive cluster health analysis.