Skip to content

Dependency scanning

The agent walks several standard project locations every 6h and parses lockfiles per package manager. Only (name, version, ecosystem, is_direct) tuples + the project_path are sent to the hub — no file contents, no env vars, no secrets.

/var/www
/opt
/srv
/home/<user>
/root
/var/lib/jenkins/workspace
C:\inetpub\wwwroot (Windows)
C:\Program Files\nodejs (Windows)

Depth: max 6 levels. Skips node_modules, vendor, .git, .svn, .idea, .vscode, target, build, dist, __pycache__, and anything starting with ..

FileEcosystem
package-lock.json (npm v1/v2/v3)npm
yarn.locknpm
pnpm-lock.yamlnpm
requirements.txtPyPI
Pipfile.lockPyPI
composer.lockPackagist
Gemfile.lockRubyGems
go.sumGo

Not (yet) supported: Cargo.lock, pubspec.lock, mix.lock, Maven pom.xml. PRs welcome.

  • Max 100 projects per host
  • Max 20,000 packages total per host
  • node_modules-style transitives are included but marked is_direct=false

The DependencyScanWorker picks up every 30s (cold-start) or 6h (steady) every unique (ecosystem, package_name, version) tuple from inventory_dependencies and batch-queries https://api.osv.dev/v1/querybatch (1000 tuples per call). For each match it fetches the vuln detail from /v1/vulns/<id>, normalises severity, and writes to inventory_dependency_cves.

Endpoint: GET /api/v1/agents/:id/inventory/dependencies → returns:

{
"projects": [
{ "project_path": "/var/www/api", "manifest": "package-lock.json",
"ecosystem": "npm", "dep_count": 1248, "direct_count": 47,
"cve_count": 89, "critical_count": 3 }
],
"cves": [
{ "vulnerability_id": "GHSA-9jj7-4m8r-rfcm",
"severity": "CRITICAL", "package_name": "jackc/pgx/v5",
"installed_version": "5.7.0", "fixed_version": "5.9.0", ... }
]
}

What DOES go to the hub:

  • Project path (e.g. /var/www/api)
  • Package name + version
  • Ecosystem label
  • Direct/transitive flag

What does NOT go to the hub:

  • Lockfile contents
  • Other files in the project (no .env, no source code)
  • Sha256 of the lockfile itself
  • Env vars from the project

The npm ls output on the host itself reveals the exact same information to anyone with shell access. We send no more than that.

inventory_dependency_cves rows are idle data without operator action. You can:

  1. Browse them in /agents/<id>Dependencies tab (per agent, per project)
  2. Fleet-wide search in /inventory (filter on CVE id, package, severity)
  3. Create an alert rule: trigger when an agent with tag production has ≥1 CRITICAL dependency CVE (combinable with threshold + duration)
  4. CSV export for your security team

Limitations to know:

  • No typosquatting detection (react-dom vs react.dom). OSV.dev matches only on exact (package, version).
  • No malicious install-script detection (post-install hooks that drop backdoors).
  • No detection of compromised maintainer accounts where legitimate versions suddenly become malicious.

For those three you’d add tools like Socket.dev or npm audit signatures (sigstore) — on the roadmap.