heretix-api is the vulnerability database of heretix, a self-hosted suite that tracks CVEs across servers, containers and network appliances (firewalls, VPNs) in one inventory (Apache-2.0).
Ask it "is this software vulnerable?", by package name and version, and it answers from a local copy of public vulnerability data:
GET /api/v1/vulnerabilities/search?package=openssl&version=3.0.2-0ubuntu1.10&ecosystem=Ubuntu:22.04:LTS
→ 46 results, e.g.
CVE-2024-6119 severity HIGH distroPriority medium fixedVersion 3.0.2-0ubuntu1.18 isKev false epssScore 0.67
It works for language packages (npm, PyPI, Go, Maven, ...), Linux distribution packages (Debian, Ubuntu, Alpine, RHEL, ...) and network appliances and commercial products (FortiOS, PAN-OS, Cisco IOS XE, vCenter, ...). Each result says how severe the vulnerability is, whether it is being exploited, and how to fix it.
Where it sits in heretix:
- heretix-cli scans a host or image and asks this API about each package.
- heretix-management keeps the inventory and the findings.
- heretix-api (this repository) imports the public sources on a schedule into its own PostgreSQL database, so searches never call those sources directly.
It can also be used on its own, as a self-hosted vulnerability lookup API.
- Import: scheduled jobs download each source (OSV, NVD, CISA KEV, EPSS, CVE Records, and vendor advisories) into per-source tables.
- Merge: records about the same CVE are linked to one master row, which also carries the exploitation signals (KEV, EPSS, CISA's SSVC assessment).
- Search: a search compares the version you give against each source's affected ranges. It uses that ecosystem's own version rules (semver, dpkg, RPM, vendor-specific), and returns one result per vulnerability.
- Vendor advisories: Fortinet, Palo Alto Networks, Cisco, Sophos, SonicWall, Oracle CPU, Oracle Linux, Red Hat, Broadcom/VMware, Splunk, Apache HTTP Server, Apache Tomcat, nginx, Zabbix, Check Point, Ivanti, NetScaler and Microsoft (Windows Server, beta)
- Distro-aware matching: dpkg and RPM version comparison for Linux distributions, and each distro's own rating (
distroPriority) and fix status (fixStatus, e.g. "will not fix") per result - Malware detection: the malicious-package records (
MAL-*, from ossf/malicious-packages) that OSV carries in itsnpm,PyPI, ... files, searchable like any vulnerability - Simple to run: PostgreSQL only (no Redis), Docker Compose included, a built-in scheduler and an import dashboard
Minimum sizing for a PoC deployment, from the heretix requirements. The figures cover heretix-api and heretix-management together; heretix-api's PostgreSQL accounts for most of them.
| Requirement | |
|---|---|
| CPU | 2 vCPU minimum. The heretix-api container can burst to roughly 70% of one core during imports and searches, and PostgreSQL adds its own load during an import |
| RAM | 8 GB minimum, 16 GB recommended. heretix-api's PostgreSQL uses around 7.7 GB with a full NVD mirror and several OSV ecosystems loaded |
| Disk | 20 GB to start. heretix-api's database can reach around 11 GB after months of NVD and OSV data; budget more to import every OSV ecosystem |
| Software | Docker and Docker Compose v2, and git |
| Network | Outbound access to the public sources (nvd.nist.gov, osv.dev, GitHub, vendor sites) |
To run without Docker (Node.js 22, pnpm, PostgreSQL 15+), see docs/operations.md.
git clone https://github.com/TITeee/heretix-api.git
cd heretix-api
cp .env.example .envEdit .env and set:
API_KEY: a secret string (openssl rand -hex 32). Every API request must send it as thex-api-keyheader.ADMIN_API_KEY: a second secret string, for the dashboard and for running and switching jobs. Keep it to administrators: the clients only needAPI_KEY.POSTGRES_PASSWORD(add the line): the password of the bundled database. Set your own: the default,changeme, is only for a local trial.NVD_API_KEY(optional, recommended): a free NVD key makes the NVD import faster.
With Docker, DATABASE_URL in .env is ignored, because Compose connects the API to its own database.
docker compose up --build -d
docker compose ps # db and app are both up
curl http://localhost:5000/health # → {"status":"ok",...}On first start, the container creates the database schema and then starts the API on port 5000. Logs: docker compose logs -f app.
The database starts empty, and the scheduled jobs only fetch changes. Open the dashboard at http://localhost:5000/dashboard and enter your admin key (ADMIN_API_KEY). Everything is loaded from there; no command is needed:
- NVD (every CVE, ~400k): press Load on the NVD row. It takes several hours; the row shows
running, thencompleted. If it fails part way, Load again carries on from where it stopped. - CISA KEV and EPSS: after NVD completes, press Run. They only annotate CVEs that are already there, and their daily runs keep them current.
- OSV: under OSV Ecosystems, choose each ecosystem you scan (
npm,PyPI,Ubuntu, ... which name?) and press Add and load. That switches its daily job on and loads it in full. - Other sources (vendor advisories, the Debian security tracker
debian-tracker): switch the job On and press Run once. CVE Records (cna, a ~600 MB download) and Microsoft (advisory-microsoft) say Load the first time, like NVD.
The commands (docker compose exec app pnpm import:nvd full, pnpm import:osv ecosystem <name>) still work, for scripts and for loading again from scratch.
Which sources to import: docs/data-sources.md.
export API_KEY=<your key>
curl -H "x-api-key: $API_KEY" \
"http://localhost:5000/api/v1/vulnerabilities/search?package=lodash&version=4.17.20&ecosystem=npm"Results appear as soon as the matching source has been imported.
docker compose down # stop; data is kept (add -v to delete it)
git pull && docker compose up --build -d # update to the latest versionOn start, the container applies any new database migrations and data backfills before the API answers. A backfill can take several minutes on a full database.
Every endpoint except /health and the /dashboard page requires the x-api-key header.
# Distro package
curl -H "x-api-key: $API_KEY" \
"http://localhost:5000/api/v1/vulnerabilities/search?package=bzip2-libs&version=1.0.8-8.el9&ecosystem=Red%20Hat:9"
# Network appliance (vendor advisory)
curl -H "x-api-key: $API_KEY" \
"http://localhost:5000/api/v1/vulnerabilities/search?package=FortiOS&version=7.4.3"
# By ID
curl -H "x-api-key: $API_KEY" "http://localhost:5000/api/v1/vulnerabilities/CVE-2021-44228"The ecosystem parameter changes which sources are queried and how versions are compared. Read Search behavior by ecosystem before assuming a search returned everything.
| Endpoint | Purpose |
|---|---|
GET /api/v1/vulnerabilities/search |
Vulnerabilities affecting a package and version |
POST /api/v1/vulnerabilities/search/batch |
The same for up to 1,000 packages |
GET /api/v1/vulnerabilities/search/cpe |
Search by CPE 2.3 string (NVD) |
GET /api/v1/vulnerabilities/suggest |
Package name autocomplete |
GET /api/v1/catalog |
Product catalog for a picker |
GET /api/v1/vulnerabilities/:id |
Detail by CVE, OSV or vendor advisory ID |
GET /api/v1/vulnerabilities/stats |
Record counts |
POST /api/v1/jobs/:source/run, PATCH /api/v1/jobs/:source |
Run or enable/disable an import job |
Full reference, including every response field: docs/api.md.
Searches for these releases are covered by accuracy checks and fixes:
| Distro | Releases |
|---|---|
| Debian | 11, 12, 13, 14 |
| Ubuntu | 20.04, 22.04, 24.04, 26.04 LTS |
| Alpine | v3.21 to v3.24 |
| AlmaLinux / Rocky Linux | 8, 9, 10 |
| Red Hat Enterprise Linux | 8, 9, 10 |
| Windows Server (beta) | 2016, 2019, 2022, 2025 (desktop and Server Core) |
Windows Server is in beta: it has been checked against only a few real servers, and it is searched by its full OS build, not by release. Windows 10 and 11 are not covered.
Other releases are not deleted: they stay searchable on a best-effort basis, without those checks. Oracle Linux is best-effort too. Language ecosystems (npm, PyPI, ...) are not affected. The reasons, the notes per distro and how the list is kept are in docs/data-sources.md.
http://localhost:5000/dashboard shows each source's import status and record count. Each source row has three buttons, one column each: Schedule (On/Off) switches the daily scheduled run; Run now runs it once (the changes since the last run, or the first load, where the button says Load); Full reload reads everything again and writes over what is stored, after a confirmation. Use it when how records are read has changed and the stored ones should follow (for example after an upgrade that reads more of the CVE Records); nothing is deleted first, so searches keep working meanwhile. The page opens on a sign-in screen: enter your admin key (ADMIN_API_KEY) to see the data. The key is kept for the open tab only; Sign out forgets it.
Only NVD, KEV and EPSS run by default; switch on the others you need.
| Source | What it provides | Schedule (UTC) |
|---|---|---|
| NVD | Every CVE, CPE ranges, CVSS | Every 2 hours |
| CISA KEV | Known-exploited flag | Daily 09:00 |
| EPSS | Exploitation probability | Daily 10:00 |
| OSV | Language ecosystems, Linux distributions, malware | Daily 08:00, one job per ecosystem |
| CVE Records (CNA) | CNA-declared affected products, CISA SSVC | Daily 15:30 |
| Red Hat | OVAL (RHEL 8/9) and CSAF VEX (unfixed CVEs; all of RHEL 10) | Daily 13:15 – 15:00 |
| Debian security tracker | Fix status (no-dsa, ignored, ...) |
Daily 07:15 |
| Vendor advisories | Fortinet, PAN, Cisco, Oracle, Broadcom, ... | Daily 11:00 – 16:00 |
Per-source details, import commands and limitations: docs/data-sources.md.
| Document | Contents |
|---|---|
| docs/api.md | API reference and search behavior |
| docs/data-sources.md | Each data source: how it is imported, commands, caveats |
| docs/operations.md | Setup, environment variables, scheduler, backfills, troubleshooting |
| docs/tls-proxy.md | Serving the API over HTTPS: reverse proxy, HSTS, TRUST_PROXY, database password |
| docs/architecture.md | Data model, deduplication, version matching |
| docs/known-issues.md | Current limitations |
| ACCURACY.md | Precision / recall measurements against official advisories |
| docs/detection-comparison-rhel9.md | One RHEL 9.8 host scanned with heretix-api and Trivy, every difference checked against Red Hat's VEX data |
| docs/detection-comparison-debian13.md | One Debian 13 host scanned with heretix-api and Trivy, every difference checked against the Debian security tracker and OSV |
| docs/detection-comparison-ubuntu2404.md | One Ubuntu 24.04 host scanned with heretix-api and Trivy, every difference checked against the Ubuntu CVE Tracker statuses, OSV and the host's upgradable packages |
| docs/detection-comparison-alpine321.md | One Alpine 3.21 container image scanned with heretix-api and Trivy, every difference checked against OSV, Alpine's security database and NVD |
| CONTRIBUTING.md | Development, tests, adding a vendor |
Apache License 2.0. See LICENSE for details.
