Core Concepts
OSV Architecture
A technical deep dive into how Agentinel bundles and queries the Open Source Vulnerabilities database, and the heuristic layer that catches what the DB misses.
What is OSV?
The Open Source Vulnerabilities (OSV) database is a Google-backed, open schema for describing security vulnerabilities in open-source packages. It aggregates data from npm security advisories, GitHub Advisory Database, and community takedown records into a single unified format.
OSV covers 216,000+ vulnerability and malicious-package records across the npm ecosystem. Each record contains the affected package name, affected version ranges, severity, and a structured description of the threat.
Agentinel bundles a snapshot of the relevant npm subset of this database at publish time. When you npm install agentinel, the DB comes with it.
Local database bundling
The OSV data is stored as a compact binary index inside the Agentinel package. At scan time, Node.js reads this file from the local filesystem. There is no HTTP request, no CDN, and no DNS lookup.
Why local?
A network-dependent scanner can fail your build if the API is down, rate-limited, or firewalled. By bundling the DB locally, Agentinel works in air-gapped environments and never adds latency from external round-trips.
The DB is updated each time you update the agentinel package itself. Running npm update agentinel pulls the latest OSV snapshot.
Version-exact matching algorithm
When Agentinel receives a package name and version string from an agent hook, it performs a two-pass lookup:
1. Name lookup
The package name is looked up in the OSV index. If no record exists, the package is clean from a vulnerability perspective (but may still trigger heuristics).
2. Version range evaluation
For each OSV record matching the package name, the requested version is tested against the affected version range using semver range evaluation. A match produces a BLOCK or WARN signal depending on mode.
The result of the matching algorithm is a structured decision object:
{
"package": "react-router-v7-beta",
"version": "1.0.0",
"decision": "BLOCK",
"source": "OSV_MATCH",
"osvId": "MAL-2024-8821",
"reason": "Package matches OSV malicious package record MAL-2024-8821"
}Heuristic scanning layer
The OSV DB catches known malware. The heuristic layer catches unknown threats before they make it into OSV. These five signals run on every package scan, in parallel with the DB lookup.
AGE_CHECKPackage age under 30 days
Newly published packages are disproportionately represented in malicious package datasets. A package registered fewer than 30 days ago that an AI agent tries to install is treated as a yellow-flag heuristic trigger.
Publication date is evaluated via a fast registry check. Only the most vital data is queried to maintain ultra-low latency.
DOWNLOAD_CHECKDownload count under 1,000
Malicious packages rarely accumulate significant download counts before takedown. A package with fewer than 1,000 total downloads is flagged, especially in combination with other heuristics.
Download counts are quickly fetched for packages that trigger suspicion, minimizing overhead while catching likely threats.
MAINTAINER_DRIFTPublisher drift
A package whose primary maintainer changed recently is a supply-chain risk signal. Attackers sometimes purchase or compromise low-traffic packages to inject malicious code into a trusted name.
Agentinel can verify maintainer metadata against known good snapshots. Sudden or suspicious ownership transfers flag this heuristic.
GHOST_PACKAGENon-existent package name
If the package name has never appeared on the npm registry (i.e., it does not exist in the bundled DB at all), it is almost certainly an LLM hallucination. This is the primary slopsquatting signal.
The engine references a massive list of known, valid packages. A complete miss is treated as a strong "ghost package" signal and triggers a BLOCK in strict mode.
TAKEDOWN_MARKERnpm takedown markers
The OSV dataset includes explicit takedown records for packages that npm has unpublished for security reasons. Any package with a takedown marker is immediately blocked, regardless of mode.
Takedown markers are the most authoritative signal in the DB. They override all other checks, including the allowlist.
Fail Open implementation
Every scan is wrapped in a top-level error boundary. If any part of the OSV lookup or heuristic evaluation throws an unexpected exception, the scanner catches it and emits an ALLOW decision with a warning written to stderr.
async function scanPackage(name: string, version: string): Promise<Decision> {
try {
const osvResult = await checkOsvDatabase(name, version);
if (osvResult.matched) return { action: "BLOCK", source: "OSV_MATCH", ...osvResult };
const heuristicResult = await runHeuristics(name, version);
if (heuristicResult.flagged) return { action: "WARN", source: "HEURISTIC", ...heuristicResult };
return { action: "ALLOW" };
} catch (err) {
process.stderr.write(`[agentinel] scan error: ${err}. Failing open.
`);
return { action: "ALLOW", source: "ERROR_FAILOPEN" };
}
}Known limitations
1-3 day DB lag
The bundled OSV snapshot lags 1-3 days behind the live OSV feed. Zero-day malicious packages published in the last 24-72 hours may not appear in the DB. The heuristic layer partially mitigates this by flagging low-trust packages regardless of DB presence.
No behavioral analysis
Agentinel does not sandbox or execute package code to detect malicious behavior at runtime. It only checks package identity against the DB and applies static heuristics. A novel malicious package that has no OSV record and passes all heuristics will not be detected.
npm ecosystem only
The current version of Agentinel only covers the npm (Node.js) ecosystem. PyPI, Cargo, and other ecosystems are on the roadmap.