@codacy/tools-trivy-0

中文文档
0.28.0发布于 2026/11/09MITTypeScriptCommonJS近 30 天下载 1.2万

Trivy adapter — CLI-mode security scanner

原始使用文档
文档目录16 节
  1. Table of Contents
  2. Overview
  3. Umbrella patterns
  4. Issue parity with codacy-trivy
  5. sourceId — why every issue carries its CVE
  6. Scan flags that affect what is found
  7. Line-number resolution
  8. Fix version
  9. Known divergences
  10. DB update management
  11. Malicious package detection
  12. Container image mode
  13. Updating patterns
  14. Updating the Trivy version
  15. Development
  16. Notes for maintainers

@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).

PropertyValue
Tool IDTrivy
Codacy UUID2fd7fbe0-33f9-4ab3-ab73-e9b62404e2cb
StrategyCLI
LanguagesMulti-language (scans dependency manifests)
Binarytrivy
File patterns* (auto-detects dependency manifests)
Pattern count6 (umbrella patterns)

Umbrella patterns

Trivy uses umbrella patterns rather than individual CVE patterns:

Pattern IDSeverityDescription
Trivy_vulnerability_criticalErrorCritical vulnerabilities
Trivy_vulnerability_highHighHigh-severity vulnerabilities
Trivy_vulnerability_mediumWarningMedium-severity vulnerabilities
Trivy_vulnerability_minorInfoLow-severity vulnerabilities
Trivy_secretErrorHardcoded secrets
Trivy_malicious_packagesErrorMalicious 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:

FindingsourceId
VulnerabilityVulnerabilityID (the CVE)
SecretTrivy's RuleID
Malicious packageThe 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.

ScenarioBehavior
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 modeAlways 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}

Container image mode

Besides the repository scan, the adapter implements the optional containerImage capability (src/image.ts), which backs the CLI's container-scan and upload-sbom commands. The descriptor advertises it with scansContainerImages: true.

MethodInvocation
scantrivy image --format json --cache-dir … [--skip-db-update --skip-java-db-update] --scanners vuln [--ignore-unfixed] --severity … --pkg-types … <image>
generateSbomtrivy image --format cyclonedx|spdx-json --output <path> --cache-dir … <image>
  • The image reference is re-validated with validateImageReference right before it becomes an argv element, even though the runner validated it first.
  • --exit-code is deliberately not passed. The finding count comes from the parsed JSON, so any non-zero exit is a real failure — no stderr heuristics like cli-v2's to decide whether it failed.
  • Findings reuse describeVulnerability (src/findings.ts), the same mapping the repository scan uses: umbrella pattern by severity, codacy-trivy's message format, CVE as sourceId, UNKNOWN dropped. The location is Trivy's Target (the OS layer or an in-image manifest) at line 1.
  • generateSbom succeeds only if Trivy exits 0 and wrote a non-empty file.
  • Every Trivy spawn (both modes) sets TRIVY_SKIP_VERSION_CHECK=true, and a failure's stderr goes through summarizeTrivyStderr (src/trivy-errors.ts) rather than being echoed: Trivy's stderr is a log stream (INFO lines, an ANSI version notice, then a FATAL Go error-wrap chain), and the text formatter truncates errors at 240 characters, which used to cut it off before the cause. The env var rather than --skip-version-check, because an older global Trivy would reject the flag.
  • test/fixtures/image-scan.json is trimmed from a real trivy image run against nginx:1.21.0-alpine, plus one synthetic UNKNOWN finding and one synthetic library finding. CODACY_TRIVY_IMAGE_IT=1 pnpm test runs the opt-in integration test against the real registry.

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/metadata.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.json → NextUpdate.

  • Trivy scans a directory, not a file list, and there is no include flag. Both scans keep the repository root as the target, so Target is repo-relative, and results are filtered to ctx.targetFiles afterwards. The secret scan also passes --skip-dirs for every directory with no target file beneath it (src/scan-scope.ts, computeSkipDirs). That is lossless, because a secret is reported on the file that holds it. Before this, analyzing one file walked the whole tree twice, node_modules included, which took minutes on a large repository. Pruning is off in two cases:

    • The vulnerability scan is never pruned. Its findings depend on files in other directories. A yarn workspace's member package.json files decide which yarn.lock entries are dev-only, so skipping packages/ made Trivy report dev dependencies' vulnerabilities.
    • No pruning when a local trivy.yaml is in use. A command-line --skip-dirs replaces the config's skip-dirs instead of adding to it, so the user's exclusions would stop applying.

    The scan also runs unpruned if the skip list would not fit on a Windows command line.

  • The vulnerability scan (and the malicious-package check that reuses its package list) is skipped when every target file has a source-code or document extension (needsVulnScan). That list is a deny-list on purpose: an extension missing from it only costs speed, whereas a forgotten manifest name in an allow-list would silently drop findings. Never add data formats (.json, .yaml, .toml, .xml, .lock, .txt) to it.

  • Target is normalized to forward slashes before it is matched against ctx.targetFiles, so a Windows-style path can never silently match nothing.

  • 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.

版本与发布记录

@codacy/tools-trivy-0 共发布 36 个版本,首次发布于 2026/03/24;过去 12 个月发布了 36 个版本。

版本发布日期距今
0.28.0latest2026/11/09今天
0.27.12026/11/054 天前
0.27.02026/11/036 天前
0.26.02026/10/3010 天前
0.25.02026/10/1921 天前
0.24.02026/09/251 个月前

关于 @codacy/tools-trivy-0 的常见问题

@codacy/tools-trivy-0 是什么?

Trivy adapter — CLI-mode security scanner

如何安装 @codacy/tools-trivy-0?

在项目目录运行 npm install @codacy/tools-trivy-0,或使用 pnpm add / yarn add / bun add。

@codacy/tools-trivy-0 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@codacy/tools-trivy-0 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@codacy/tools-trivy-0 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@codacy/tools-trivy-0 可以商用吗?

@codacy/tools-trivy-0 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@codacy/tools-trivy-0 的下载量有多少?

根据 npm 官方下载统计,@codacy/tools-trivy-0 在 2026/10/10 – 2026/11/08 这 30 天内被下载 11,966 次,日均约 399 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@codacy/tools-trivy-0 还在维护吗?

最新版本 0.28.0 发布于 2026/11/09(今天);至今共发布 36 个版本,其中过去 12 个月发布了 36 个;首次发布于 2026/03/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。