npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codacy/tools-trivy-0

v0.21.0

Published

Trivy adapter — CLI-mode security scanner

Readme

@codacy/tools-trivy-0

Table of Contents


Overview

Security scanner using the Trivy binary. Scans for vulnerabilities in dependencies and hardcoded secrets. Uses the CLI execution strategy with two separate scan modes (vulnerability + secret).

| Property | Value | | ------------- | ------------------------------------------- | | Tool ID | Trivy | | Codacy UUID | 2fd7fbe0-33f9-4ab3-ab73-e9b62404e2cb | | Strategy | CLI | | Languages | Multi-language (scans dependency manifests) | | Binary | trivy | | File patterns | * (auto-detects dependency manifests) | | Pattern count | 6 (umbrella patterns) |

Umbrella patterns

Trivy uses umbrella patterns rather than individual CVE patterns:

| Pattern ID | Severity | Description | | ------------------------------ | -------- | ------------------------------------ | | Trivy_vulnerability_critical | Error | Critical vulnerabilities | | Trivy_vulnerability_high | High | High-severity vulnerabilities | | Trivy_vulnerability_medium | Warning | Medium-severity vulnerabilities | | Trivy_vulnerability_minor | Info | Low-severity vulnerabilities | | Trivy_secret | Error | Hardcoded secrets | | Trivy_malicious_packages | Error | Malicious packages (via OSV.dev API) |

Issue parity with codacy-trivy

Codacy Cloud analyses repositories with the codacy-trivy Docker engine, so a repository scanned locally and uploaded must produce the same results as the same repository scanned on the cloud. Three pieces of this adapter exist only to hold that line; the reference implementation is codacy-trivy internal/tool/tool.go, and the ports live in src/vuln-mapping.ts (fallbackSearchForLineNumber, findLeastDisruptiveFixedVersion, purlPrettyPrint). Change them only alongside that file.

sourceId — why every issue carries its CVE

Codacy derives a result's deterministic UUID from an MD5 over four keys: filename, pattern id, the line's text with whitespace stripped, and sourceId (codacy-worker shared/rules/…/rules/components/ResultUUIDRules.scala).

Trivy reports many CVEs under one of four severity umbrella patterns, so two CVEs on the same lockfile line share three of those four keys. Without sourceId they collapse into a single Codacy result. Every issue this adapter produces therefore sets it:

| Finding | sourceId | | ----------------- | ----------------------------- | | Vulnerability | VulnerabilityID (the CVE) | | Secret | Trivy's RuleID | | Malicious package | The OSV advisory id (MAL-…) |

src/metadata.ts sets needsSourceIdUpload: true, which is what makes upload include the field in the v2 payload (mirroring needs_source_id_upload in the Go CLI's Trivy plugin manifest). Adapters without the flag omit the field entirely — sending it where the cloud engine does not would give the same finding a different UUID.

Scan flags that affect what is found

The vulnerability scan passes --detection-priority comprehensive, matching codacy-trivy's DetectionPriority: PriorityComprehensive. It reports more vulnerabilities — some of which may be false positives — and it is required for Go standard-library findings: verified against trivy 0.70, a go.mod scan without it reports zero stdlib vulnerabilities (6 issues instead of 26 on a small go 1.20 module). Removing the flag would silently drop every stdlib finding and make the go.mod handling below dead code.

Line-number resolution

Trivy reports no line for a vulnerable dependency, so the line is reconstructed:

  1. Look up the package's Locations[0].StartLine, keyed by PURL — the key the cloud engine uses. PkgID is a secondary key for the rare package Trivy reports without a PURL.
  2. On a miss or a zero, scan the manifest top to bottom for the first line whose trimmed text contains the package name.
  3. Still nothing ⇒ emit a file-level error (Line numbers not supported, deduplicated to one per file), not an issue on line 1. A confidently wrong location is worse than an honest "unknown"; codacy-trivy makes the same call via mapIssuesWithoutLineNumber.

go.mod standard library. Trivy reports standard-library vulnerabilities against a package named stdlib, which never literally appears in go.mod. Trivy documents using the minimum of the toolchain and go directives, but in practice always uses toolchain when it exists. So the scan returns the toolchain line as soon as it sees one, and only falls back to the go directive line after reading the whole file. This is not derivable from Trivy's docs — do not "simplify" it.

Fix version

Trivy's FixedVersion is a comma-separated list of every fixing version ("1.9.0, 1.10.0, 2.0.1"). The message reports only the least disruptive one: the smallest candidate strictly greater than the installed version, by semantic version. When no candidate is greater (or the scheme isn't semver — Ruby's ~>, Maven qualifiers), Trivy's raw value is passed through; when FixedVersion is empty the message reads (no fix available).

Message format, matching the cloud engine verbatim:

Insecure dependency {pretty-printed PURL} ({CVE}: {title}) (update to {version})
Insecure dependency {pretty-printed PURL} ({CVE}: {title}) (no fix available)

Comparison uses a port of Go's golang.org/x/mod/semver (compareSemver), not npm semver: it accepts two-component versions like v1.2, and treats an unparseable version as lower than any valid one, which is what makes non-semver schemes fall through instead of being ranked.

Known divergences

Both are deliberate; see docs/tech-debt.md.

  • Fix-version ordering. codacy-trivy sorts the candidate strings before adding the v prefix, so x/mod/semver sees them all as invalid, compares them equal, and falls back to a lexicographic tiebreak — picking 1.10.0 over 1.9.0. We sort on the prefixed values and return the genuinely smallest.
  • Packages without a PURL. codacy-trivy skips those vulnerabilities entirely. We keep them, resolving the line by name and rendering the package as name@version, because silently dropping a real vulnerability is worse than a message that differs from the cloud's.
  • Secret message text. Ours appends the secret's category (Possible hardcoded secret: {title} ({category})); the cloud engine stops at the title.
  • Offline scan. codacy-trivy sets OfflineScan: true (its container is air-gapped); we don't, so Trivy may resolve some Java/Maven dependencies over the network and report slightly more accurate results for those ecosystems. Not changed here: making local scans less accurate to match an air-gap constraint we don't have would be the wrong trade.

DB update management

The adapter reads Trivy's metadata.json (at {cacheDir}/db/metadata.json) to determine if the vulnerability database is still fresh. The NextUpdate field tells us when Trivy expects the next DB update.

| Scenario | Behavior | | ------------------------------ | ------------------------------------------------------------------ | | DB fresh (now < NextUpdate) | --skip-db-update --skip-java-db-update passed — no network check | | DB stale (now >= NextUpdate) | Trivy checks for updates normally | | First run (no metadata) | Trivy downloads the DB (~40MB) | | Container mode | Always skips DB updates (DBs are pre-baked) |

Malicious package detection

Detects known malicious packages by querying the OSV.dev batch API. This piggybacks on the vulnerability scan output — the package list from --list-all-pkgs is extracted and cross-referenced against the OpenSSF malicious packages index (MAL-* IDs).

  • Covers 14 ecosystems: npm, PyPI, Go, RubyGems, crates.io, NuGet, Maven, Packagist, Pub, Hex, ConanCenter, CocoaPods, SwiftURL, conda
  • Uses a 10-second timeout per API call
  • On API failure (network error, timeout), logs a warning and skips — never blocks the core scan
  • Message format: Malicious package detected: {name}@{version} ({MAL-ID}). {summary}

Updating patterns

# Re-fetch pattern metadata from the Codacy API
pnpm prefetch

# Commit the result
git add src/patterns.json

Updating the Trivy version

  1. Update preferredVersion in src/adapter.ts
  2. Update the download URL template if the release format changed
  3. Run pnpm test to verify compatibility

Development

pnpm build    # Build with tsup
pnpm test     # Run tests (requires trivy in PATH or auto-install)

Notes for maintainers

  • Trivy runs two separate scan invocations: one for vulnerabilities (--scanners vuln --detection-priority comprehensive) and one for secrets (--scanners secret). Malicious package detection piggybacks on the vuln scan output (no extra invocation). Which scans run depends on which umbrella patterns are enabled.
  • The vulnerability database is downloaded lazily on first run to --cache-dir ~/.codacy/cache/trivy/. Internet access is required on first use. DB staleness is managed via metadata.jsonNextUpdate.
  • Trivy scans whole directories, not individual files. Results are filtered to ctx.targetFiles after scanning.
  • The binary is downloaded from GitHub releases as a .tar.gz archive.
  • Vulnerability severity (CRITICAL/HIGH/MEDIUM/LOW) maps to the corresponding umbrella pattern.
  • Message format, line resolution and sourceId are all parity-critical — see Issue parity with codacy-trivy before touching them.
  • A vulnerability whose line cannot be resolved becomes a file-level AnalysisError (kind: "LineNumbersNotSupported"), one per file, rather than an issue on line 1.
  • Malicious package detection uses the OSV.dev batch API. On failure, it degrades gracefully (warning only).
  • Config file: checks for trivy.yaml in the repo root.