skip to content

Scanning Targets

Trivy's subcommand decides what it reads: installed packages and binaries in an image, lockfiles in a repo, manifests in a cluster. Interviewers ask why one codebase gives different findings.

on this pageshow

explore

questions

5

Why does Trivy 0.74 report different vulnerabilities for one service when you run `trivy fs`, `trivy repo`, `trivy image` and `trivy rootfs` against it?

level: middleimportance: must knowfreq 34%

answer

  1. pre-build versus post-build evidence
  2. each subcommand switches analyzers off
  3. most lockfiles skipped by image and rootfs
  4. binaries and JARs ignored by fs
  5. repo drops OS packages entirely

basics

~20 s

Each Trivy subcommand enables a different set of analyzers: fs and repo read pre-build lockfiles, while image, rootfs and vm read post-build evidence such as OS package databases, installed package metadata, Go binaries and JARs, and skip most lockfiles.

solid answer

~40 s

Trivy 0.74 sorts targets into pre-build and post-build. `trivy fs` and `trivy repo` read lockfiles and manifests such as `package-lock.json`, `poetry.lock`, `go.mod` and `pom.xml`, and switch off the analyzers for installed packages, built binaries and JARs; `repo` also drops OS packages and accepts a remote Git URL. `trivy image`, `trivy rootfs` and `trivy vm` do the opposite: most lockfile analyzers are disabled, and they read the OS package database, installed metadata such as `.dist-info/METADATA` or each installed `package.json`, Go and Rust binaries and `JAR/WAR/PAR/EAR` files. So the image scan adds the base image's OS packages and the Go standard library the binary was compiled with, while the `fs` scan can list dependencies that never reach the image. Neither answer is wrong; they read different evidence.

go deeper

for a junior

Remember the split: fs and repo read lockfiles from source, while image, rootfs and vm read what is installed. Different files in, different findings out.

for a middle

Explain which analyzers each subcommand switches off: lockfiles for image and rootfs, installed metadata, binaries and JARs for fs, plus OS packages for repo.

for a senior

Use the difference deliberately: a source scan to stop a dependency before merge, an image scan by digest to prove what ships, and rootfs for hosts. Explain a longer image report without calling it noise.

for a principal

Decide which evidence the organisation treats as authoritative for release decisions, and keep the source scan as an early warning rather than a substitute for scanning the shipped artefact.

## Two kinds of evidence Trivy 0.74 does not scan "a service"; it scans a **target**, and the subcommand you choose decides which **analyzers** run against it. The documentation splits targets into two groups: - **Pre-build** targets, such as a source checkout. Trivy reads the files a build *uses*: lockfiles and manifests. - **Post-build** targets, such as a container image. Trivy reads what a build *produced and installed*: the OS package database, installed package metadata, compiled binaries and archives. The same codebase therefore yields different findings simply because each subcommand reads a different record of what the software contains. ## What each subcommand reads | Subcommand | Typical target | Reads | Switched off in 0.74 | |---|---|---|---| | `trivy fs` | a project directory or a single lockfile | lockfiles and manifests (`package-lock.json`, `yarn.lock`, `poetry.lock`, `requirements.txt`, `go.mod`, `pom.xml`, `Gemfile.lock`) | installed-package analyzers (gemspec, Python egg and wheel metadata, installed `package.json`, Go and Rust binaries, JARs) and SBOM files | | `trivy repo` | a local path or a remote Git URL | the same lockfiles; library packages only | OS analyzers, the `os` package type, installed-package analyzers and SBOM files | | `trivy image` | a container image | OS packages, installed language metadata, Go and Rust binaries, `JAR/WAR/PAR/EAR` | most lockfile analyzers | | `trivy rootfs` | an installed filesystem: a host's `/`, an unpacked image, a Dockerfile stage | the same post-build view as `image` | most lockfile analyzers | | `trivy vm` | a VM disk image, `ami:` or `ebs:` | the post-build view of the disk | most lockfile analyzers | A few formats are read by every target, which is why the table says *most*, because they are both a build input and something that ships: `Cargo.lock`, the .NET files (`packages.lock.json`, `.deps.json`, `packages.config`) and Julia's `Manifest.toml`. ## Why one service gives four answers 1. **OS packages.** Only the post-build scans see the base image's distribution packages. `trivy repo` excludes them outright, and a source checkout has no package database for `trivy fs` to read. 2. **Lockfile entries that never ship.** A lockfile can list packages that the final build does not install. For several ecosystems (npm and yarn among them) development dependencies are left out by default and come back only with `--include-dev-deps`. 3. **Compiled-in versions.** A Go binary records the toolchain that built it, so an image scan matches standard-library advisories against the real Go version. From `go.mod` Trivy can only infer that version, and only in the opt-in comprehensive detection mode. 4. **Archives versus manifests.** A fat JAR in an image is read as the JAR it is; the source tree offers `pom.xml`, whose resolution may differ from what was packaged. How a lockfile view and a shipped-artefact view differ as inventories is a supply-chain subject in its own right; the point here is which files each Trivy subcommand opens. ## Choosing the target for the job - **Pull-request checks on source:** `trivy fs .` (the docs say so explicitly for local projects in CI) or `trivy repo` for a remote URL with `--branch`, `--commit` or `--tag`. - **What will actually run:** `trivy image` on the built image, ideally by digest. - **A host or an unpacked filesystem:** `trivy rootfs /`, which reads installed packages rather than lockfiles. `trivy rootfs --pkg-types os --scanners vuln /` avoids a full file traversal when only OS packages matter. - **A VM disk:** `trivy vm disk.vmdk`, or `ami:` and `ebs:` targets for cloud disk snapshots. Live cloud-account configuration is not a target of the core binary any more: the `aws` subcommand was removed in 0.53.0, and that job moved to the separate Trivy AWS plugin. ## Reading the difference correctly When an engineer asks why the image report is longer than the repository report, the honest answer is a list of evidence sources, not a bug. Run both: the source scan catches a vulnerable dependency before it is built, and the image scan proves what shipped, including what the base image brought along.

  • When would you choose `trivy rootfs` over `trivy fs` for a directory?
    When the directory is an installed system rather than a source tree: a host's `/`, an unpacked image filesystem, or a scan run inside a Dockerfile stage after packages are installed. `rootfs` reads the OS package database and installed metadata and ignores lockfiles; `fs` does the reverse, and the Trivy docs recommend `fs` for local projects in CI.
  • An old runbook runs `trivy aws` to check an account's live configuration. What happens with Trivy 0.74?
    It fails: 0.53.0 removed the `aws` subcommand from the core binary, a breaking change in its changelog. Live account scanning now lives in the separate Trivy AWS plugin, installed through `trivy plugin install`. `trivy vm` with `ami:` or `ebs:` is still in core, but it scans a disk image's contents, not the account's configuration.
  • Why can a Go standard-library CVE appear in the image scan but not in the `fs` scan of the same repository?
    The compiled binary records the Go toolchain version, so `trivy image` matches standard-library advisories against it. From `go.mod` Trivy can only guess the version from the `go` and `toolchain` directives, and it does so only when the comprehensive detection priority is chosen; the default is precise.

A lockfile is the shopping list and an image is the pantry. Reading the list (trivy fs) tells you what you meant to buy, including items never brought home; reading the shelf labels (trivy image) shows what is really there, including jars that came with the house.

saying these in an interview costs you the question

  • trivy fs and trivy image read the same files, only from different places.
  • An image scan reads package-lock.json if the file was copied into the image.
  • trivy repo also reports the OS packages of the base image the code builds on.
  • trivy rootfs is just another name for trivy fs.
  • A clean source-tree scan proves the shipped image is clean.
open as a page

In Trivy 0.74, which checks does `trivy image` or `trivy fs` run by default, and how does `--scanners` change them?

level: juniorimportance: should knowfreq 24%

basics

~20 s

Trivy 0.74's image, fs, repo, rootfs and vm subcommands default to vulnerability and secret scanning. Misconfiguration and license checks stay off until listed in --scanners, and that flag replaces the default list rather than adding to it.

open as a page

Why can Trivy 0.74's `trivy image` scan a different copy of the same tag on a laptop than in CI, and which flags pin that choice?

level: middleimportance: should knowfreq 15%

basics

~20 s

trivy image scans the first copy it finds, trying Docker Engine, containerd, Podman and then the registry, so a stale local pull or another architecture can be scanned. --image-src fixes the source order and --platform chooses the architecture.

open as a page

In Trivy 0.74 client/server mode, what does `trivy server` do, what still runs on the client, and where does each side keep its cache?

level: seniorimportance: should knowfreq 12%

basics

~20 s

The Trivy server holds and refreshes the vulnerability database and matches packages; the client still pulls the artefact, extracts packages and runs secret and misconfiguration checks. Both use --cache-dir, and several servers must share a Redis scan cache.

open as a page

What does a `trivy k8s` run in Trivy 0.74 read and create in a cluster, and how do you keep its report usable?

level: seniorimportance: nice to knowfreq 9%

basics

~20 s

trivy k8s lists cluster resources through a kubeconfig context, scans each workload image and manifest, checks RBAC and control-plane component versions, and by default runs a node-collector job on every node. --report summary and namespace or kind filters keep the output readable.

open as a page