Dashboard

What does a vulnerability management dashboard show in Metabase?

A vulnerability management dashboard shows open exposure and remediation velocity across every scanner: criticals by asset group, new vs. remediated per week, and SLA compliance by severity. It's built from findings synced from tools such as Tenable, Wiz, Snyk, and Orca Security.

For: security engineers, remediation owners, and CISOs reporting to the board. Grain: one row per open finding per asset.

What does a vulnerability management dashboard look like?

Here's the layout this guide builds, at the grain of one open finding per asset: total exposure and SLA standing at the top, then where the critical and high findings sit by asset group and team, then remediation velocity and the assets that keep failing. Read it in the weekly remediation review.

Vulnerability management dashboard in Metabase showing severity mix, aging buckets, remediation velocity, and SLAs.
An example vulnerability management dashboard in Metabase, built from Tenable, Wiz, and Snyk data. Figures are illustrative.

Which cards belong on a vulnerability management dashboard?

  • Open critical and high findings by asset group (bar)
  • New vs. remediated findings per week (line)
  • Median time to remediate by severity (bar)
  • SLA compliance by severity vs. target (table)
  • Findings aging buckets — under 30, 30–90, over 90 days (stacked bar)
  • Top assets by open critical findings with owner (table)

What data does the dashboard need?

  • vulnerability_findings — one row per finding per asset, with severity, status, first_seen_at, resolved_at, and sla_due_at.
  • assets — the inventory, with asset group, owning team, and criticality tier.

How do you build it?

  1. Sync findings from each scanner into one table with a shared severity scale and a canonical asset + CVE + source key.
  2. Join to the asset inventory so every finding has an owner and a criticality tier — unowned findings never get fixed.
  3. Stamp sla_due_at at first sight from severity, so SLA compliance is computable without re-deriving policy in every query.
  4. Build the open-criticals bar and the new-vs-remediated trend first; add aging buckets and the per-asset table next.

Example card SQL

Open critical findings by asset group with age bucketsPostgreSQL
SELECT
  a.asset_group,
  COUNT(*) AS open_criticals,
  COUNT(*) FILTER (
    WHERE f.first_seen_at >= CURRENT_DATE - INTERVAL '30 days'
  ) AS age_under_30d,
  COUNT(*) FILTER (
    WHERE f.first_seen_at < CURRENT_DATE - INTERVAL '30 days'
      AND f.first_seen_at >= CURRENT_DATE - INTERVAL '90 days'
  ) AS age_30_to_90d,
  COUNT(*) FILTER (
    WHERE f.first_seen_at < CURRENT_DATE - INTERVAL '90 days'
  ) AS age_over_90d
FROM vulnerability_findings f
JOIN assets a ON a.id = f.asset_id
WHERE f.severity = 'critical'
  AND f.status = 'open'
GROUP BY a.asset_group
ORDER BY open_criticals DESC;

Metrics

Integrations

Dashboards

FAQ

What is a vulnerability management dashboard?
A vulnerability management dashboard is the cross-scanner remediation view: how many critical and high findings are open, how fast teams close them, and whether closures happen inside the SLA. It joins findings from Tenable, Wiz, and Snyk against a single asset inventory, so open critical vulnerabilities and mean time to remediate become one number per team instead of a per-console guess. It's the anchor dashboard of a security analytics stack.
How do you dedupe the same CVE reported by multiple scanners?
Define a canonical finding key — asset + CVE + source — and dedupe on asset + CVE when counting exposure. If Tenable sees CVE-2026-1234 on a host and Orca Security sees the same CVE on the same host, that's one exposure with two evidence rows, not two findings. Keep the source column so you can still audit which scanner found what, and let scan coverage tell you where only one tool is looking.
Why use median time to remediate instead of the mean?
Remediation times are heavily right-skewed: most criticals close in days, but a handful of legacy findings sit open for a year and drag the mean into uselessness. The median tells you what a typical fix actually takes, and the aging buckets on this dashboard expose the long tail separately instead of letting it hide inside an average. Track time to remediate as a median by severity, and treat the over-90-day bucket as its own problem to burn down.
How is vulnerability SLA compliance computed?
Each finding gets an sla_due_at derived from severity at first sight — say 15 days for critical, 30 for high. A finding is SLA-compliant if resolved_at lands before sla_due_at; open findings past their due date count as breaches now, not when they eventually close. Vulnerability SLA compliance is then the percentage of findings resolved (or still inside the window) on time, sliced by severity and asset group so owners see their own number.
Why build this in Metabase instead of using each scanner's console?
Each scanner console reports only what that scanner sees, with its own severity model and no view of the others. Warehouse the findings and one dashboard answers the questions consoles can't: total exposure across cloud, host, and dependency scanners, remediation velocity per owning team, and a board-ready SLA number. It also joins security data to business context — asset criticality, ownership — and sits next to the AppSec findings and attack surface coverage dashboards for the full picture.