Skip to content

Supply-chain security

monsys.ai covers three categories of supply-chain risk:

  1. OS packages — apt/rpm/winget/wmic → NVD + EPSS
  2. Container images — Docker images → Trivy (hub-side)
  3. Application dependencies — npm/pip/composer/go/gem → OSV.dev

None of the three needs extra software on the customer host. The agent reports names + versions; the hub does the CVE work.

OS packages

The agent reads package manager state:

OSSource
Debian/Ubuntudpkg-query -W
RHEL/Alma/Rockyrpm -qa
Alpineapk info -vv
Windowswinget list with wmic product get fallback

Result per agent: inventory_packages row with (name, version, manager). Hub matches against the current NVD feed + EPSS exploit likelihood, with version-range parsing for exact, geq/leq and multi-range expressions.

Per match a risk_score is computed:

base = cvss × max(epss, 0.05)
× 1.5 if CVE > 30 days without a patch (age factor)
× 2.0 if known public exploit exists (exploit factor)
× 1.5 if package listens on an internet-facing port
capped at 10.0

Internet exposure is derived from inventory_ports where address NOT IN ('127.0.0.1', '::1') matched on process name.

Endpoint: GET /api/v1/inventory/cves (fleet-wide) or ?agent=<uuid> (per host). Filters: cve, pkg, min_cvss, tag. CSV export: &format=csv.

Container images

For customers running Docker, the agent reports inventory_containers rows — image name + tag, image digest, run state, port mappings, run-as user, cap_add, privileged flag.

The hub runs trivy image --severity=HIGH,CRITICAL --scanners=vuln against each unique (image, tag) every 6h. Trivy uses the official vuln database (mirror of GitHub Advisory + NVD); we sync that DB once on the hub.

Important: Trivy is not on the customer host. We briefly considered that approach, but it requires root access and software installation at every customer. The hub-side approach works for:

  • Public registries (Docker Hub, GHCR, Quay) — out of the box
  • Private registries — one-time trivy registry login on the hub host

Findings land in inventory_container_cves and are visible in each agent’s Containers tab.

Limitations:

  • No scan for images only available through a private registry behind a VPN the hub can’t reach. For that scenario see RFC-0001 Tailscale integration.
  • No scan of running container internals (process tree, mounted secrets) — only what’s in the image manifests.

Application dependencies (npm/pip/composer/go/gem)

The agent walks /var/www, /opt, /srv, /home/*, /root (max depth 6) and parses lockfiles:

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

Only (name, version, ecosystem, is_direct) tuples are sent to the hub — no file content. Per-host caps: max 100 projects, max 20,000 packages, max depth 6. node_modules, vendor, .git are skipped.

The hub DependencyScanWorker batch-queries https://api.osv.dev/v1/querybatch (1000 tuples/request, free, public). For each match it fetches /v1/vulns/<id> for details, normalises severity, and writes to inventory_dependency_cves.

Cold-start cadence: every 30s for the first 15 minutes after hub start (catches new deps), then 6h steady.

What OSV.dev DOES cover

  • Known CVEs with aliases (CVE-, GHSA-, PYSEC-, RUSTSEC-, …)
  • Affected version ranges with fix versions
  • Severity from GitHub Advisory DB (normalised by us to CRITICAL/HIGH/MODERATE/LOW)
  • Cross-ecosystem aliases — one GHSA can cover both npm and Python

What OSV.dev does NOT cover

  • Typosquattingreact-dom vs react.dom. No pattern detection.
  • Malicious install scriptsnpm install of a legitimate-looking package that drops backdoors. Requires tarball analysis.
  • Compromised maintainer accounts where a normal package suddenly contains malicious code (event-stream-style).

For those categories you need behaviour analysis like Socket.dev or npm audit signatures (sigstore signing). Both can be integrated later.

Best practices for customers

  1. npm ci --ignore-scripts in CI and production — npm install only in dev where you know what you’re running.
  2. Pin production dependencies (package-lock.json committed, no ^X.Y.Z ranges).
  3. Set an alert rule: a new CRITICAL CVE in inventory_dependency_cves for an agent with tag production → notify within a minute.
  4. Maintenance windows during deploys — otherwise your rolling update triggers an alert storm.
  5. Weekly audit log review for abnormal playbook_run or branding-PUT actions.