VulnForge
Container security insights for your homelab
What is VulnForge?
VulnForge is a self-hosted dashboard that keeps homelab operators on top of container security. It combines Trivy scanning, a native compliance checker, Dockle linting, and Dive layer analysis to surface vulnerabilities, configuration drift, and image hygiene issues in one place -- all without relying on external SaaS services.
The project focuses on reliability and clarity for home environments: simple deployment, a lightweight SQLite datastore, multi-service notifications (ntfy, Gotify, Pushover, Slack, Discord, Telegram, Email), offline-friendly scanners, and tooling that explains what to fix next. Whether you are running a single-node lab or a rack of services, VulnForge turns nightly scans into actionable chores instead of noisy reports.
Technology Stack
Backend
- → Python 3.14 + FastAPI + Granian ASGI server
- → SQLAlchemy 2.x + aiosqlite with WAL mode
- → Docker SDK, APScheduler, and Pydantic 2.x
- → Trivy, Docker Bench, Dockle, Dive integrations
- → Typed response_model schemas on all endpoints with standardized error responses
- → Multi-service notifications and CISA KEV enrichment
Frontend
- → React 19 + TypeScript 6 with Vite 8
- → TanStack Query for server state and caching
- → React Router v7 single-page navigation
- → Tailwind CSS 4 + Zod 4 schema validation
- → OpenAPI-generated TypeScript types with CI freshness gate
- → Recharts, Lucide icons, and Sonner toasts
Project Statistics
Version History
Track the evolution of VulnForge through its version releases. Each release includes new features, improvements, and bug fixes.
v4.6.1 2026-04-13
📝 Dev Dependencies
- • **@typescript-eslint/eslint-plugin**: 8.58.0 → 8.58.2
- • **@typescript-eslint/parser**: 8.58.0 → 8.58.2
- • **@vitest/coverage-v8**: 4.1.2 → 4.1.4
- • **@vitest/ui**: 4.1.2 → 4.1.4
- • **autoprefixer**: 10.4.27 → 10.5.0
- • **globals**: 17.4.0 → 17.5.0
- • **jsdom**: 29.0.1 → 29.0.2
- • **postcss**: 8.5.8 → 8.5.9
- • **pyright**: 1.1.400 → 1.1.408
- • **pytest**: 9.0.2 → 9.0.3
- • **typescript-eslint**: 8.58.0 → 8.58.2
- • **vite**: 8.0.3 → 8.0.8
- • **vitest**: 4.1.2 → 4.1.4
📝 App Dependencies
- • **@tanstack/react-query**: 5.96.2 → 5.99.0
- • **authlib**: 1.6.9 → 1.6.10
- • **cryptography**: 46.0.6 → 46.0.7
- • **lucide-react**: 1.7.0 → 1.8.0
- • **pydantic**: 2.12.5 → 2.13.0
- • **python-multipart**: 0.0.22 → 0.0.26
- • **react**: 19.2.4 → 19.2.5
- • **react-dom**: 19.2.4 → 19.2.5
- • **react-router-dom**: 7.14.0 → 7.14.1
📝 Dockerfile Dependencies
- • **oven/bun**: 1.3.11-alpine → 1.3.12-alpine
📝 HTTP Servers
- • **granian**: 2.7.2 → 2.7.3
v4.6.0 2026-04-05
📝 Dev Dependencies
- • **@playwright/test**: 1.58.2 → 1.59.1
- • **@typescript-eslint/eslint-plugin**: 8.57.1 → 8.58.0
- • **@typescript-eslint/parser**: 8.57.1 → 8.58.0
- • **@vitest/coverage-v8**: 4.1.0 → 4.1.2
- • **@vitest/ui**: 4.1.0 → 4.1.2
- • **eslint**: 10.1.0 → 10.2.0
- • **ruff**: 0.15.7 → 0.15.9
- • **typescript**: 5.9.3 → 6.0.2
- • **typescript-eslint**: 8.57.1 → 8.58.0
- • **vite**: 8.0.1 → 8.0.3
- • **vitest**: 4.1.0 → 4.1.2
📝 App Dependencies
- • **@tanstack/react-query**: 5.94.5 → 5.96.2
- • **fastapi**: 0.135.1 → 0.135.3
- • **lucide-react**: 0.577.0 → 1.7.0
- • **react-router-dom**: 7.13.1 → 7.14.0
- • **recharts**: 3.8.0 → 3.8.1
- • **requests**: 2.33.0 → 2.33.1
- • **sqlalchemy**: 2.0.48 → 2.0.49
🔒 Security
- • Add bootstrap token for first-run setup protection (prevents unauthenticated admin takeover)
- • Add `require_admin` defense-in-depth to 23 unguarded API endpoints
- • Add login rate limiting (5/minute) and fix dead-code limiter in scan endpoints
- • Add JWT session versioning (`sv` claim) with invalidation on password change
- • Add in-memory token denylist for immediate logout revocation
- • Reject pre-upgrade JWTs (missing `sv` claim) on deploy
- • Add `public_base_url` setting for OIDC redirects (falls back to X-Forwarded-* headers if unset)
- • Remove unauthenticated widget endpoint bypass (CWE-200 information disclosure)
- • Add pagination upper bounds to 11 endpoints to prevent memory exhaustion
- • Parameterize migration 010 SQL to eliminate string interpolation
- • Pin Python base image to `python:3.14.0-slim`
v4.5.0 2026-03-21
✨ Added
- • Typed `response_model` schemas on all API endpoints — zero untyped dict returns remain
- • OpenAPI-generated TypeScript types via openapi-typescript with `check:api-freshness` CI gate
- • VulnerabilityStatusService for orchestrated status changes with container count resync
- • Shared `NON_ACTIONABLE_STATUSES` constant for consistent vulnerability filtering
- • Frontend risk-based tests: SSE scan status hook, vulnerability mutations, compliance flows (173 frontend tests)
- • Backend characterization tests for ScanResultProcessor and count consistency (740 backend tests)
🔄 Changed
- • Extract compliance and image compliance scan logic from routes to services
- • Extract scan result persistence from ScanQueue to ScanResultProcessor
- • Extract container schema builders and Trivy result parser to standalone modules
- • Deduplicate ActivityLogger internals with shared builder (724 → 409 lines)
- • Replace 32 useState calls in NotificationsTab with useSettingsForm hook
- • Classify settings mutability per-key; write endpoints return restart_required flag
- • Document single-worker/process-local architecture contract
- • Standardize all error responses via global HTTPException handler (detail, status_code, error_type, is_retryable)
🐛 Fixed
- • Vulnerability counts now exclude both `false_positive` and `accepted` statuses consistently
- • Widget cache invalidated on vulnerability status changes, not just scan completion
- • VulnerabilitySummary schema includes notes and description fields
- • Null vs undefined mismatches exposed by strict generated types
🔒 Security
- • Bump flatted to resolve prototype pollution vulnerability
🗑️ Removed
- • Deprecated `perform_scan()` route handler (170 lines of dead code)
- • Phantom `redacted` field from Secret type (never existed in API)
📝 Dev Dependencies
- • **@tailwindcss/vite**: 4.2.1 → 4.2.2
- • **eslint**: 10.0.3 → 10.1.0
- • **jsdom**: 29.0.0 → 29.0.1
- • **pytest-cov**: 7.0.0 → 7.1.0
- • **ruff**: 0.15.6 → 0.15.7
- • **tailwindcss**: 4.2.1 → 4.2.2
- • **vite**: 8.0.0 → 8.0.1
📝 App Dependencies
- • **@tanstack/react-query**: 5.90.21 → 5.94.5
- • **croniter**: 6.0.0 → 6.2.2
v4.4.1 2026-03-17
🔄 Changed
- • Decompose scan pipeline `_process_scan` into 4 discrete stages with documented commit boundaries
- • Split monolithic `api.ts` (1140 lines) into modular type and API client files (21 modules)
- • Migrate direct API calls to React Query hooks in About, ContainerDetail, ApiKeysCard, DatabaseBackupSection
- • Add TTL cache, typed batch getters, and declarative validation to SettingsManager
- • Add provider caching, circuit breaker, and exponential backoff to notification dispatcher
- • Document repository transaction convention (flush vs commit) across all repositories
🗑️ Removed
- • Dead header-based auth system (19 settings keys, routes/auth.py, frontend schemas)
- • Legacy ntfy-only notifier (`notifier.py`) — replaced by multi-service dispatcher
- • Legacy notification settings (`notify_on_scan_complete`, `notify_on_critical`, thresholds)
- • Dead frontend code: `authApi`, `userAuth:401` listener, auth Zod validators
🐛 Fixed
- • Auth middleware now respects `user_auth_mode=none`, allowing open access on fresh installs without requiring setup first (fixes #28)
- • Missing `theme` entry in `DEFAULT_CATEGORIES` (was falling back to 'general' instead of 'ui')
- • Deprecated `send_to_ntfy` field in notification rule schemas (API contract preserved)
- • Marked `ScanResultRepository` as deprecated (test-only, no production consumers)
✨ Added
- • Frontend test infrastructure: `test-utils.tsx`, `test-factories.ts`
- • Tests for SettingsContext, useVulnForge hooks, Dashboard page (110 -> 134 tests)
📝 Dev Dependencies
- • **@typescript-eslint/eslint-plugin**: 8.56.1 → 8.57.0
- • **@typescript-eslint/parser**: 8.56.1 → 8.57.0
- • **@vitejs/plugin-react-swc**: 4.2.3 → 4.3.0
- • **@vitest/coverage-v8**: 4.0.18 → 4.1.0
- • **@vitest/ui**: 4.0.18 → 4.1.0
- • **ruff**: 0.15.5 → 0.15.6
- • **typescript-eslint**: 8.56.1 → 8.57.0
- • **vite**: 7.3.1 → 8.0.0
- • **vitest**: 4.0.18 → 4.1.0
📝 App Dependencies
- • **pyjwt**: 2.11.0 → 2.12.1
v4.4.0 2026-03-09
📝 Dev Dependencies
- • **eslint**: 10.0.2 → 10.0.3
- • **globals**: 17.3.0 → 17.4.0
- • **postcss**: 8.5.6 → 8.5.8
- • **ruff**: 0.15.4 → 0.15.5
📝 App Dependencies
- • **authlib**: 1.6.8 → 1.6.9
- • **fastapi**: 0.133.1 → 0.135.1
- • **lucide-react**: 0.575.0 → 0.577.0
- • **python-dotenv**: 1.2.1 → 1.2.2
- • **recharts**: 3.7.0 → 3.8.0
- • **sqlalchemy**: 2.0.47 → 2.0.48
🔄 Changed
- • Secrets page redesigned: compact two-column card layout, container name shown on each secret, summary stat cards removed
- • Select All moved from bottom of page into the filter bar
- • Status filters (Active, False Positives, Accepted Risks, All) now server-side instead of client-side
🐛 Fixed
- • Navigation bar overflowing on mobile/tablet; desktop nav now uses icons-only below 1280px with bottom nav only on phones (<768px)
- • Batch scan counter accumulating across consecutive scan-all runs instead of resetting
- • Trivy scanning now uses client/server mode for faster scans
- • Secret counts accumulating across scans instead of showing only latest completed scan per container
- • Status filter for False Positives and Accepted Risks returning empty results (backend was excluding them)
- • Active secrets filter now correctly excludes both false positives and accepted risks
v4.3.0 2026-02-26
📝 Dev Dependencies
- • **@tailwindcss/vite**: 4.1.18 → 4.2.1
- • **@typescript-eslint/eslint-plugin**: 8.55.0 → 8.56.1
- • **@typescript-eslint/parser**: 8.55.0 → 8.56.1
- • **autoprefixer**: 10.4.24 → 10.4.27
- • **eslint**: 10.0.0 → 10.0.2
- • **eslint-plugin-react-refresh**: 0.5.0 → 0.5.2
- • **jsdom**: 28.0.0 → 28.1.0
- • **ruff**: 0.15.1 → 0.15.4
- • **tailwindcss**: 4.1.18 → 4.2.1
- • **typescript-eslint**: 8.55.0 → 8.56.1
📝 App Dependencies
- • **fastapi**: 0.129.0 → 0.133.1
- • **lucide-react**: 0.564.0 → 0.575.0
- • **pydantic-settings**: 2.12.0 → 2.13.1
- • **react-router-dom**: 7.13.0 → 7.13.1
- • **sqlalchemy**: 2.0.46 → 2.0.47
- • **tailwind-merge**: 3.4.0 → 3.5.0
📝 Dockerfile Dependencies
- • **oven/bun**: 1.3.9-alpine → 1.3.10-alpine
📝 HTTP Servers
- • **granian**: 2.7.1 → 2.7.2
🔒 Security
- • Redact raw Trivy output in error logs (Match/Content JSON keys, 7 logging sites)
- • Defensive redaction at API/export boundaries for secret match values
- • Redact sensitive ENV/ARG assignments in misconfig code snippets
🔄 Changed
- • Redesigned About page: hero, Why VulnForge section, Learn More links, refreshed Built with AI attribution
🐛 Fixed
- • Notification event toggles were non-interactive (clicks on the visible track had no effect due to missing input overlay)
- • Advanced retry settings (attempts, delay) were never saved — missing state and auto-save payload entries
- • False positive key too broad — added `start_line` for precise matching (NULL = wildcard for legacy)
- • Secret status accepted arbitrary strings — now validated against enum
- • Audit log hardcoded `old_status="active"` — now captures actual prior status
- • Severity sort was lexicographic — now uses CRITICAL > HIGH > MEDIUM > LOW ordering
- • Bulk status update did N queries — replaced with single `WHERE id IN (...)` query
✨ Added
- • FP pattern deletion unsuppresses affected secrets (with overlap guard)
- • Audit logging for FP pattern deletion with unsuppress count
- • Migration 009: FP table rebuild for `start_line` column + invalid status cleanup
v4.2.1 2026-02-14
📝 Dev Dependencies
- • **@eslint/js**: 9.39.2 → 10.0.1
- • **@types/react**: 19.2.10 → 19.2.14
- • **@typescript-eslint/eslint-plugin**: 8.54.0 → 8.55.0
- • **@typescript-eslint/parser**: 8.54.0 → 8.55.0
- • **@vitejs/plugin-react-swc**: 4.2.2 → 4.2.3
- • **eslint**: 9.39.2 → 10.0.0
- • **jsdom**: 27.4.0 → 28.0.0
- • **ruff**: 0.15.0 → 0.15.1
- • **typescript-eslint**: 8.54.0 → 8.55.0
📝 App Dependencies
- • **@tanstack/react-query**: 5.90.20 → 5.90.21
- • **authlib**: 1.6.6 → 1.6.8
- • **fastapi**: 0.128.2 → 0.129.0
- • **lucide-react**: 0.563.0 → 0.564.0
📝 Dockerfile Dependencies
- • **oven/bun**: 1.3.8-alpine → 1.3.9-alpine
📝 HTTP Servers
- • **granian**: 2.7.0 → 2.7.1
✨ Added
- • **ScanOrchestrator Service** — Extracts the two-phase commit pattern (create ScanJob → commit → enqueue) into a reusable service used by both the API and scheduler
- • **GET /api/v1/containers/by-image** — Image-based container lookup with registry-agnostic matching for TideWatch integration
- • **GET /api/v1/containers/by-name/{name}** — O(1) container lookup by name
- • **GET /api/v1/scans/jobs/{job_id}** — Poll scan job status and retrieve linked scan_id on completion
- • **Scan Correlation Tracking** — New `scan_jobs` table links API-triggered scan requests to completed scans via job IDs
- • **`scan_id` filter on GET /api/v1/scans/cve-delta** — Deterministic CVE delta retrieval instead of relying on time windows
- • **ScanJob Retention Cleanup** — Automatically deletes completed/failed jobs older than 30 days and marks orphaned queued jobs as failed
- • **37 new tests** covering scan orchestrator, container by-image endpoints, and regression scenarios
🔄 Changed
- • **Scheduler uses ScanOrchestrator** — All scheduled scans now go through the priority queue with ScanJob tracking, CVE delta, and batch notifications
- • **Additive batch registration** — Overlapping scheduler + API batches no longer destroy each other's notification counters
- • **POST /api/v1/scans/scan** — Now returns `job_ids` array; refactored to use ScanOrchestrator
- • **Queue worker links ScanJob to Scan** — Includes retry with backoff for WAL checkpoint delay edge cases
🐛 Fixed
- • **`scan_id` + `since_hours` filter collision** — Time window is now skipped when `scan_id` is provided
- • **Orphan ScanJob rows** — Failed enqueue operations now immediately mark the job as failed
📝 Deprecated
- • **`perform_scan()`** — Legacy scan function; no callers remain after scheduler refactor
🗑️ Removed
- • **`run_scans_sequentially()` dead code** from scans.py
v4.2.0 2026-02-08
✨ Added
- • **System Info Endpoint** — `/api/v1/system/info` returns app name and version dynamically
- • **Frontend Unit Tests** — 110 new tests covering API client, utilities, error handling, and shared components
- • **Backend Tests** — 122 new tests covering API keys, scan queue, OIDC, dispatcher, scanner health, and Docker Bench
- • **Playwright E2E Tests** — 17 end-to-end tests covering auth, dashboard, navigation, settings, containers, and compliance
- • **CI Quality Gates** — Comprehensive pipeline with ruff lint/format, pyright type checking, pytest + Codecov, frontend coverage, and E2E with Playwright artifacts
- • **Shared Components** — Toggle switch, TestConnectionButton, and ContainerCard extracted as reusable components
- • **Typed Notification Settings** — Replaced `Record<string, unknown>` with proper `NotificationSettings` interface across all notification components
- • **API Client Namespaces** — Consolidated all `fetch()` calls into typed `api.ts` with compliance, image compliance, maintenance, and secrets namespaces
- • **Auto-Save Hook** — Debounced auto-save with initialization guard and payload diffing
🔄 Changed
- • **Settings Page Decomposed** — Extracted into 5 tab components (System, Scanning, Notifications, Security, Data), each with scoped state and auto-save
- • **Compliance Page Decomposed** — Extracted into 7 sub-components (ScanProgress, ScoreCard, CategoryBreakdown, TrendChart, FindingsFilters, FindingsTable, IgnoreModal)
- • **Containers Page** — Extracted ContainerCard component for cleaner rendering
- • **scan_queue._process_scan() Decomposed** — Extracted vulnerability storage, secret detection, Dive analysis, and logging into focused helper methods
- • **Version Sourcing** — Switched from `tomllib` to `importlib.metadata.version()` to fix crash in Docker/installed environments
- • **Migration 006 Fixed** — Replaced synchronous `create_engine` with async `upgrade(connection)` pattern
- • **Pyright Clean** — Resolved all 193 errors at `standard` mode (0 remaining)
- • **Image Compliance Summary API** — Fixed field names to match frontend interface expectations
- • **Dependency floors bumped** — Updated fastapi, granian, sqlalchemy, httpx, apscheduler, and other backend dependencies to latest stable versions
- • **Bun** — Updated to 1.3.8-alpine in both Dockerfile and CI
🐛 Fixed
- • **Image Security Dashboard** — Critical and Failures tiles were showing empty due to mismatched field names between backend and frontend
- • **VulnerabilityCharts** — Wrong field names for compliance data (pre-existing bug)
- • **Duplicate formatRelativeTime** — Consolidated to shared utility
- • **Dead computation in scan_queue** — Removed unused fixable_count aggregation
- • **ESLint/Vite conflicts** — Fixed coverage directory and cache permission issues
🗑️ Removed
- • Dead legacy migration code from database.py (~150 lines)
- • Duplicate vulnerability building logic in containers.py (extracted to shared helpers)
- • Inline toggle CSS replaced by Toggle component
- • Redundant Loader2 imports replaced by TestConnectionButton
🔒 Security
- • **CodeQL Remediation** — Resolved 48 CodeQL security alerts (16 false positives dismissed with justification) → Log injection prevention across backend logging calls → Path injection hardening for directory-listing lookup → Stack trace exposure fixes (generic messages to users, details in logs only) → SSRF validation strengthening → Clear-text logging remediation
v4.1.0 2025-01-27
✨ Added
- • **Native Compliance Checker** — Replaced Docker Bench with a Python-based compliance checker that runs directly via Docker API → 20 homelab-relevant checks across 4 categories: Daemon Configuration, Container Runtime, Image Security, Host Configuration → Built-in remediation guidance with copy-paste snippets → Per-container findings with actual/expected values → ~0.4 second scan time (vs Docker Bench container overhead)
- • **Grouped Compliance Findings View** — Aggregates findings by check ID with expandable rows showing per-container results, reducing 400+ rows to ~20 grouped checks
🔄 Changed
- • **Compliance Page** — Updated to use native checker with grouped view; tab renamed from "Docker Bench" to "VulnForge Checker"
- • **Dependencies** — Bumped oven/bun, react, react-dom, typescript-eslint, and globals to latest versions
🗑️ Removed
- • **Docker Bench dependency** — No longer requires `docker-bench-security` container; native checker provides equivalent functionality with better performance
v4.0.1 2025-12-25
🔄 Changed
- • **Single-User Model Clarification** — Removed vestigial multi-user RBAC references (unused `groups` field, related settings, and documentation). No functional changes.
v4.0.0 2025-12-22
✨ Added
- • **User Authentication System** — Single-user model with admin account → Local authentication (username/password with Argon2id hashing) → OIDC/SSO authentication (Authentik integration via OAuth2 authorization code flow) → JWT session management (httpOnly cookies, 24-hour expiry) → Auto-migration system, protected routes, setup page, login page, profile management → Security features: CSRF protection, SSRF prevention, nonce validation
- • **Backend Test Coverage** — 116 new tests across image compliance, notifications, Trivy misconfiguration, Docker client, KEV service, and notifier modules (489 → 605 total)
🔄 Changed
- • **API Authentication Simplified** — Replaced complex multi-provider system (Authentik ForwardAuth, Custom Headers, Basic Auth) with database-backed API keys using `vf_` prefix and SHA256 hashing
- • **Authentication Architecture** — Separated user auth (JWT cookies for browsers) from API auth (ForwardAuth + API keys for integrations)
- • **Settings UI** — Refactored to TideWatch-style user profile with action button grid and self-contained modals
- • **Settings Security Tab** — Replaced 4-provider auth card with clean API Keys manager (generate/list/revoke)
- • **Test Infrastructure** — Fixed fixtures, migrated to Pydantic V2 ConfigDict, updated datetime calls for Python 3.13+
🐛 Fixed
- • **Critical SQL Query Bug** — Fixed ignored findings filter in Image Compliance API that was filtering out all non-ignored findings
- • **Settings Auto-Save Race Condition** — Fixed spurious save on initial page load due to initialization timing
- • **SPA Routing** — Fixed catch-all route intercepting API endpoints
- • **Test Warnings** — Eliminated all 56 test suite warnings (Pydantic V2, datetime deprecation, unawaited coroutines)
🔒 Security
- • **Password Security** — Argon2id hashing (time_cost=2, memory_cost=102400, parallelism=8)
- • **JWT Security** — HS256 with 256-bit secret, httpOnly + SameSite=Lax cookies
- • **CSRF/SSRF/Nonce Protection** — State tokens with 10-minute TTL, private IP blocking, ID token replay prevention
- • **CodeQL Improvements** — 53% reduction in security warnings (119 → 56) with log injection prevention, path traversal protection, and stack trace exposure fixes
v3.3.0 2025-11-28
✨ Added
- • **Multi-Service Notification System** — Expanded from ntfy-only to 7 services: ntfy, Gotify, Pushover, Slack, Discord, Telegram, and Email (SMTP)
- • **Notification Dispatcher** — Centralized event routing with priority-based retry logic and service-specific delay multipliers
- • **Frontend Notification UI** — Per-service configuration forms with test buttons and event notification toggles organized by category
🔄 Changed
- • **Notification Architecture** — Migrated from single NtfyService to NotificationDispatcher with backward-compatible settings migration
v3.2.0 2025-11-26
✨ Added
- • **Frontend Error Handling** — New `errorHandler.ts` utilities, typed `ApiError` class, and enhanced ErrorBoundary with dev/prod mode, copy-to-clipboard error reports, and retryable indicators
- • **Zod Validation Schemas** — Reusable validators for settings with safe integer parsing
🔄 Changed
- • **Error Handling Standardization** — Replaced generic `except Exception` handlers with specific exception types across all API endpoints; structured error responses with `detail`, `suggestions`, and `is_retryable` fields
🐛 Fixed
- • **Safe Integer Parsing in Settings** — Replaced 12 unsafe `parseInt()` calls with `parseSettingInt()` to prevent NaN values in numeric settings fields
v3.1.0 2025-11-26
✨ Added
- • **Light/Dark Theme Support** — Theme context with dual persistence (localStorage + backend API), FOUC prevention, and Tailwind v4 CSS custom properties
- • **CVE Delta Tracking** — New `cves_fixed` and `cves_introduced` columns with automatic delta calculation and `GET /api/v1/scans/cve-delta` endpoint for TideWatch integration
🔄 Changed
- • **Larger Header & Navigation** — Improved visual hierarchy with larger title, nav tabs, and shield icon
- • **Standardized Button Colors** — All primary buttons now use consistent blue theme
- • **Docker Connection** — Simplified to use `DOCKER_HOST` environment variable; removed Docker Connection card from Settings
🐛 Fixed
- • **Light Mode Visibility** — Fixed hardcoded `text-white` throughout UI with proper theme-aware colors
🗑️ Removed
- • Docker Socket Proxy setting from Settings Manager defaults
v3.0.0 2025-11-15
🔄 Changed
- • **Granian ASGI Server** — Migrated from uvicorn to Granian for ~15-20% memory reduction and better async handling
- • **Tailwind CSS v4** — Migrated from v3 with CSS-based `@theme` directive replacing JavaScript config
- • **Python 3.14** — Updated to latest Python release
- • **React 19.2** — Updated to latest React with concurrent features
- • **Backend/Frontend Dependencies** — Bumped all dependencies to latest stable versions
⚡ Performance
- • **79% reduction in initial bundle size** (885 KB → 187 KB) through route-based code splitting, vendor chunking, and memoization
- • **70% reduction in network requests** via React Query staleTime configuration
- • **60% faster Time to Interactive** (2.5s → <1s)
- • Sub-5ms health check response times with 159 MiB average memory footprint
v2.7.0 2025-11-12
✨ Added
- • **CHANGELOG.md** — Version history tracking in Keep a Changelog format
- • **README.md** — Project documentation with quick start guide
🔄 Changed
- • **Trivy-Only Scanning** — Simplified vulnerability scanning by removing redundant Grype scanner; faster scan times and cleaner codebase
🗑️ Removed
- • **Grype vulnerability scanner** — Provided 100% overlapping functionality with Trivy; all related services, endpoints, UI components, and consensus logic removed
🐛 Fixed
- • **Frontend build script** — Removed `tsc &&` prefix that was blocking CI/CD builds
v2.6.0 2025-11-XX
Key Features
● Scanning & Detection
- → Trivy vulnerability scanning with CISA KEV tagging, CVSS scoring, and per-container history
- → Secret detection workflow with false-positive pattern management, automatic unsuppression, and accepted-risk tracking
- → Security-hardened output with Trivy match redaction, API boundary sanitization, and ENV/ARG scrubbing
- → Real-time SSE scan progress, retry controls, and classified error guidance for every job
● Compliance & Image Hygiene
- → Docker Bench scheduling with weekly reports, CSV export, and historical trend charts
- → Dockle image compliance dashboard with on-demand scans and remediation tips
- → Dive integration for layer efficiency analysis and wasted-byte insights per image
● Automation for Homelabs
- → Cron-style scheduling, automatic container discovery, and image batch scanning
- → Multi-service notifications (ntfy, Gotify, Pushover, Slack, Discord, Telegram, Email) with priority-based routing
- → Offline resilience with cached scanner databases and intelligent fallbacks
● Authentication & Hardening
- → Bootstrap token for first-run setup protection and defense-in-depth admin guards on all endpoints
- → JWT session versioning with immediate invalidation on password change and in-memory token denylist
- → Login rate limiting, pagination upper bounds, and parameterized migration SQL
- → OIDC integration via Authentik with configurable public base URL for redirect handling
● Data & Workflow
- → SQLite WAL persistence with backup/restore, download, and safety snapshots
- → CSV exports, drill-down findings, and timeline of homelab activity
- → Responsive dashboard widgets tuned for desktop dashboards and tablet control rooms
Dashboard & Insights
Visual Analytics
7 interactive Recharts including severity distribution, fixable vs non-fixable comparison, top vulnerable containers, and scan & remediation trends
Remediation Groups
Package-based grouping showing which updates fix multiple CVEs with impact visualization and severity breakdowns
Real-time Progress
Live streaming scan updates over Server-Sent Events with container-level feedback and auto-refresh when scans complete
Homepage Widgets
Four API endpoints for Homepage dashboard integration: summary, critical focus, top containers, and remediation actions
Use Cases
Vulnerability Management
Scan 50-60+ Docker containers, prioritize fixable vulnerabilities, and track remediation progress with historical trends
Compliance Monitoring
Weekly Docker Bench reports for CIS benchmark compliance with pass/fail breakdowns and Dockle image hygiene checks
Automated Scanning
Cron-based scheduled scans with multi-service notifications, container discovery, and intelligent retry controls for failed jobs
Secret Detection
Identify exposed secrets in containers with triage workflow for false positives and accepted-risk tracking
Screenshots
Dashboard
At-a-glance security posture with severity breakdown, scan trends, KEV alerts, and remediation priorities.
Containers
All running containers with vulnerability counts, last scan time, and quick-scan controls.
Container Overview
Individual container detail with image info, vulnerability summary, and navigation to detailed findings.
Container Vulnerabilities
Detailed CVE listing with severity, CVSS scores, fix versions, and KEV tagging for exploited vulnerabilities.
Scan History
Historical scan results with trend visualization showing vulnerability counts over time.
Secret Detection
Exposed secrets found in container images with triage workflow for false positives and accepted risks.
Docker Bench Compliance
CIS Docker Benchmark compliance checks with pass/fail breakdown and historical trends.