Dashboard

What goes in a DevSecOps dashboard in Metabase?

A DevSecOps dashboard puts security inside the delivery pipeline: scan coverage in CI, findings by pipeline stage, remediation speed by severity, secrets-scanning catches, dependency freshness, and how often security gates block a deploy. It complements the estate-wide vulnerability management view and the findings-deep AppSec findings dashboard.

For: security engineers, platform teams, and engineering leads. Grain: weekly, with live counts for open criticals. Source: scanner and CI APIs, normalized into one findings table.

What does a DevSecOps dashboard look like?

Here’s the layout this guide builds. Posture scalars and the attention card lead, so an SLA breach is impossible to miss; findings and remediation come next — where findings surface and how fast they die; pipeline gates and hygiene close the page with the controls that stop new debt from entering.

DevSecOps dashboard in Metabase showing findings by stage, remediation time by severity, gate pass rate, and scan coverage.
An example DevSecOps dashboard in Metabase, built from normalized scanner and CI data. Figures are illustrative.

Which cards belong on a DevSecOps dashboard?

The eight below cover the loop: what the scanners see, how fast findings get fixed, and whether the gates are holding.

  • Findings by pipeline stage — PR review, build, deploy, per week (stacked bar)
  • New vs. resolved findings per week (bar)
  • Mean time to remediate by severity (row)
  • Oldest open critical findings, with age and SLA status (table)
  • Security gate pass rate, weekly with a goal line (line)
  • Secrets-scanning catches per week (bar)
  • Scan coverage by scanner type — SAST, SCA, secrets, IaC, containers (bar)
  • Dependency freshness — share of dependencies within 90 days of latest (line)

What data does the dashboard need?

  • A normalized security_findings table — severity, detected_at, resolved_at, repo, pipeline_stage, scanner, sla_interval — merged from your SAST, SCA, and container scanners.
  • CI gate results per pipeline run: gate name, pass/fail, and whether the failure blocked a merge or deploy.
  • Secrets-scanner events with repo, rule, and a resolved/revoked flag — counts only, never the secret material itself.
  • A repo inventory with which scanner types are enabled per repo, for the coverage card.
  • SCA dependency exports with pinned version, latest version, and release dates, for the freshness trend.

How do you build it?

  1. Pull findings from your scanners — Snyk, Semgrep, SonarQube — into one table, deduplicating on rule + location so a finding that appears in every nightly scan counts once.
  2. Tag each finding with the pipeline stage that surfaced it (PR review, build, deploy) from the CI context of the scan run.
  3. Encode your SLA per severity as an sla_interval column and build the remediation model — resolved time minus detected time — that every remediation card reads.
  4. Add gate results from CI check runs and the per-repo scanner inventory, then build the coverage and gate-rate cards against them.
  5. Add filters for repository, severity, scanner, and date range, and alert on the two numbers that matter daily: open criticals and gate pass rate.

Example card SQL

Open findings, remediation time, and SLA compliance by severity PostgreSQL
SELECT
f.severity,
COUNT(*) FILTER (WHERE f.resolved_at IS NULL)         AS open_findings,
ROUND(AVG(
  EXTRACT(EPOCH FROM f.resolved_at - f.detected_at) / 86400
) FILTER (WHERE f.resolved_at IS NOT NULL), 1)        AS mean_days_to_remediate,
COUNT(*) FILTER (
  WHERE f.resolved_at IS NULL
    AND now() - f.detected_at > f.sla_interval
)                                                     AS open_past_sla,
ROUND(
  100.0 * COUNT(*) FILTER (
    WHERE f.resolved_at IS NOT NULL
      AND f.resolved_at - f.detected_at <= f.sla_interval
  ) / NULLIF(COUNT(*) FILTER (WHERE f.resolved_at IS NOT NULL), 0), 1
)                                                     AS remediated_within_sla_pct
FROM security_findings f
WHERE f.detected_at >= now() - interval '90 days'
GROUP BY f.severity
ORDER BY
CASE f.severity
  WHEN 'critical' THEN 1 WHEN 'high' THEN 2
  WHEN 'medium' THEN 3 ELSE 4
END;

Metrics

Integrations

Dashboards

FAQ

What is a DevSecOps dashboard?
A DevSecOps dashboard measures security as part of the delivery pipeline rather than as an annual audit: how much of CI is covered by scanners, where in the pipeline findings surface, how fast each severity gets fixed, what the secrets scanner is catching, and how often security gates block a deploy. It is the shared page between security engineers and platform teams — unlike an AppSec findings dashboard, which goes deep on the findings themselves, this one keeps the pipeline in frame.
How is this different from a vulnerability management dashboard?
A vulnerability management dashboard covers the whole estate — hosts, images, cloud config — and lives with the security team. This dashboard covers what happens inside the delivery pipeline: scanners wired into CI, gates that pass or block, and findings attributed to a repo and a stage. The overlap is deliberate and small: both track remediation SLAs, so compute mean time to remediate from one shared model and let each page slice it its own way.
Why break findings down by pipeline stage?
Because the stage where a finding surfaces sets how expensive it is. A SAST hit in PR review costs one commit; the same flaw caught at the deploy gate costs a blocked release and a context switch; anything later is an incident. Charting findings by stage per week shows whether your shift-left investment is working — the PR-review share should grow over time — and explains remediation numbers: teams fix PR-stage findings in hours, while build-stage dependency findings sit for days because someone must chase an upgrade.
How do I keep secrets-scanning numbers honest?
Count catches, never the secrets themselves, and never put secret values, file paths, or diff fragments in the warehouse — a BI tool must not become a map of where credentials leak. A weekly count by repo with a resolved flag is enough to see whether catches are trending up because a new rule went live (good) or because a team is pasting keys into config (bad). Pair the count with time-to-revoke, since a caught-but-unrevoked credential is the real exposure.
What is a good security gate pass rate?
High enough that engineers trust the gate, low enough that it still catches things — in practice most teams land between 90% and 98%. A rate near 100% usually means the gate only enforces rules nobody violates; a rate below 90% means builds are blocking so often that teams will route around the gate or demand exemptions. When you tighten a rule, expect a dip and annotate it: a drop from 96% to 92% the week a secrets rule went blocking is the gate working, not failing — but only if most of the new failures are real catches.
How should I measure dependency freshness?
Pick one definition and chart the share: the percentage of dependencies within N days (90 is common) of their latest release, or without a known CVE at their pinned version. Share-based freshness beats counting outdated packages because the count grows with the codebase even when hygiene improves. Track it weekly from your SCA tool's export, and expect it to move slowly — its value is the direction, and as context for why dependency findings take longer to remediate than code findings.
Which severity SLA should the dashboard enforce?
Whatever your security policy already says — the dashboard's job is to make the SLA visible, not to invent one. A common baseline is 7 days for critical, 30 for high, 90 for medium, and best-effort for low. Encode the SLA per severity in the model (an sla_interval column) so the "open past SLA" count and the SLA compliance rate are computed, not eyeballed, and put breached findings in a table with names and ages — aggregates alone let old criticals hide.