A Query.Farm VGI worker for DuckDB.
vgi-cve · a Query.Farm VGI worker
A VGI worker, written in Go, that looks up CVE / vulnerability data from the NVD 2.0 API and computes CVSS v3.1 scores — all exposed as DuckDB/SQL functions. It is a defensive vulnerability-management tool.
Built on the vgi-go SDK; speaks the
VGI protocol over stdio. Catalog name: cve.
INSTALL vgi FROM community; LOAD vgi;
-- LOCATION is the path to the compiled worker binary.
ATTACH 'cve' AS cve (TYPE vgi, LOCATION '/path/to/vgi-cve-worker');
-- Offline CVSS math (no network):
SELECT cve.cvss_base_score('CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H'); -- 9.8
SELECT cve.cvss_severity(9.8); -- CRITICAL
-- Look up a CVE from the NVD API:
SELECT id, cvss_score, cvss_severity, cwe FROM cve.cve('CVE-2021-44228');
-- Keyword search (paginated, bounded to 100 results):
SELECT id, cvss_severity, published FROM cve.cve_search('log4j');
-- CVEs affecting a CPE name:
SELECT cve_id, cvss_score, cvss_severity
FROM cve.cpe_cves('cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*');There are two families: offline scalars (pure CVSS math, no network, deterministic) and table functions (live NVD 2.0 API lookups).
| Function | Returns | Description |
|---|---|---|
cvss_severity(score DOUBLE) |
VARCHAR |
Map a base score to NONE/LOW/MEDIUM/HIGH/CRITICAL per the CVSS v3 bands. |
cvss_base_score(vector VARCHAR) |
DOUBLE |
Compute the CVSS v3.1 base score from a vector string (e.g. CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H → 9.8). Implements the official v3.1 base equation, including the changed-scope path and the spec "Roundup". |
| Function | Returns | Description |
|---|---|---|
cve(cve_id) |
id, description, cvss_score DOUBLE, cvss_severity VARCHAR, cvss_vector, published, last_modified, cwe |
Fetch one CVE by ID (one row, or zero rows for a NULL id). |
cve_search(keyword) |
id, description, cvss_score, cvss_severity, published |
Keyword search of CVE descriptions; paginated, bounded to 100 results. |
cpe_cves(cpe) |
cve_id, cvss_score, cvss_severity |
CVEs affecting a CPE 2.3 name; paginated, bounded. |
A CVE with no CVSS metrics yields a NULL cvss_score.
Every table function accepts the same optional named arguments (DuckDB
name := value syntax):
| Option | Default | Meaning |
|---|---|---|
base_url |
the real NVD endpoint | Override the NVD 2.0 base URL (used to point at a mock/proxy). |
api_key |
'' |
NVD API key, sent as the apiKey header. Raises NVD's rate limit. |
SELECT id, cvss_score
FROM cve.cve('CVE-2021-44228', api_key := 'your-nvd-key');- Offline first.
cvss_severityandcvss_base_scoremake no network call and are fully deterministic — ideal for scoring vectors already in your data. - NULL / absent input → no rows. A NULL id/keyword/cpe yields zero rows.
- No CVSS metrics → NULL score. Records still under analysis surface a NULL
cvss_scorerather than a misleading0. - Bounded & timed. Searches page through results but stop at 100 rows; every HTTP call has a 30 s timeout, so a slow or unreachable endpoint fails fast.
- Clear errors, never a crash or hang. HTTP 4xx/5xx, NVD rate-limiting (429), an unknown CVE id (404), or malformed JSON all surface as a clean DuckDB error.
Requires Go 1.25+.
make build # builds ./vgi-cve-worker and ./mockserverThe vgi-cve-worker binary speaks the VGI protocol over stdio; point a DuckDB
ATTACH ... (TYPE vgi, LOCATION '…') at it.
make test-unit # pure-Go unit tests (offline CVSS + httptest mock NVD)
make test-sql # haybarn-unittest SQL end-to-end against a local mock NVD
make test # bothmake test-sql needs haybarn-unittest on PATH:
uv tool install haybarn-unittest
export PATH="$HOME/.local/bin:$PATH"It builds the worker and a small mock NVD server (cmd/mockserver, serving
canned NVD 2.0 JSON), starts the mock on a free port, points the table functions
at it via the base_url option, runs the suite, and stops the mock.
This worker calls the public NVD 2.0 vulnerability API operated by NIST.
Please respect the NVD terms of use
and rate limits: unauthenticated clients are throttled aggressively (roughly a
handful of requests per rolling 30 s window). Request a free
NVD API key and pass it via
api_key := '…' to raise the limit. CVE data is courtesy of NIST/NVD; this
project is not endorsed by or affiliated with NIST.
- This worker is licensed MIT — see
LICENSE. - It uses only the Go standard library (
net/http,encoding/json) for the NVD client and CVSS math, plus thevgi-goSDK (and its Arrow dependency) for the VGI protocol — see that repo for its terms.
Written by Query.Farm.
Copyright 2026 Query Farm LLC - https://query.farm
