# How SkillSpector Integrates with OSV.dev for Vulnerability Lookups

> Learn how SkillSpector integrates with OSV.dev for fast vulnerability lookups of Python and JavaScript dependencies. Discover security risks efficiently.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-06-14

---

**SkillSpector performs batch vulnerability lookups against the OSV.dev database using HTTP POST requests to identify security risks in Python and JavaScript dependencies, with built-in caching and static fallback lists for offline operation.**

SkillSpector, NVIDIA's skill security analysis framework, integrates with the Open Source Vulnerability (OSV) database to detect vulnerable third-party dependencies. The **SkillSpector OSV.dev integration** enables automated security scanning of [`requirements.txt`](https://github.com/NVIDIA/SkillSpector/blob/main/requirements.txt) and [`package.json`](https://github.com/NVIDIA/SkillSpector/blob/main/package.json) files by querying the public OSV API with batched requests. This implementation combines live vulnerability data with local caching and offline fallback mechanisms to ensure reliable detection across network conditions.

## Batch Query Architecture

The OSV client implements a two-stage lookup process that minimizes API calls while retrieving comprehensive vulnerability data.

### Building the Batch Request

In [`src/skillspector/nodes/analyzers/osv_client.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/osv_client.py), the `_build_query()` method (lines 92-96) constructs the JSON payload containing all package names and versions from a dependency file. The `query_batch()` function (lines 122-135) sends this payload via **httpx** in a single HTTP POST request to `https://api.osv.dev/v1/querybatch`.

### Fetching Detailed Vulnerability Data

For each vulnerability ID returned by the batch query, `_fetch_vuln_details()` (lines 86-96) executes a secondary GET request to `https://api.osv.dev/v1/vulns/<ID>`. This retrieves the full advisory including severity scores, aliases, and human-readable summaries.

## Caching and Offline Fallback

The integration prioritizes performance and reliability through aggressive caching and static fallback databases.

### In-Memory Caching Strategy

Results are cached in the `_cache` dictionary (lines 57-61) keyed by the tuple **`(name, version, ecosystem)`** with a one-hour TTL (`_CACHE_TTL_SECS`). This prevents redundant API calls when analyzing multiple skills with overlapping dependencies.

### Static Fallback Databases

When the OSV API is unreachable or returns no data, the analyzer falls back to curated static lists defined in [`src/skillspector/nodes/analyzers/static_patterns_supply_chain.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_patterns_supply_chain.py). The variables `_FALLBACK_VULNERABLE_PYPI` and `_FALLBACK_VULNERABLE_NPM` (lines 104-132) contain known vulnerable packages for offline detection in air-gapped environments.

## Severity Normalization

Vulnerability severity is standardized through a multi-step extraction process. The `_severity_from_vuln()` method (lines 49-57) prioritizes GHSA severity ratings, followed by ecosystem-specific scores, then CVSS vectors. The helper `_osv_severity_to_app()` (lines 60-68) maps these values to the internal `Severity` enum (`CRITICAL`, `HIGH`, `MEDIUM`, or `LOW`).

## Integration with Supply-Chain Analysis

The `static_patterns_supply_chain` analyzer orchestrates the vulnerability detection workflow. The `_sc4_from_osv()` function (lines 88-108) invokes `query_batch()` and converts results into `AnalyzerFinding` objects containing package identifiers, advisory counts, and formatted summaries via `_format_vuln_ids()`. Uncovered packages pass to `_sc4_from_fallback()` (lines 136-176) for static pattern matching.

## Implementation Examples

Run a manual OSV lookup from a Python REPL:

```python
from skillspector.nodes.analyzers.osv_client import query_batch, ECOSYSTEM_PYPI

# Example packages extracted from a requirements.txt file

packages = [("requests", "2.28.1"), ("django", None)]

# Perform the batch lookup

results = query_batch(packages, ECOSYSTEM_PYPI)

for pkg, vulns in zip(packages, results):
    name, version = pkg
    print(f"{name}{'==' + version if version else ''}:")
    for v in vulns:
        print(f"  - {v.vuln_id} [{v.severity}] {v.summary}")

```

Integrate OSV results into the supply-chain analyzer:

```python
def _sc4_from_osv(
    packages: list[tuple[str, str | None, int]],
    ecosystem: str,
    file_path: str,
    tag: list[str],
) -> tuple[list[AnalyzerFinding], set[str]]:
    # Build (name, version) tuples for the OSV client

    pkg_pairs = [(name, version) for name, version, _ in packages]

    # Query OSV.dev (live lookup)

    osv_results = query_batch(pkg_pairs, ecosystem)

    # Convert OSV results → AnalyzerFinding objects

    ...

```

## Summary

- **SkillSpector** uses the OSV.dev batch API (`/v1/querybatch`) to query multiple dependencies in a single HTTP request.
- The [`osv_client.py`](https://github.com/NVIDIA/SkillSpector/blob/main/osv_client.py) module implements caching with a one-hour TTL and static fallback lists for offline operation.
- Severity scores normalize to four levels (**CRITICAL**, **HIGH**, **MEDIUM**, or **LOW**) from GHSA, ecosystem, or CVSS sources.
- The supply-chain analyzer ([`static_patterns_supply_chain.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_patterns_supply_chain.py)) coordinates live OSV queries with static pattern matching via `_sc4_from_osv()` and `_sc4_from_fallback()`.

## Frequently Asked Questions

### What API endpoint does SkillSpector use for OSV queries?

SkillSpector sends POST requests to `https://api.osv.dev/v1/querybatch` for batch vulnerability lookups and GET requests to `https://api.osv.dev/v1/vulns/<ID>` for detailed advisory information, as implemented in [`osv_client.py`](https://github.com/NVIDIA/SkillSpector/blob/main/osv_client.py).

### How does SkillSpector handle network failures during vulnerability scanning?

When the OSV API is unreachable, the analyzer automatically falls back to static vulnerability lists (`_FALLBACK_VULNERABLE_PYPI` and `_FALLBACK_VULNERABLE_NPM`) defined in [`static_patterns_supply_chain.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_patterns_supply_chain.py), ensuring security checks continue in air-gapped environments.

### What is the cache duration for OSV vulnerability lookups?

The OSV client maintains an in-memory cache keyed by package name, version, and ecosystem with a TTL of one hour (`_CACHE_TTL_SECS`), preventing redundant API calls during repeated scans.

### Which ecosystems does SkillSpector support for OSV vulnerability detection?

The implementation supports PyPI (Python) and npm (JavaScript) ecosystems through the `ECOSYSTEM_PYPI` constant and corresponding fallback lists, as defined in the OSV client and static patterns modules.