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.
Scanned paths
/var/www/opt/srv/home/<user>/root/var/lib/jenkins/workspaceC:\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 ..
Recognised lockfiles
| File | Ecosystem |
|---|---|
package-lock.json (npm v1/v2/v3) | npm |
yarn.lock | npm |
pnpm-lock.yaml | npm |
requirements.txt | PyPI |
Pipfile.lock | PyPI |
composer.lock | Packagist |
Gemfile.lock | RubyGems |
go.sum | Go |
Not (yet) supported: Cargo.lock, pubspec.lock, mix.lock, Maven pom.xml. PRs welcome.
Caps to bound payload
- Max 100 projects per host
- Max 20,000 packages total per host
node_modules-style transitives are included but markedis_direct=false
What the hub does
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", ... } ]}Privacy
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.
What to do with findings
inventory_dependency_cves rows are idle data without operator action. You can:
- Browse them in
/agents/<id>→ Dependencies tab (per agent, per project) - Fleet-wide search in
/inventory(filter on CVE id, package, severity) - Create an alert rule: trigger when an agent with tag
productionhas ≥1 CRITICAL dependency CVE (combinable with threshold + duration) - CSV export for your security team
Limitations to know:
- No typosquatting detection (
react-domvsreact.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.