How to build Vanta dashboards in Metabase
Vanta is a trust management platform that automates compliance monitoring and evidence collection for SOC 2, ISO 27001, HIPAA, and other frameworks. Metabase is where you turn those security signals into shared, trustworthy dashboards. This guide covers two complementary paths: a lightweight MCP + CLI route that pulls live data with the Vanta MCP Server and loads a CSV into Metabase with the Metabase CLI, and a durable pipeline route that syncs Vanta findings into a database so you can build dashboards anyone can read.
How do you connect Vanta to Metabase?
Most teams combine both routes: use MCP and CLI uploads for a fast first pass, then move recurring security reporting to a warehouse-backed model.
Live data in, quick analysis out
Pair the Vanta MCP Server with the Metabase CLI. Use MCP for live lookups, write a scoped result to CSV, then load it into Metabase as a ready-to-query table and model.
- Quick lookups such as "show me control pass rate by framework"
- Loading a Vanta export into Metabase in seconds
- Spot-checks and one-off analyses without a warehouse
- Great for exploration, not governed security reporting
- Use read-only, minimally scoped credentials — security tools especially
- CSV uploads are snapshots — refresh or move to the pipeline for history
Durable dashboards with history
Sync Vanta findings and metadata into a database or warehouse with a connector, custom pipeline, or API, then point Metabase at it.
- Vanta posture reporting leaders and auditors depend on
- Joining Vanta data with assets, HR, ticketing, or other security tools
- Long-run trends for control pass rate by framework and failing tests with owner and age
- You own the refresh schedule and the snapshot cadence
- Sync findings, entities, and daily rollups — not the raw event firehose
- Metric definitions must be consistent across tools and teams
What can you analyze from Vanta data in Metabase?
- Control pass rate by framework — built from control tests and the related controls, frameworks, policies data your sync exposes.
- Failing tests with owner and age — built from control tests and the related controls, frameworks, policies data your sync exposes.
- Evidence freshness — built from control tests and the related controls, frameworks, policies data your sync exposes.
- Personnel compliance — built from control tests and the related controls, frameworks, policies data your sync exposes.
- Vendor review status — built from control tests and the related controls, frameworks, policies data your sync exposes.
Which Vanta dashboards should you build in Metabase?
Posture overview
How close you are to a clean audit, today.
- Control pass rate by framework (bar)
- Failing controls (number + trend)
- Tests failing more than 14 days (table)
- Audit readiness by framework (number)
Remediation queue
Failing controls, with names attached.
- Failing controls by owner (table)
- Newly failing this week (table)
- Time to fix failed controls (line)
- Evidence past its freshness window (table)
Personnel compliance
The human-side controls auditors always check.
- Security training completion (number)
- MFA adoption (number + trend)
- Background checks pending (table)
- Offboarding tasks overdue (table)
Trust reporting
Compliance posture as a business trendline.
- Pass-rate trend by framework (line)
- Open vendor reviews (number)
- Framework coverage map (table)
- Quarter-over-quarter posture change (bar)
How do you use the Vanta MCP Server with the Metabase CLI?
Pair the Vanta MCP Server with the Metabase CLI for fast, hands-on analysis. MCP is useful for scoped lookups and summarized exports; the Metabase CLI's upload command loads CSV data into Metabase and creates a ready-to-query table and model.
Example workflow
- Ask the MCP server for the current control tests with framework, status, and owner.
- Export the result as CSV, keeping stable IDs, severities, statuses, owners, and timestamps.
- Run
mb upload csvto load it into Metabase as a table and model, then build questions and dashboards on top.
Be honest about the limits
- MCP lookups are excellent for exploration, not scheduled reporting.
- A CSV upload is a snapshot; refresh it with
mb upload replaceor move to the pipeline for real history. - Compliance platforms report current state — daily snapshots are required for pass-rate trends.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up Vanta MCP and the Metabase CLI?
Vanta MCP Serverofficial · beta
- Transport
- Hosted remote MCP via Streamable HTTP
- Auth
- OAuth — available to Vanta Admin users only
- Best for
- Live scoped lookup and export
Metabase CLIofficial
- Install
npm install -g @metabase/cli- Auth
mb auth login- Load data
mb upload csv --file data.csv- Requires
- An uploads database (Admin → Settings → Uploads)
{
"mcpServers": {
"vanta": {
"url": "https://mcp.vanta.com/mcp"
}
}
}Regional endpoints: https://mcp.eu.vanta.com/mcp (EU) and https://mcp.aus.vanta.com/mcp (Australia). The earlier local vanta-mcp-server package is deprecated in favor of the hosted server.
# Install the Metabase CLI
npm install -g @metabase/cli
# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com
# Load a control-tests export — creates a table AND a model
mb upload csv --file vanta-control-tests.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file vanta-control-tests.csvCan you generate a Vanta dashboard with AI?
Yes. Use the prompt below with any assistant that can run the Vanta MCP Server and the Metabase CLI. It works end to end: if Vanta tables already exist in Metabase it analyzes those; otherwise it pulls scoped, summarized data over MCP, loads it with mb upload csv, then builds the dashboard and caveats any metric that needs missing history.
Create a polished Metabase dashboard for Vanta compliance analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help security and engineering leaders understand control pass rates, failing controls, personnel compliance, and audit readiness from Vanta data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for vanta tables and
models). If durable Vanta data is already present — synced from a warehouse
or uploaded earlier — use it and skip to Step 2.
- If nothing is there, pull a scoped, summarized export with the Vanta MCP Server:
control tests, plus controls, frameworks, policies.
Prefer aggregated or entity-grain views over raw events. Write each result to a
CSV, then load it with the Metabase CLI — run "mb upload csv --file <export>.csv"
so each upload creates a table and a ready-to-query model. Use "mb upload replace
<table-id> --file <export>.csv" to refresh an existing table instead of creating
duplicates.
Step 2 — Inspect before querying:
Do not assume exact table or column names. Inspect available fields, severities,
statuses, timestamps, and whether snapshots or history exist before creating
duration or trend cards.
Important:
- Build on whatever data is present; don't claim Metabase connects natively to
Vanta — it reads a database or CLI-uploaded tables.
- Never try to load raw security telemetry or event firehoses into Metabase; use
findings, detections, entities, and daily rollups.
- Only compute durations (time to remediate, time to triage, time to detect)
when the required timestamps exist.
- Exclude test environments and suppressed or accepted-risk items from headline
cards, and keep them visible in a labeled register instead.
- A single CSV is a point-in-time snapshot: only build trend cards if there is a
usable date column or multiple periods have been uploaded.
Dashboard title: Vanta Compliance Overview
Sections:
1. Executive summary: Pass rate by framework; Failing controls; Tests failing
>14 days; Personnel compliance; Vendor reviews open.
2. Controls: Pass rate by framework and category; newly failing this week.
3. Remediation: Failing controls by owner and age; time to fix.
4. Personnel: Training completion; MFA adoption; onboarding/offboarding tasks.
5. Trend: Daily snapshot history of pass rate by framework.
Filters: Date range, Severity, Status, Team or owner, Environment or asset group.
Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data.How do you sync Vanta data into a database or warehouse?
For dashboards that need history and reliability, land Vanta findings and metadata in a database first, then connect Metabase to that database.
Connector options
- Managed ETL — use a connector when one covers the objects you need.
- Custom pipeline — use the Vanta API for control over fields, snapshot cadence, and refresh schedule.
- MCP + CSV — use this for quick exploration and one-off slices.
No managed ELT connector — the notable gap in this category. Pull tests, controls, and people data from the Vanta API on a schedule, and snapshot daily: Vanta reports current state, so trends only exist if you build the history.
Notes
- Decide the snapshot cadence first (daily is the norm for security data) — posture trends only exist if you build the history.
- Land raw entity tables first, then build clean Metabase models on top.
- Normalize framework, control, status, owner, and tested-at fields.
How should you model Vanta data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
vanta_test_results_daily | one row per test per day | snapshot_date, test_id, control_id, framework, status, owner |
vanta_controls | one row per control | id, name, frameworks, category, owner |
vanta_people_compliance | one row per person | person_id, department, training_complete, mfa_enrolled, background_check, offboarded_at |
Modeling advice
- Build a clean
control_results_dailymodel with common columns across tools, so multi-source dashboards don't fork definitions. - Separate entity tables (assets, users, controls) from findings, events, and daily snapshot tables.
- Exclude test environments and suppressed or accepted-risk items from headline metrics; keep them in a labeled register instead.
- Use stable IDs for asset, user, and finding joins; display names change.
Which Vanta metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Control pass rate | Passing controls over monitored controls, per framework. | Use the latest test per control; snapshot daily. |
| MFA adoption rate | Active users with a strong second factor enrolled. | Report the factor mix, not just the total. |
| Vulnerability SLA compliance | Findings remediated within policy windows. | A standing control in most frameworks. |
| Open critical vulnerabilities | Open criticals — the number auditors ask about first. | Keep the accepted-risk register separate and labeled. |
What SQL powers Vanta dashboards in Metabase?
These assume a cleaned analytical model in a warehouse (PostgreSQL dialect). Adjust table and column names to match your pipeline.
Latest test result per control, rolled up per framework.
WITH latest AS (
SELECT DISTINCT ON (control_id, framework)
control_id, framework, status
FROM control_results_daily
ORDER BY control_id, framework, snapshot_date DESC
)
SELECT
framework,
COUNT(*) AS monitored_controls,
COUNT(*) FILTER (WHERE status = 'passing') AS passing,
ROUND(
100.0 * COUNT(*) FILTER (WHERE status = 'passing')
/ NULLIF(COUNT(*), 0), 1
) AS pass_rate_pct
FROM latest
GROUP BY framework
ORDER BY pass_rate_pct ASC;The remediation queue with accountability attached.
WITH history AS (
SELECT
control_id,
framework,
owner,
MAX(snapshot_date) FILTER (WHERE status = 'passing') AS last_passed_on,
MIN(snapshot_date) FILTER (WHERE status = 'failing') AS first_failed_on
FROM control_results_daily
WHERE snapshot_date >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY control_id, framework, owner
HAVING BOOL_AND(status = 'failing') FILTER (
WHERE snapshot_date >= CURRENT_DATE - INTERVAL '14 days'
)
)
SELECT
control_id,
framework,
owner,
-- The current streak starts the day after the most recent pass, so a
-- control that failed, was fixed, then broke again isn't aged from the
-- older failure. Never passed in the window: fall back to first failure.
COALESCE(last_passed_on + 1, first_failed_on) AS failing_since,
CURRENT_DATE - COALESCE(last_passed_on + 1, first_failed_on) AS days_failing
FROM history
ORDER BY days_failing DESC;Training and MFA completion from people records.
SELECT
department,
COUNT(*) AS people,
ROUND(100.0 * COUNT(*) FILTER (WHERE training_complete)
/ NULLIF(COUNT(*), 0), 1) AS training_pct,
ROUND(100.0 * COUNT(*) FILTER (WHERE mfa_enrolled)
/ NULLIF(COUNT(*), 0), 1) AS mfa_pct
FROM people_compliance
WHERE offboarded_at IS NULL
GROUP BY department
ORDER BY mfa_pct ASC;