How SkillSpector Handles Offline Environments for OSV.dev: Resilient Vulnerability Scanning
SkillSpector gracefully handles unreachable OSV.dev services by catching network exceptions, returning empty lists, and falling back to a built-in static vulnerability database, ensuring continuous operation in air-gapped environments.
NVIDIA's SkillSpector is designed to operate in secure, offline environments where external API access is restricted. When the OSV.dev vulnerability database cannot be reached, the tool implements a multi-layered resilience strategy centered in src/skillspector/nodes/analyzers/osv_client.py that maintains scanning capabilities without network connectivity.
Network Failure Protection in osv_client.py
The OSV client implements robust exception handling to survive complete network isolation. Within the query_batch function, all HTTP calls are wrapped in try/except blocks that specifically catch httpx.HTTPError, httpx.TimeoutException, and parsing errors including ValueError and KeyError.
When any exception occurs, the client logs a warning message and returns an empty list for every package in the batch rather than propagating the error:
except (httpx.HTTPError, httpx.TimeoutException, ValueError, KeyError) as exc:
logger.warning("OSV.dev API request failed, falling back to static data: %s", exc)
return [[] for _ in packages]
This pattern ensures that upstream analyzers receive the expected list structure even when the OSV.dev API is completely unreachable, preventing pipeline crashes in offline environments.
In-Memory Caching for Resilience
SkillSpector reduces network dependency through time-based caching. The OSV client stores successful query results for _CACHE_TTL_SECS = 3600 (one hour).
When operating in intermittent connectivity environments, this cache allows the scanner to reference recent vulnerability data without requiring fresh API calls. If the service becomes unreachable during a scan session, cached results for previously queried packages remain available for the duration of the TTL window.
Graceful Degradation to Static Vulnerability Patterns
When live OSV.dev queries fail, SkillSpector automatically activates its static vulnerability database. The upstream analyzer static_patterns_supply_chain.py expects query_batch to always return a list (potentially empty).
Upon receiving empty results from the offline client, the analyzer merges these with a curated static vulnerability list that ships with the repository. This embedded dataset contains high-impact CVEs for common packages, ensuring the scanner still produces actionable security findings even without live look-ups.
Proactive Connectivity Checking
To avoid unnecessary network timeouts, SkillSpector provides the is_available() helper function in osv_client.py. This method issues a lightweight POST request to the OSV.batch endpoint before attempting full batch queries.
Applications can leverage this check to proactively determine connectivity status:
from skillspector.nodes.analyzers.osv_client import query_batch, is_available
# Example list of dependencies (name, version)
deps = [("requests", "2.28.1"), ("flask", None)]
# Check whether the live OSV service can be reached
if is_available():
results = query_batch(deps, ecosystem="PyPI")
else:
# OSV.dev is unreachable → rely on static data (empty lists here)
results = [[] for _ in deps]
for (name, _), vulns in zip(deps, results):
if vulns:
print(f"{name} has {len(vulns)} known vulnerabilities")
else:
print(f"{name} – no live data; using static fallback")
When is_available() returns False in air-gapped environments, the code path skips network attempts and immediately utilizes the static fallback mechanism.
Summary
- Exception handling: The
query_batchfunction inosv_client.pycatcheshttpx.HTTPError, timeouts, and parsing errors, returning empty lists instead of crashing the pipeline. - Caching layer: Successful queries are cached for 3600 seconds, providing a buffer against transient network failures.
- Static fallback: The
static_patterns_supply_chain.pyanalyzer activates a built-in vulnerability database when OSV.dev cannot be reached. - Connectivity detection: The
is_available()function enables proactive detection of offline environments before attempting API calls.
Frequently Asked Questions
What happens when OSV.dev is completely unreachable in SkillSpector?
SkillSpector catches the network exception in osv_client.py, logs a warning, and returns empty lists for all packages. This triggers the supply chain analyzer to use its built-in static vulnerability database instead of live OSV data, allowing scans to complete without internet access.
Does SkillSpector cache OSV.dev responses for offline use?
Yes. The client caches successful API responses for 3600 seconds (one hour) using the _CACHE_TTL_SECS constant defined in osv_client.py. If the service goes offline, recent query results remain available from memory for the duration of the cache window.
Can SkillSpector detect if OSV.dev is available before attempting queries?
Yes. The is_available() function in osv_client.py performs a lightweight connectivity check to the OSV.batch endpoint. Applications can call this method to decide whether to attempt live queries or skip directly to static analysis, preventing unnecessary timeout delays in offline environments.
What vulnerability data is available when running offline?
When OSV.dev cannot be reached, SkillSpector falls back to a static vulnerability list embedded in static_patterns_supply_chain.py. This curated dataset contains high-impact CVEs for common packages, ensuring the scanner still produces security findings without internet access.
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 →