Trivy Rootfs vs Filesystem: Understanding the Difference Between Scan Targets

Use trivy rootfs when scanning an unpacked Linux root filesystem (like a container's rootfs or host /) for OS package vulnerabilities, and use trivy filesystem (or trivy fs) when scanning regular project directories containing source code, configuration files, or build artifacts.

The aquasecurity/trivy vulnerability scanner provides two distinct modes for analyzing local directories: rootfs and filesystem. While both commands inspect directory contents, they differ fundamentally in their assumptions about the target structure and optimization strategies. Understanding the difference between Trivy's rootfs and filesystem scan targets ensures you select the appropriate command for container security scans versus traditional software composition analysis.

Core Architectural Differences

Target Kind Constants

In pkg/commands/artifact/run.go, Trivy defines two distinct target type constants that determine scan behavior:

  • TargetRootfs ("rootfs") – Indicates the target is a complete Linux root filesystem
  • TargetFilesystem ("fs") – Indicates the target is a generic directory or project folder

These constants drive the initialization logic at lines 49-55, where the scanner determines whether to apply rootfs-specific optimizations or standard directory traversal.

Command Implementation

The CLI commands are implemented separately in pkg/commands/app.go to handle distinct flag sets and initialization paths:

  • NewRootfsCommand (lines 404-429) – Creates the rootfs subcommand with dedicated rootfsFlags and invokes artifact.Run(..., artifact.TargetRootfs)
  • NewFilesystemCommand (lines 330-360) – Creates the fs subcommand with fsFlags and invokes artifact.Run(..., artifact.TargetFilesystem)

This separation ensures that each mode receives appropriate default configurations and help text tailored to its intended use case.

Walker Behavior and File Analysis

The critical difference lies in pkg/fanal/walker/fs.go, where the rootfs walker expects a real Linux root layout (e.g., /etc/os-release, /var/lib/dpkg, /var/lib/rpm). When scanning only OS packages (--scanners vuln --pkg-types os), this walker reads package database files directly without traversing the entire directory tree.

Conversely, the generic filesystem walker used by trivy fs walks every file under the supplied path to locate language-specific lock files, secrets, and configuration files. This comprehensive traversal is necessary because the locations of these artifacts are unknown and distributed throughout the project structure.

Performance Characteristics

Rootfs Optimization for OS Packages

When executing trivy rootfs --scanners vuln --pkg-types os /path/to/rootfs, Trivy leverages the rootfs structure to bypass full filesystem traversal. The scanner directly accesses the OS package manifests (such as RPM or DPKG databases) and os-release files, significantly reducing scan time for large root filesystems.

This optimization is documented in the rootfs scanning guide and relies on the assumption that the directory mimics a standard Linux root layout.

Filesystem Traversal Requirements

For trivy filesystem, Trivy must walk the entire directory tree because language packages (Node.js, Python, Go), secrets, and misconfigurations can reside anywhere within the project hierarchy. The generic walker cannot assume standard paths and performs comprehensive file discovery unless explicitly restricted with --skip-dirs.

When to Use Each Scan Target

Use trivy rootfs for:

  • Scanning host machines at / or exported container rootfs directories
  • Analyzing filesystems extracted via docker export or podman export
  • Fast OS-package vulnerability detection where Linux distribution databases are present
  • Security assessments of base images or operating system installations

Use trivy filesystem for:

  • Source code repositories and application projects
  • CI/CD pipelines requiring language-specific dependency analysis
  • Secret detection in configuration files or commit histories
  • Misconfiguration scanning in infrastructure-as-code files
  • Build artifact directories containing multiple project types

Practical Code Examples

Scanning an Exported Container Rootfs

Export a container's root filesystem and analyze it using the rootfs target:

docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
trivy rootfs /tmp/rootfs

This command invokes NewRootfsCommandartifact.Run(..., artifact.TargetRootfs), treating /tmp/rootfs as a Linux root filesystem.

Scanning a Project Directory

Analyze a Python application for vulnerabilities, secrets, and licenses:

trivy fs /home/user/my-python-app

This executes NewFilesystemCommandartifact.Run(..., artifact.TargetFilesystem), walking the entire directory tree to discover requirements.txt, Pipfile.lock, and configuration files.

Optimized OS Package Scanning

Perform a fast scan of the host OS without full filesystem traversal:

trivy rootfs --scanners vuln --pkg-types os /

According to the Trivy source code in pkg/fanal/walker/fs.go, this command reads /etc/os-release and package databases directly, skipping the expensive directory walk required for language-specific analysis.

Summary

  • trivy rootfs assumes a Linux root filesystem structure and optimizes for OS package scanning by reading distribution databases directly rather than walking every file.
  • trivy filesystem treats the target as a generic project directory and performs comprehensive traversal to detect language packages, secrets, and misconfigurations distributed throughout the tree.
  • Both commands are defined in pkg/commands/app.go with separate initialization paths (NewRootfsCommand vs NewFilesystemCommand) and target constants (TargetRootfs vs TargetFilesystem).
  • Choose rootfs for container/host filesystem analysis and filesystem for application source code and artifact scanning.

Frequently Asked Questions

Can I use trivy filesystem to scan a container rootfs?

Yes, but it will perform significantly slower for OS package detection. When you run trivy fs on an unpacked rootfs, the generic walker traverses every file rather than reading package databases directly. Use trivy rootfs specifically for rootfs targets to leverage the performance optimizations implemented in pkg/fanal/walker/fs.go.

Why is trivy rootfs faster for OS package scanning?

The rootfs walker in Trivy's source code recognizes standard Linux paths like /var/lib/dpkg and /var/lib/rpm. When scanning with --pkg-types os, it accesses these databases directly without traversing the entire directory tree, while trivy filesystem must walk every directory to locate potential artifacts.

Which command should I use in CI/CD pipelines?

Use trivy filesystem (or trivy fs) for CI/CD pipelines analyzing application source code, dependencies, and infrastructure configurations. Use trivy rootfs only when your pipeline exports and scans container root filesystems or base images as part of the security workflow.

Do both commands support the same vulnerability scanners?

Both commands support vulnerability scanning, secret detection, and misconfiguration checks, but the discovery mechanism differs. The filesystem command is better suited for language-specific scanners that require go.mod, package-lock.json, or similar files, while rootfs excels at OS-level vulnerability detection through direct package manager database access.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →