Architecture overview
PatchBase is composed of a Go backend, a SvelteKit frontend, a PostgreSQL database, and a job queue. This page gives a high-level tour of how the pieces fit together.
Components
┌─────────────────────────────────┐
│ PatchBase Server │
│ ┌──────────┐ ┌───────────────┐ │
Browser ◄──────► │ │ SvelteKit │ │ REST API │ │
│ │ Dashboard │ │ (/api/v1/) │ │
│ └──────────┘ └───────┬───────┘ │
│ ┌──────────────────────┴───────┐ │
│ │ Services Layer │ │
│ │ Hosts · Advisories · Auth │ │
│ │ SSH Pull · Matcher · Queue │ │
│ └───────┬──────────┬──────────┘ │
└──────────┼──────────┼──────────────┘
│ │
┌──────────▼──┐ ┌────▼─────────┐
│ PostgreSQL │ │ River │
│ (data) │ │ (job queue) │
└─────────────┘ └──────────────┘
Agent ◄──────────► POST /api/v1/agent/snapshots
Server (patchbase-server)
The server is a Go binary built with:
- Cobra for CLI commands (
serve,migrate,version) - Viper for configuration (YAML with defaults)
- net/http with Go 1.22+ ServeMux pattern routing
- pgxpool for PostgreSQL connection pooling
- River (pgx-based) for background job queue
- samber/do for dependency injection
- WebSocket for real-time dashboard updates
The server embeds the SvelteKit dashboard as static files. In production, the same binary serves both the API and the frontend — no separate frontend deployment needed.
Service layer
All business logic lives in internal/services/:
- Hosts — registration, approval, snapshot ingestion, SSH pull, manual report parsing
- Advisory sync — manifest fetching, SQLite download, advisory import, scope management
- Matcher — compares host packages against advisory rules (RPM-EVR and Debian version comparison)
- Settings — global SSH key management, email configuration
- Auth — JWT issuance and validation
Job queue
River handles background jobs:
- SSH pull jobs — periodic SSH collection per host
- Advisory sync jobs — periodic advisory database refresh per scope
Jobs are inserted into PostgreSQL (River uses Postgres as its backing store) and workers process them concurrently.
Agent (patchbase-agent)
The agent is a separate static Go binary with no runtime dependencies. It:
- Reads
/etc/os-releaseto detect the OS family - Collects package data using
dpkg-query(APT) orrpm -qa(RPM) - Collects repository data from apt sources or dnf/yum repolist
- Collects system metadata (hostname, machine-id, kernel, uptime)
- Marshals everything into a protobuf
AgentSnapshot - POSTs it to the server's
/api/v1/agent/snapshotsendpoint
The agent is stateless between runs — all configuration comes from /etc/patchbase-agent/config.json.
Advisory database
Advisory data lives in per-scope SQLite databases hosted at dl.patchbase.net. Each scope (e.g., rocky:9, ubuntu:jammy) has its own database containing:
advisories— advisory metadata (ID, severity, description, dates)product_streams— distribution channels (e.g., "Rocky Linux 10.2 BaseOS x86_64")advisory_product_streams— many-to-many link between advisories and streamsadvisory_references— external references (CVEs, vendor URLs)affected_package_rules— conditions for package vulnerabilityfixed_packages— specific package versions that fix the advisory
The server downloads these SQLite files, verifies checksums, and imports the records into PostgreSQL for querying.