aquasecurity/trivy
Architecture
Trivy is structured as a single Go binary that orchestrates several internal subsystems through a layered pipeline: the CLI parses flags and selects a command, the command builds a scan service, the service drives an artifact handler from pkg/fanal/ to inspect the target, and the resulting blobs are passed to one or more scanners. The same pipeline runs both standalone and in client/server mode, with the boundary drawn at the Backend interface in pkg/scan/service.go.
Top-level scan pipeline
graph TD
User[User / CI / Operator] -->|trivy <command>| CLI[CLI<br/>pkg/commands/app.go]
CLI -->|flag.Options| Runner[Artifact runner<br/>pkg/commands/artifact/run.go]
Runner -->|build| Scanner[scanner.NewScanner<br/>pkg/commands/artifact/scanner.go]
Scanner --> ScanSvc[scan.Service<br/>pkg/scan/service.go]
ScanSvc --> Artifact[artifact.Artifact<br/>pkg/fanal/artifact]
ScanSvc --> Backend{Backend}
Backend -->|standalone| Local[local.Service<br/>pkg/scan/local/service.go]
Backend -->|client| Remote[remote.Service<br/>pkg/rpc/client]
Artifact -->|inspect| Walker[walker<br/>pkg/fanal/walker]
Walker --> Analyzers[analyzer registry<br/>pkg/fanal/analyzer]
Analyzers -->|BlobInfo| Cache[cache<br/>pkg/cache]
Local -->|applier| Applier[applier<br/>pkg/fanal/applier]
Applier --> Cache
Local --> VulnDetect[vulnerability detector<br/>pkg/detector]
Local --> MisconfScan[misconf scanner<br/>pkg/misconf + pkg/iac]
Local --> SecretScan[secret scanner<br/>pkg/fanal/secret]
Local --> LicenseScan[license scanner<br/>pkg/licensing]
VulnDetect --> TrivyDB[(Trivy DB<br/>pkg/db)]
Local --> Report[types.Report]
Remote --> Report
Report -->|VEX filter| VEX[pkg/vex]
Report -->|render| Writer[report writer<br/>pkg/report]
Writer --> Output[stdout / file]Layered design
Trivy is roughly organized into five layers:
- Command layer —
cmd/trivy/main.gocallspkg/commands.Run, which builds a Cobra root command inpkg/commands/app.go(NewApp). Each subcommand (image,fs,repo,vm,k8s,sbom,server,client,convert,clean,module,plugin,vex,auth,registry,config,version) lives next to it in the same file or underpkg/commands/<sub>/. - Flag layer —
pkg/flag/defines flag groups (global, scan, db, image, kubernetes, misconf, license, package, registry, remote, repo, report, rego, secret, vulnerability, cache, clean, AWS) and their bindings to viper. Each command composes a subset of groups;flag.Options.ToOptions()materializes a typed options object that downstream code consumes. - Orchestration layer —
pkg/commands/artifact/run.goandpkg/commands/artifact/scanner.goglue everything together. They build the cache, choose the artifact handler (image, filesystem, repository, VM, SBOM), build the scan service backend (local or remote), and run the scan.pkg/scan/service.gois the small but central type that everyone routes through. - Scan layer — analyzers, scanners, and detectors.
pkg/fanal/analyzer/registers analyzers for OS releases, package managers, language lockfiles, configuration files, secrets, and licenses (seepkg/fanal/analyzer/const.gofor the full enum). Vulnerability detection lives inpkg/detector/andpkg/scan/local/. Misconfiguration scanning runs throughpkg/misconf/and the IaC engine inpkg/iac/. - Reporting layer —
pkg/types/report.godefines theReportstruct.pkg/report/contains writers for table, JSON, SARIF, CycloneDX, SPDX, GitHub dependency snapshot, and Go templates.pkg/vex/filters findings against VEX statements before rendering.
Standalone vs client/server
Standalone scans run the entire pipeline in-process. In client/server mode the same scan.Service runs on both sides but with different Backend implementations:
- Client (
trivy clientortrivy image --server <url>etc.) — runs the artifact handler locally, ships blob digests over Twirp RPC to the server, and receives aScanResponse. Seepkg/rpc/client/andpkg/rpc/convert.go. - Server (
trivy server) — exposes Twirp endpoints fromrpc/scanner/service.protoandrpc/cache/service.proto. The server holds the Trivy DB and the cache. Seepkg/rpc/server/andpkg/commands/server/.
The split lets a single, well-managed server own the multi-gigabyte vulnerability database while many clients only ship blob references.
fanal: the file analysis subsystem
pkg/fanal/ ("file analyzer") is the heart of Trivy's content discovery. It owns:
- Artifact handlers (
pkg/fanal/artifact/) — adapters for image, filesystem, repository, VM, and SBOM scans. Each implementsartifact.Artifact(Inspect+Clean). - Image reader (
pkg/fanal/image/) — reads container images from Docker engine, containerd, podman, registries, and tar archives viago-containerregistry. - Walker (
pkg/fanal/walker/) — walks filesystem trees and image layers, deciding which files to feed to which analyzer. - Analyzer registry (
pkg/fanal/analyzer/) — every analyzer registers itself ininit()viaRegisterAnalyzerorRegisterPostAnalyzer. Analyzers produceBlobInforecords that are stored in the cache keyed by content digest. - Applier (
pkg/fanal/applier/) — merges per-layer blob results into a singleArtifactDetailsnapshot.
The cache (pkg/cache/) means that re-scanning the same image only re-analyzes layers whose content has changed.
Database layer
Trivy ships pre-built read-only databases:
- Trivy DB — vulnerability data downloaded from
ghcr.io/aquasecurity/trivy-db.pkg/db/db.gohandles versioning, OCI download, and bbolt access. The database itself comes from the trivy-db repo. - Trivy Java DB — a separate database for Maven coordinate lookup, in
pkg/javadb/. - Trivy Checks — Rego policies for IaC scanning, downloaded as an OCI bundle by
pkg/policy/policy.go.
Database updates are gated by --skip-db-update, --no-progress, and --db-repository.
Extensibility
Trivy can be extended through three mechanisms:
- Plugins (
pkg/plugin/) — separate binaries discovered bytrivy pluginand exposed as top-level subcommands. Indexed at the trivy-plugin-index. - WebAssembly modules (
pkg/module/) — sandboxed analyzers/post-scanners written in any language that compiles to WASM. The host loads modules with wazero. - Custom IaC checks — Rego policies passed via
--config-policy, evaluated bypkg/iac/rego/.
Default file walker
sequenceDiagram
participant CLI
participant Artifact as artifact.Artifact
participant Walker as walker.FS
participant Analyzer as analyzer.AnalyzerGroup
participant Cache as cache.ArtifactCache
CLI->>Artifact: Inspect(ctx)
Artifact->>Walker: Walk(root, fn)
loop each file
Walker->>Analyzer: AnalyzeFile(path, info, opener)
Analyzer->>Analyzer: dispatch to analyzers (apk, dpkg, gomod, ...)
Analyzer-->>Walker: AnalysisResult
end
Walker->>Analyzer: PostAnalyze(post-analyzers)
Artifact->>Cache: PutBlob(blobID, BlobInfo)
Artifact-->>CLI: artifact.ReferenceFor container images the walker iterates over each layer and stores per-layer blobs; for filesystem and repository scans there is a single synthetic layer.
Languages and platforms
Trivy understands packages in: Ruby (Bundler, Gemspec), Rust (Cargo, rust binaries), PHP (Composer), Java (Maven, Gradle, sbt, JAR), Node.js (npm, yarn, pnpm, bun), .NET (NuGet, dotnet-core), Conda, Python (pip, pipenv, poetry, uv, PyLock), Go (go.mod, Go binaries), C/C++ (Conan), Elixir (mix), Swift (CocoaPods, Swift Package Manager), Dart (Pubspec), Julia. See pkg/fanal/analyzer/language/ and pkg/dependency/parser/.
OS distros covered include Alpine, Amazon Linux, Azure Linux/CBL-Mariner, Debian, Photon, CentOS, Rocky, Alma, Fedora, Oracle, Red Hat, SUSE, Ubuntu (incl. ESM), Bottlerocket, CoreOS, Wolfi, Chainguard. See pkg/fanal/analyzer/os/ and pkg/detector/ospkg/.
IaC providers covered include Terraform (HCL and plan JSON/snapshot), CloudFormation (JSON/YAML), Kubernetes manifests, Helm charts, Dockerfile, Ansible, Azure ARM, and Cloud (AWS, Azure, GCP, Oracle, OpenStack, Nifcloud, DigitalOcean, CloudStack). See pkg/iac/scanners/ and pkg/iac/providers/.
Where to go next
- Read the per-feature pages under
features/for deep dives into vulnerability, misconfiguration, secret, license, SBOM, VEX, Kubernetes, and cloud scanning. - Read the per-system pages under
systems/for fanal, cache, database, RPC, plugin, and WASM module internals. - Read
apps/cliandapps/serverfor the user-facing surface.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.