How SkillSpector Performs OSV.dev Live Vulnerability Lookups for Supply Chain Security
SkillSpector performs live OSV.dev vulnerability lookups by batching dependency queries, sending POST requests to the OSV.dev API, and normalizing results into severity-scored findings with automatic fallback to static lists when offline.
NVIDIA's SkillSpector implements real-time supply chain security scanning by integrating OSV.dev live vulnerability lookups directly into its static analysis pipeline. The system queries the Open Source Vulnerabilities database to identify known security issues in Python and JavaScript dependencies, providing immediate feedback during code review. This implementation ensures developers receive current vulnerability data while maintaining resilience through offline fallback mechanisms.
Building Batched Queries for OSV.dev
The process begins in src/skillspector/nodes/analyzers/osv_client.py where the query_batch function constructs optimized batch requests. For each dependency file discovered in the project, SkillSpector extracts (name, version) tuples and maps them to specific ecosystem constants—ECOSYSTEM_PYPI for Python packages or ECOSYSTEM_NPM for Node.js dependencies.
Request Structure
Each package translates into a dictionary following OSV.dev's batch specification: { "package": {"name": <name>, "ecosystem": <ecosystem>}, "version": <version> }. The helper function _build_query assembles these into a single JSON payload capable of querying multiple packages in one HTTP request, minimizing network overhead when analyzing large dependency trees.
Executing Live Lookups Against the OSV.dev API
The query_batch function transmits requests via httpx.Client to https://api.osv.dev/v1/querybatch. The client respects the SKILLSPECTOR_OSV_TIMEOUT environment variable for configurable network timeouts, ensuring scans don't hang in restricted network environments.
Retrieving Detailed Vulnerability Records
When OSV.dev returns a results array containing vulnerability IDs (vulns), SkillSpector initiates secondary GET requests to https://api.osv.dev/v1/vulns/<id> via _fetch_vuln_details. This retrieval is capped at 10 IDs per batch to prevent API rate limiting while gathering complete severity metadata and advisory summaries.
Normalizing Severity and Caching Results
Raw vulnerability data transforms into structured VulnResult dataclasses through severity normalization pipelines in osv_client.py.
Severity Extraction
The _severity_from_vuln function extracts CVSS scores from OSV.dev responses, passing them to _estimate_cvss_severity to normalize ratings into standardized severity levels. This ensures consistent risk scoring across different vulnerability databases and advisory formats.
In-Memory Caching
To optimize repeated scans, osv_client.py maintains an in-memory _cache dictionary keyed by (name, version, ecosystem) tuples with a one-hour TTL. Subsequent lookups for identical dependencies return cached results, eliminating redundant API calls during iterative development.
Integrating OSV.dev Results into Supply Chain Analysis
The supply chain analyzer in src/skillspector/nodes/analyzers/static_patterns_supply_chain.py orchestrates the vulnerability detection workflow through the _sc4_from_osv function.
Converting to AnalyzerFindings
Each vulnerability list transforms into an AnalyzerFinding with human-readable descriptions formatted as: "Known Vulnerable Dependency: requests==2.31.0 — 1 advisory(ies): CVE-2023-32681 (header leak on redirect)". These findings include the normalized severity extracted earlier and precise file locations within the dependency manifest.
Offline Fallback Mechanism
When network requests fail—the OSV.dev service is unreachable, timeouts occur, or in air-gapped environments—the system sets _last_query_ok = False and automatically falls back to _FALLBACK_VULNERABLE_PYPI or _FALLBACK_VULNERABLE_NPM static lists. A warning finding alerts users that results derive from offline data only, maintaining security visibility despite connectivity issues.
Implementation Examples
Direct OSV Client Usage
from skillspector.nodes.analyzers.osv_client import query_batch, ECOSYSTEM_PYPI
# Look up a few PyPI packages
packages = [("requests", "2.31.0"), ("jinja2", "3.1.3")]
results = query_batch(packages, ECOSYSTEM_PYPI)
for pkg, vulns in zip(packages, results):
print(f"{pkg[0]}=={pkg[1]} → {len(vulns)} vulnerabilities")
for v in vulns:
print(f" • {v.vuln_id} – {v.severity}: {v.summary}")
Full Supply Chain Node Execution
from skillspector.state import SkillspectorState
from skillspector.nodes.analyzers.static_patterns_supply_chain import node
# Minimal state containing a requirements file
state = SkillspectorState({
"components": ["requirements.txt"],
"file_cache": {"requirements.txt": "requests==2.31.0\njinja2==3.1.3"},
"manifest": {}
})
response = node(state)
for finding in response["findings"]:
print(f"[{finding.rule_id}] {finding.message} (severity={finding.severity})")
Checking OSV.dev Availability
The is_available() method performs a lightweight POST check to verify OSV.dev reachability before executing full scans. After any query attempt, was_osv_reachable() returns the _last_query_ok flag, allowing downstream components to adjust behavior based on live connectivity status.
Summary
- SkillSpector batches dependency queries in
osv_client.pyto minimize API calls tohttps://api.osv.dev/v1/querybatch - Vulnerability details are retrieved via
_fetch_vuln_detailswith rate limiting protection (10 IDs per batch) - Severity normalization uses
_severity_from_vulnand_estimate_cvss_severityfor consistent risk scoring - A one-hour TTL in-memory cache prevents redundant network requests for repeated dependency scans
- Offline fallback activates automatically using
_FALLBACK_VULNERABLE_PYPIand_FALLBACK_VULNERABLE_NPMwhen OSV.dev is unreachable
Frequently Asked Questions
What happens when OSV.dev is unreachable during a scan?
If the OSV.dev API returns a network error or timeout, SkillSpector sets _last_query_ok = False and automatically falls back to built-in static vulnerability lists (_FALLBACK_VULNERABLE_PYPI for Python, _FALLBACK_VULNERABLE_NPM for Node.js). The system emits a warning finding to notify users that the results are based on offline data rather than live OSV.dev vulnerability lookups.
How does SkillSpector prevent redundant API calls for the same dependencies?
The osv_client.py module implements an in-memory _cache dictionary keyed by (name, version, ecosystem) tuples with a one-hour TTL. Subsequent scans within the TTL window return cached VulnResult objects, eliminating redundant HTTP requests to OSV.dev.
What is the batch size limit for vulnerability detail retrieval?
SkillSpector caps detail retrieval at 10 vulnerability IDs per batch when calling _fetch_vuln_details. This prevents hitting OSV.dev rate limits while still gathering complete severity information and advisory summaries for each identified vulnerability.
Which ecosystems does SkillSpector support for OSV.dev queries?
As implemented in the source code, SkillSpector supports PyPI (Python) using ECOSYSTEM_PYPI and npm (Node.js) using ECOSYSTEM_NPM. The ecosystem constant determines which package registry OSV.dev searches when processing the batch query.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →