How OSV-Scanner Analyzes Transitive Dependencies for Vulnerabilities
OSV-Scanner analyzes transitive dependencies by automatically enabling a "transitive" enricher preset that uses the deps.dev resolver library to compute the complete Maven dependency graph, then queries the OSV database for every node in that graph.
The google/osv-scanner tool extends vulnerability detection beyond packages listed directly in your lockfiles to include the full transitive closure of Maven projects. When scanning Java projects, the tool computes the complete dependency tree—encompassing both direct and indirect dependencies—ensuring that vulnerabilities hidden deep within your supply chain are surfaced. This analysis is performed by default for Maven pom.xml files unless explicitly disabled.
The Transitive Enricher Preset
OSV-Scanner implements transitive dependency analysis through a specialized enricher preset defined in internal/scalibrplugin/presets.go at lines 62-71. When a scan initiates, the scanner automatically appends the "transitive" preset to its plugin configuration (unless the user passes --no-resolve), which activates two critical enrichers:
transitivedependency/requirements– Resolves Mavenpom.xmlfiles and parses their version requirement constraints.transitivedependency/pomxml– Resolves the full Maven dependency graph, traversing all transitive edges to build a complete tree.
This preset is injected during plugin initialization in pkg/osvscanner/scan.go (lines 71-73), where the scan driver checks whether transitive resolution has been disabled before adding the enricher to the pipeline.
Maven Graph Resolution via deps.dev
The heavy lifting of dependency resolution is delegated to deps.dev's resolver library (deps.dev/util/resolve). As implemented in internal/depsdev/depsdev.go (lines 19-27), OSV-Scanner maintains a mapping between OSV ecosystem identifiers and deps.dev system coordinates, allowing the resolver to query the correct API endpoints for Maven artifacts.
The resolver walks the entire Maven coordinate space, constructing a graph that includes both direct dependencies and their transitive dependents. By default, the resolver queries the deps.dev API for version and requirement data. However, when you specify --data-source=native, the resolver reads directly from Maven Central or a configured private registry instead of the API.
Vulnerability Database Lookup
After the resolver assembles the complete dependency graph, OSV-Scanner feeds every node—including deeply nested transitive dependencies—into the standard vulnerability checking pipeline. The plugin configuration in pkg/osvscanner/scan.go (lines 50-57) passes registry overrides and data-source flags to the enrichers, ensuring that the resolved coordinates match your specified environment. Each package is then checked against the OSV vulnerability database exactly as direct dependencies are, with results merged into the final scan output.
Controlling Transitive Analysis Behavior
You can control transitive dependency resolution through several command-line flags parsed in the scan driver.
Scan with transitive resolution (default behavior):
osv-scanner scan source ./my-java-project/pom.xml
Disable transitive dependency analysis:
osv-scanner scan source --no-resolve ./my-java-project/pom.xml
Use native Maven Central resolution instead of deps.dev API:
osv-scanner scan source --data-source=native ./my-java-project/pom.xml
Specify a private Maven registry for native resolution:
osv-scanner scan source \
--data-source=native \
--maven-registry=https://my.private.repo/maven2/ \
./my-java-project/pom.xml
Summary
- Automatic enrichment: OSV-Scanner adds the
"transitive"enricher preset by default ininternal/scalibrplugin/presets.go, enabling Maven dependency graph resolution. - deps.dev integration: The resolver library in
internal/depsdev/depsdev.gomaps OSV ecosystems to deps.dev systems and walks the full Maven coordinate space. - Complete graph coverage: Both direct and transitive dependencies are fed to the OSV database, with configuration handled in
pkg/osvscanner/scan.go. - User control: The
--no-resolveflag disables transitive scanning, while--data-source=nativeand--maven-registrycontrol how the resolver fetches package metadata.
Frequently Asked Questions
Which ecosystems support transitive dependency scanning?
Currently, OSV-Scanner supports transitive dependency analysis exclusively for Maven projects using pom.xml files. The transitive enricher preset specifically bundles resolvers for Maven requirements and POM XML parsing, though the architecture may extend to additional ecosystems in future releases.
How do I disable transitive dependency analysis?
Pass the --no-resolve flag to your scan command. According to the source in pkg/osvscanner/scan.go (lines 71-73), this flag prevents the scanner from adding the transitive enricher preset to the plugin list, limiting analysis to only those packages explicitly listed in your lockfile or manifest.
What is the difference between deps.dev API and native resolution?
The deps.dev API (default) queries Google's hosted service for version and dependency metadata, providing comprehensive graph resolution without requiring local Maven installations. Native resolution (--data-source=native) reads directly from Maven Central or your specified --maven-registry, which is useful for air-gapped environments or when scanning against private artifacts not indexed by deps.dev.
Can OSV-Scanner analyze transitive dependencies offline?
Yes, when using --data-source=native combined with a private Maven registry mirroring your dependencies. However, if you rely on the default deps.dev API resolution, the scanner requires internet connectivity to fetch dependency graphs. The --no-resolve option will run completely offline but skips transitive analysis entirely.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →