Dashboard

What goes in an IT compliance dashboard in Metabase?

An IT compliance dashboard tracks control attestation across frameworks — pass rates, evidence freshness, exceptions with owners, audit-finding burndown, and access reviews. It's the audit-cycle companion to the compliance posture dashboard: that page shows what your security platform's monitors see; this one shows what your auditor will ask about. Metabase builds it from GRC exports or a controls table in your warehouse.

For: IT compliance managers, control owners, and audit leads. Grain: one row per control test, evidence item, or exception. Refresh: daily from the GRC platform; weekly review cadence.

What does an IT compliance dashboard look like?

Here’s the layout this guide builds. The attestation headline sits at the top — controls monitored, failing, exceptions, overdue evidence, open findings — so the weekly review opens on one row; controls and evidence come next because pass rate and freshness are what slip between audits; the bottom section tracks the audit cycle itself: finding burndown, access-review progress, and the exception table the review meeting walks through.

IT compliance dashboard in Metabase showing control pass rates by framework, evidence freshness, exception aging, and audit-finding burndown.
An example IT compliance dashboard in Metabase, built from GRC-platform exports or a warehouse controls table. Figures are illustrative.

Which cards belong on an IT compliance dashboard?

The eight below cover the three questions an audit cycle turns on: are the controls passing, is the evidence current, and are the known gaps being worked down?

  • Overall control pass rate — latest test result across all active controls (gauge)
  • Control pass rate by framework — SOC 2, ISO 27001, PCI DSS, HIPAA side by side (row)
  • Failing controls by domain — where the gaps cluster (bar)
  • Evidence status by framework — current, due within 30 days, overdue (stacked bar)
  • Audit-finding burndown — open findings per week since the last audit (line)
  • Access reviews completed — this quarter’s reviews against the due count (progress)
  • Open exceptions by age — under 30 through over 90 days (row)
  • Open exceptions by owner — the worklist, with control, framework, age, and expiry (table)

What data does the dashboard need?

  • A controls table — control_id, name, domain, owner, active — plus a control_framework_map linking each control to the frameworks it satisfies.
  • control_tests with control_id, tested_at, and status — the latest row per control drives every pass-rate card.
  • An evidence table with collected_at and a per-item refresh_days cadence, for the freshness buckets.
  • exceptions with owner, opened_at, expires_at, and the control they cover; findings with opened_at and closed_at for the burndown.
  • Access-review records per quarter — system, reviewer, due_at, completed_at — for the progress card.

How do you build it?

  1. Export control and evidence state from your GRC platform daily — Drata and Vanta both have APIs, and a spreadsheet-based program can load its sheets into the warehouse as-is.
  2. Model “current status” once: a view that takes the latest test per control and joins the framework map, so every pass-rate card shares one definition.
  3. Compute evidence freshness as now() - collected_at against each item’s cadence, bucketed into current / due soon / overdue.
  4. Build the exception and finding cards from their own tables — age buckets for exceptions, weekly open-count for the finding burndown — and keep “exception” strictly separate from “failing control.”
  5. Add filters for framework, control owner, and date range; subscribe control owners to a weekly digest so the exception table arrives in their inbox before the review meeting.

Example card SQL

Control pass rate and overdue evidence by framework PostgreSQL
SELECT
f.framework,
COUNT(DISTINCT c.control_id)                          AS controls,
COUNT(DISTINCT c.control_id)
  FILTER (WHERE t.status = 'fail')                    AS failing_controls,
ROUND(
  100.0 * COUNT(DISTINCT c.control_id)
            FILTER (WHERE t.status = 'pass')
    / NULLIF(COUNT(DISTINCT c.control_id), 0), 1
)                                                     AS pass_rate_pct,
COUNT(e.evidence_id)
  FILTER (WHERE e.collected_at
            < now() - (e.refresh_days || ' days')::interval)
                                                      AS evidence_overdue
FROM controls c
JOIN control_framework_map f USING (control_id)
LEFT JOIN LATERAL (
SELECT status
FROM control_tests
WHERE control_id = c.control_id
ORDER BY tested_at DESC
LIMIT 1
) t ON true
LEFT JOIN evidence e USING (control_id)
WHERE c.active
GROUP BY f.framework
ORDER BY pass_rate_pct ASC;

Metrics

Integrations

Dashboards

FAQ

How is this different from a compliance posture dashboard?
The compliance posture dashboard is the security-platform view: automated monitors from Vanta or Drata continuously testing controls, with personnel compliance alongside. An IT compliance dashboard is the audit-cycle view: attestations, exceptions with owners and expiry dates, finding burndown, and access reviews — the things an auditor asks about that no monitor tests automatically. Most teams need both; this one is owned by whoever runs the audit calendar rather than the security tooling.
What's the difference between a failing control and an exception?
A failing control is a control whose most recent test didn't pass and that nobody has formally dispositioned — it's unplanned. An exception is a documented decision to accept the gap for a while: it has an owner, a justification, usually a compensating control, and an expiry date. The dashboard must keep them separate, because an auditor treats them very differently. The trap is the silent conversion — a failing control that lingers until someone writes it up as an exception to make the pass rate look better. Charting exception age catches that.
How do I measure evidence freshness?
Give every evidence item a refresh cadence — quarterly access-review exports, annual policy sign-offs, monthly backup-restore tests — and compute freshness as the gap between now() and collected_at versus that cadence. Then bucket into current, due within 30 days, and overdue. The 30-day bucket is the one that makes the dashboard useful: it turns evidence collection from a pre-audit scramble into a rolling queue. Group the overdue count by framework so you know which audit it endangers, not just how big the pile is.
Should each framework get its own dashboard?
No — keep one control set and map it to frameworks. Most SOC 2, ISO 27001, and PCI DSS requirements land on the same underlying controls (access reviews, change approval, encryption, logging), so testing once and mapping many-to-many via a control_framework_map table means one test updates every framework's pass rate. A per-framework dashboard multiplies work and lets the same control be "passing" for SOC 2 and forgotten for ISO. Use a framework filter on one dashboard instead — that's what the control pass rate by framework card is for.
How should exceptions appear on the dashboard?
As a table with owner, age, and expiry — never just a count. An exception without an expiry date is a permanent control gap wearing paperwork, and an owner column is what makes the weekly review actionable: the meeting walks the table, and each owner speaks to their line. Add an aging chart (under 30, 30–60, 60–90, over 90 days) because auditors read old exceptions as management not operating its own process. A reasonable rule: anything over 90 days needs re-approval, not renewal by inertia.
What does a realistic control pass rate look like mid-cycle?
Not 100%. A live estate that tests controls honestly will sit in the low-to-mid 90s between audits, because tests catch drift — that's the point of testing. What matters is the direction of the trend, the age of each failure, and whether the failing controls cluster in one domain (the failing-controls-by-domain card exists to show exactly that). A dashboard pinned at 100% all year usually means the tests are rubber stamps. Aim to enter the audit window at 100% with the burndown chart showing how you got there.
Where does the data come from if we track controls in spreadsheets?
Move the spreadsheet into the warehouse and keep the workflow. A controls sheet, an exceptions sheet, and a findings sheet upload cleanly as tables Metabase can query, and that alone gets you pass rates, aging, and burndown. When you adopt a GRC platform later, Drata and Vanta both expose control and evidence state through their APIs, so the dashboard keeps its shape and swaps its source. Start with the spreadsheet — the discipline of owners and expiry dates matters more than the tooling.