I Built an Open-Source Vulnerability Scanner with a Real-Time Dashboard — Because Nothing Else Did It All
Self-hosted. No SaaS. No cloud accounts. Just your infrastructure, fully visible.

The Problem That Started It All
If you run servers, write code, or manage containers, you already know the uncomfortable truth: vulnerabilities, exposed secrets, and misconfigurations are everywhere. The question isn't if they exist in your infrastructure — it's whether you know about them.
Most teams fall into one of two traps:
Trap 1 — Enterprise SaaS tools. Snyk, Wiz, Orca, Lacework. Powerful, polished, and expensive. They also require cloud accounts, and your code, container metadata, and scan results travel to someone else's servers. For regulated industries, startups watching spend, or anyone who simply values data sovereignty, this is a deal-breaker.
Trap 2 — Raw CLI tools. Trivy, Grype, Semgrep. Free, open-source, and genuinely excellent. But they give you a wall of JSON in a terminal. No dashboard. No history. No way to see what's happening across twenty servers at once. No scheduling. No aggregation.
I spent months looking for something in the middle — a self-hosted, open-source platform that could:
Scan Docker images, Git repositories, and local filesystems
Run agents on multiple machines and aggregate results centrally
Show everything in a proper dashboard with charts, history, and PDF reports
Use token authentication so random actors can't POST fake findings to your server
It didn't exist. So I built it.
Introducing VaultHound
VaultHound is a distributed vulnerability scanning platform built on top of Trivy — the best open-source scanner available. It adds everything Trivy is missing: a master server, intelligent agents, a real-time dark-theme dashboard, and a clean installation experience.
The tagline is simple: Scan. Detect. Protect.
How It Works
The architecture is deliberately simple — a master/agent model that anyone who has used Prometheus, Grafana Agent, or Datadog will instantly recognise.
Client Machines Master Server
┌──────────────────────┐ ┌─────────────────────────┐
│ VaultHound Agent │ HTTPS + Token │ VaultHound Server │
│ (Go binary) │────────────────▶│ (Node.js / Express) │
│ │ POST /api/ │ │
│ • Trivy scans │ ingest │ • Aggregates findings │
│ • Auto-discovers │ │ • Deduplicates scans │
│ containers │ │ • Serves dashboard │
│ • Runs on schedule │ │ • Token auth on ingest │
└──────────────────────┘ └─────────────────────────┘
The Master Server
A Node.js / Express application that does three things:
Receives scan results from agents via
POST /api/ingest— protected by a Bearer tokenStores results with smart deduplication: if the same agent scans the same target again, the result is updated in place rather than creating a new row (so your critical count never artificially inflates)
Serves a self-contained dashboard at port 4000 — a single HTML file with Chart.js, no build step, no npm in production
The Agent
A compiled Go binary (/usr/bin/vaulthound-agent) that wraps Trivy and handles reporting. It reads from /etc/vaulthound/agent.conf and supports:
--dir /var/www/html— filesystem scan (vulns + secrets + misconfigs)--image nginx:latest— Docker image scan (vulns + secrets)--repohttps://github.com/org/repo— Git repository scan (vulns + secrets + misconfigs)--auto— auto-discover every running Docker container and scan its image--daemon— run continuously on a configurable interval (default: 30 minutes)
The agent is intelligent about container scanning. If you pass a container name or ID instead of an image reference, it resolves the actual image via docker inspect before scanning. In --auto mode it deduplicates — if three containers all run nginx:1.24, it only scans the image once.
By default (no --log flag), the agent shows a clean animated progress bar. Pass --log to get full verbose output for debugging. One-shot scans exit cleanly after completing — only --daemon mode keeps running.
The Dashboard
The dashboard is built as a single self-contained HTML file — no React, no build pipeline, no CDN dependencies at runtime. It's served directly by the Node.js server and works on any modern browser.
Overview tab:
8 stat cards: total scans, active agents, critical/high/medium/low findings, secrets exposed, misconfigurations
Severity trend chart with three modes: Daily (hourly breakdown of today), Weekly (Mon–Sun of current week), Monthly (every day in the current month)
Severity breakdown bars
Recent activity table showing the latest scans from all agents
Top vulnerable targets ranked by total findings
Scan History tab:
Full scan list filterable by type (image / filesystem / repo)
View button opens a detail panel with:
Severity filter dropdown (All / Critical / High / Medium / Low)
Full CVE table with package, installed version, fixed version, severity, title
Secrets table with file path and exact line numbers — no hunting through code
Misconfigurations table with ID, type, severity, status
Export to PDF — branded report with VaultHound header, summary boxes, full data tables
Agents tab:
- Every registered agent with hostname, OS, version, last seen time, and scan count
Security Model
Authentication is handled with a shared Bearer token:
# /etc/vaulthound/server.conf (on master)
SERVER_TOKEN=a1b2c3d4e5f6... # 48-char hex, generated at install
# /etc/vaulthound/agent.conf (on each agent)
SERVER_TOKEN=a1b2c3d4e5f6... # must match
Every POST /api/ingest from an agent includes Authorization: Bearer <token>. The master rejects anything without a valid token with 401 Unauthorized. The dashboard API itself is intentionally unauthenticated — it's designed to run inside your network, behind a VPN or firewall.
Both config files are written with mode 640 (readable only by root and the vaulthound service user). The service user has no shell, no home directory, and no sudo access.
Installation in Two Commands
The entire installation is handled by two shell scripts. No Ansible, no Docker Compose, no Kubernetes.
Master Server
git clone https://github.com/krishnabagal/VaultHound.git
cd VaultHound/vaulthound-server
sudo bash install-master.sh
The script detects your OS (Ubuntu/Debian/RHEL/Amazon Linux), installs Node.js 20 via the official NodeSource repo, creates a vaulthound system user, deploys the server to /opt/vaulthound/master/, writes the config with a generated token, installs a systemd service, and opens the firewall port. At the end it prints the SERVER_TOKEN to copy for agent setup.
Agent (on every machine to scan)
cd VaultHound/vaulthound-agent
sudo bash install-agent.sh
The agent installer prompts for the master URL and token, then installs Trivy using the official method for your distribution (apt repo for Debian/Ubuntu, yum repo for RHEL/CentOS, install script fallback for others), downloads and compiles Go 1.22, builds the agent binary, writes the config, and starts the vaulthound-agent systemd service.
Manual scans (no service required)
# Scan and exit
vaulthound-agent --dir /var/www/html
vaulthound-agent --image nginx:latest
vaulthound-agent --repo https://github.com/org/repo
vaulthound-agent --auto # scan all running containers
# Verbose output
vaulthound-agent --dir /app --log
What Gets Scanned
| Target | Vulnerabilities | Secrets | Misconfigurations |
|---|---|---|---|
| Docker image | ✅ | ✅ | — |
| Git repository | ✅ | ✅ | ✅ |
| Local filesystem | ✅ | ✅ | ✅ |
Vulnerabilities — OS packages (Alpine, Ubuntu, Debian, RHEL, Amazon Linux) and language packages (npm, pip, Maven, Gradle, Go modules, Cargo, RubyGems, NuGet, Composer).
Secrets — hardcoded API keys, tokens, passwords, certificates, private keys. Trivy's secret scanner covers AWS, GCP, Azure, GitHub, Slack, Stripe, and hundreds of other patterns.
Misconfigurations — Dockerfile best practices, Kubernetes manifests, Terraform, CloudFormation, ARM templates — anything Trivy's misconfiguration scanner supports.
The Tech Stack
| Component | Technology | Why |
|---|---|---|
| Agent | Go 1.22 | Single static binary, fast, no runtime dependency, easy to install |
| Master server | Node.js 20 + Express | Lightweight, easy to deploy, npm ecosystem for minimal deps |
| Dashboard | Vanilla HTML + Chart.js | No build step, works everywhere, single file to deploy |
| Scanner | Trivy | Best-in-class open-source scanner, actively maintained by Aqua Security |
| Service management | systemd | Universal on modern Linux, proper restart/logging/user isolation |
Who Should Use This
DevOps and Platform Engineers who want a single pane of glass across all their servers without a SaaS subscription
Security Engineers who need continuous scanning without shipping code metadata to third parties
Startups that want professional-grade visibility at zero licensing cost (runs fine on a $5/month VPS)
Regulated industries (finance, healthcare, government) where data must stay on-premises
Developers who want to catch secrets and CVEs before code reaches production
MSPs and consultants who deploy one master per client environment
What's Next
The project is actively developed. The roadmap includes:
PostgreSQL / SQLite persistence (currently in-memory, resets on restart)
Webhook notifications (Slack, Teams, PagerDuty) on new critical findings
Kubernetes DaemonSet deployment for the agent
GitHub Actions integration for CI/CD pipeline scanning
CVE suppression / ignore rules per target
Multi-user authentication for the dashboard
Try It, Star It, Contribute
VaultHound is MIT-licensed, free forever, and open to contributions.
If you've ever stared at a wall of Trivy JSON output wishing you had a proper dashboard — or paid a SaaS vendor just for visibility into your own servers — give VaultHound a try.
GitHub: https://github.com/krishnabagal/VaultHound
Issues, feature requests, and pull requests are all welcome. If VaultHound saves you time or money, a ⭐ on GitHub goes a long way.
Built by Krishna Bagal. Powered by Trivy. Licensed under MIT.

