What does Trivy 0.74's --detection-priority comprehensive change compared with the default precise, and when would you turn it on?
answer
- precision versus recall
- OS-installed files: vendor or upstream
- a version range gets its minimum
- Go stdlib guessed from go.mod
basics
~20 sprecise, the default, trusts only distribution advisories for OS-installed files and skips unpinned dependencies; comprehensive adds upstream advisories, scans a range at its minimum and infers Go's stdlib from go.mod, finding more but misfiring more.
solid answer
~50 sThe flag, added in 0.55.0, trades precision for recall. Under `precise` Trivy minimises false positives: software installed by `apt` or `dnf` is matched only against the distribution's advisories, because vendors backport fixes without changing upstream version numbers; a dependency declared as a range such as `>=3.0` with no lockfile is skipped; and the Go standard library is not inferred from `go.mod`. Under `comprehensive` Trivy also consults upstream advisories such as the GitHub Advisory Database for OS-installed software, scans a ranged dependency at the range's minimum, and derives the stdlib version from the lower of the `go` and `toolchain` directives. Turn it on when you suspect false negatives — a distribution advisory lagging a known upstream CVE, a project without a lockfile — preferably as a periodic or comparison run rather than the blocking gate, because every extra finding needs triage.
code
bash · 2 linestrivy fs --format json --output precise.json ./checkout-service
trivy fs --detection-priority comprehensive --format json --output comprehensive.json ./checkout-servicego deeper
Recall that precise is the default and keeps noise low at the cost of missing some issues, while comprehensive finds more and is noisier.
Explain the concrete differences: vendor-only versus upstream advisories for OS-installed files, the range-minimum rule and the go.mod stdlib inference.
Show when a miss justifies comprehensive, how to run it as a comparison pass instead of the gate, and how to triage the extra findings by their false-positive path.
Weigh a noisier configuration's recall against gate credibility across many teams, and decide where a deep pass runs and who triages what it finds.
## The tradeoff the flag names Every scanner balances **false positives** (reporting a vulnerability that is not there) against **false negatives** (missing one that is). Trivy's documentation compares `--detection-priority` to precision and recall: `precise` keeps reports quiet and accepts that some real issues will be missed; `comprehensive` widens the net and accepts noise. The flag was added in 0.55.0, takes `precise` or `comprehensive`, and defaults to `precise` in 0.74. It changes **package detection**, not just reporting, so it can also change the package list in an SBOM generated from the same scan. ## What precise does - **OS-installed software uses the vendor's advisories only.** If `dnf` installed a Python library, Trivy does not analyse that library against upstream advisories. Trivy's documentation walks through the reason: a package at version 2.20.0 looks vulnerable to an upstream flaw fixed in 2.31.0, but the vendor backported the fix into its own 2.20.0 release, so an upstream match would be a false positive. - **Unpinned versions are skipped.** When a manifest says `package-a: ">=3.0"` and no lockfile pins it, Trivy cannot know the installed version and does not guess. - **No stdlib guess from `go.mod`.** The Go toolchain that will build a module is not certain from source alone, so it is left out. ## What comprehensive adds | Situation | `precise` | `comprehensive` | |---|---|---| | Library installed by the OS package manager | vendor advisories only | also upstream advisories, such as the GitHub Advisory Database | | Dependency declared as a range, no lockfile | skipped | scanned at the range's minimum version | | Go module source with `go.mod` | stdlib not reported | stdlib version = lower of `go` and `toolchain` directives, Go 1.21 or later | | Go binary in an image | stdlib detected from the embedded build info | same; the flag is not needed | Each row adds findings that **may** be real and **may** be noise: the upstream advisory may describe a flaw the vendor already backported; the minimum of a range may not be what is installed; the toolchain in CI may be newer than `go.mod` suggests. ## When to turn it on 1. **A suspected miss.** An upstream advisory is public and the distribution has not published yet. `comprehensive` surfaces it from the upstream source while the vendor catches up. 2. **Projects without lockfiles.** Ranges otherwise vanish from the report; scanning the minimum at least tells you whether the floor is vulnerable. 3. **A periodic deep pass.** Running it weekly, or alongside the default scan for comparison, finds blind spots without flooding every pull request. Keeping `precise` as the blocking configuration is the usual choice: a gate whose findings are often false is a gate teams learn to bypass. ## Limits neither mode removes - **Matching is by version only.** Neither mode checks whether vulnerable code is reachable; that is a separate analysis, and Trivy's own Go documentation points to `govulncheck` for stdlib findings. - **Go binaries always carry stdlib findings.** Trivy reads the compiler version embedded in a Go binary and matches the standard library by that version in both modes, without knowing which functions are used, so some findings will not apply. An ignore file or a VEX statement is the documented way to suppress the ones that do not. - **Severity selection is unchanged.** Which source rates a finding is decided separately. ## Reading a comprehensive report When a finding appears only under `comprehensive`, check three things before acting: whether the package came from the OS package manager and the vendor has backported the fix, whether the version was inferred from a range minimum, and whether the stdlib version was inferred from `go.mod`. Each of those is a known false-positive path that the mode chose to accept. ## Rolling it out without losing the team - Start with a **diff, not a gate**: run both modes on a sample of services and count how many findings appear only under `comprehensive`, and why. - Sort the extra findings by their path — upstream advisory, range minimum, `go.mod` stdlib — because each path has a different fix: a lockfile removes range guesses, a vendor advisory or VEX statement settles a backport. - Keep the setting in shared configuration so every pipeline runs the same mode; a mode that differs per team makes reports incomparable. - Re-evaluate after a quarter. If the extra findings are mostly confirmed, the deep pass is earning its noise; if they are mostly backports, the default was right for that estate.
- Does comprehensive mode make Trivy check whether the vulnerable function is actually called?No. Both modes match package versions against advisories; neither builds a call graph. `comprehensive` only widens which packages and advisories are considered. Proving a finding unreachable takes a separate reachability tool, such as `govulncheck` for Go, which Trivy's own documentation suggests for stdlib findings.
- Why does a Go binary in an image report stdlib CVEs even under precise?A Go binary embeds the compiler version, so Trivy knows the stdlib version exactly and matches it in either mode. It cannot know which stdlib functions the program uses, so some findings will not apply; the documented mitigations are a reachability check, an ignore file or a VEX statement.
A smoke detector's sensitivity dial: turning it up catches a smouldering fire sooner but also sounds for burnt toast, and it never makes the detector better at telling the two apart.
saying these in an interview costs you the question
- comprehensive also turns on misconfiguration and secret scanning
- comprehensive performs reachability analysis to confirm each finding
- precise means Trivy reports everything it could possibly find
- comprehensive only adds true positives, so there is no cost to enabling it
- --detection-priority changes which source a finding's severity comes from