An sbt plugin that scans your project's dependencies against the OSV (Open Source Vulnerabilities) database and reports known vulnerabilities.
This is the sister project to sbt-dependency-check
offering similar features (we hope to bring feature parity). This project differs a bit from its sister
in the following aspects:
- Doesn't depend on NVD database directly, but on OSV's API (which also aggregates NVD information).
- Has more precise vulnerability search, meaning less false positives on the analysis report.
- Only supports dependencies from the Maven ecosystem, for now. Whereas DependencyCheck, and in turn
sbt-dependency-checksupport way more ecosystems. - By having a simpler design, analysis may be faster than its sister project.
Add the plugin to your project/plugins.sbt:
addSbtPlugin("net.nmoncho" % "sbt-osv" % "<version>")The plugin activates automatically for all JVM projects. No additional enablePlugins(...) call is required.
Runs the dependency vulnerability scan and generates a report.
sbt osvScan [arguments...]
Note: when arguments are provided the whole command has to be wrapped in single quotes for SBT to properly parse it. See examples.
| Argument | Description |
|---|---|
single-report |
Produce one combined report for all aggregated sub-projects instead of one report per project. |
all-projects |
When used together with single-report, gathers dependencies from all projects into a single analysis. |
list-settings |
Print the effective osvScan settings before running the scan. |
list-unused-suppressions |
After the scan completes, log any suppression rules that did not match any found vulnerability. |
original-summary |
Use the DependencyCheck-style summary format (default): lists dependency coordinates and vulnerability IDs. |
all-vulnerabilities-summary |
Summary includes every vulnerability with its CVSS score, whether it breaches the threshold or not. |
offending-vulnerabilities-summary |
Summary includes only vulnerabilities that exceed the osvFailBuildOnCVSS threshold. |
Examples:
# Basic scan of all sub-projects
sbt osvScan
# Single combined report, listing any unused suppressions
sbt 'osvScan all-projects single-report list-unused-suppressions'
# Scan with a summary that shows only failing vulnerabilities
sbt 'osvScan offending-vulnerabilities-summary'
Lists all suppression rules that are active for the project — both those defined inline in build.sbt and those
imported from packaged suppressions.
sbt osvListSuppressions [argument]
| Argument | Description |
|---|---|
| (none) | List suppressions per sub-project (default). |
per-project |
Explicit alias for the default: list suppressions per sub-project. |
all-projects |
List suppressions aggregated across all projects. |
Examples:
sbt osvListSuppressions
sbt 'osvListSuppressions all-projects'
| Setting | Type | Default | Description |
|---|---|---|---|
osvFailBuildOnCVSS |
Double |
11.0 |
Fail the build if any vulnerability has a CVSS score above this threshold. The CVSS scale is 0–10, so the default of 11.0 means the build never fails. See NVD CVSS for details. |
osvSkip |
Boolean |
false |
Skip this project during the vulnerability scan. |
osvOutputDirectory |
File |
crossTarget |
Directory where reports are written. |
osvReportFormats |
Seq[ReportGenerator] |
Seq(HTML) |
Report formats to generate. Currently ReportGenerator.HTML is supported. |
osvAnalysisTimeout |
Option[Duration] |
None |
Maximum time allowed for the analysis. |
osvConnectionTimeout |
Option[Duration] |
None |
URL connection timeout when downloading external data. |
osvConnectionReadTimeout |
Option[Duration] |
None |
URL connection read timeout when downloading external data. |
Controls which dependency scopes are included in the scan.
osvScopes := ScopesSettings(
compile = true, // default
test = false, // default
runtime = true, // default
provided = true, // default
optional = true // default
)| Field | Type | Default | Description |
|---|---|---|---|
compile |
Boolean |
true |
Include Compile scoped dependencies. |
test |
Boolean |
false |
Include Test scoped dependencies. |
runtime |
Boolean |
true |
Include Runtime scoped dependencies. |
provided |
Boolean |
true |
Include Provided scoped dependencies. |
optional |
Boolean |
true |
Include Optional scoped dependencies. |
Controls the scan engine behaviour, including caching and the OSV API endpoint.
osvEngineSettings := EngineSettings(
baseUrl = "https://api.osv.dev",
cacheEviction = Duration.ofDays(1),
dataDirectory = None
)| Field | Type | Default | Description |
|---|---|---|---|
baseUrl |
String |
"https://api.osv.dev" |
Base URL for the OSV API. |
cacheEviction |
Duration |
1 day |
How long a cached API response is considered fresh before querying the API again. |
dataDirectory |
Option[File] |
None |
Where to store the local cache database (osv.db). When None, the plugin resolves a shared directory based on its own JAR location, so all local projects share one cache. |
Configures suppression rules to ignore known false positives.
osvSuppressions := SuppressionSettings(
file = file(".osvignore"),
suppressions = Set(
SuppressionRule("CVE-1234-5678", "Not applicable — we don't use the affected code path", "")
),
packagedEnabled = false,
packagedFilter = SuppressionSettings.PackagedFilter.BlacklistAll
)| Field | Type | Default | Description |
|---|---|---|---|
file |
File |
.osvignore |
Path to an .osvignore suppression file (see Suppression Files). |
suppressions |
Set[SuppressionRule] |
Set.empty |
Inline suppression rules defined directly in build.sbt. Each rule has a name (vulnerability ID), optional comments, and optional source. |
packagedEnabled |
Boolean |
false |
When true, the plugin looks inside dependency JARs for bundled .osvignore files and imports their rules (see Packaged Suppressions). |
packagedFilter |
PackagedFilter |
BlacklistAll |
Predicate that decides which dependency JARs are allowed to contribute packaged suppression rules. |
| Helper | Description |
|---|---|
PackagedFilter.BlacklistAll |
Reject all packaged suppressions (default). |
PackagedFilter.WhitelistAll |
Accept packaged suppressions from every dependency. |
PackagedFilter.ofGav(pred) |
Accept JARs where pred(groupId, artifactId, version) is true. |
PackagedFilter.ofFile(pred) |
Accept JARs where pred(File) is true. |
PackagedFilter.ofFilename(pred) |
Accept JARs where pred(filename) is true. |
PackagedFilter.ofFilenameRegex(regex) |
Accept JARs whose filename matches regex. |
Suppressions tell the plugin to ignore specific vulnerabilities. The default file is .osvignore in the project root,
configurable via osvSuppressions.
Each entry in the file is a block separated by a blank line:
# Optional comment describing why this is suppressed
# @source: name-of-the-jar-that-introduced-this-rule (optional)
CVE-1234-5678
Rules:
- Lines starting with
#are comments. - Lines starting with
# @source:record where the rule came from. - The first non-comment line is the vulnerability ID (e.g. a CVE or GHSA identifier).
- Multiple rules can be listed consecutively without blank lines between them.
Example .osvignore:
# Not affected — we don't call the vulnerable API
CVE-2021-44228
# False positive in test scope only
# @source: my-library.jar
GHSA-xxxx-yyyy-zzzz
Suppression rules can also be defined inline in build.sbt via SuppressionSettings.suppressions:
import net.nmoncho.sbt.osv.SuppressionRule
import net.nmoncho.sbt.osv.settings.SuppressionSettings
osvSuppressions := SuppressionSettings(
suppressions = Set(
SuppressionRule(
name = "CVE-2021-44228",
comments = "Not affected — we don't call the vulnerable API",
source = ""
)
)
)Libraries can bundle an .osvignore file inside their JAR to ship suppression rules alongside their code.
When packagedEnabled = true, the plugin extracts and imports those rules automatically.
Use packagedFilter to restrict which JARs may contribute rules:
osvSuppressions := SuppressionSettings(
packagedEnabled = true,
packagedFilter = SuppressionSettings.PackagedFilter.ofGav { (org, name, _) =>
org == "com.example" && name.startsWith("my-library")
}
)To ship suppression rules inside your own library, set packagedEnabled = true in that library's build.
The plugin will generate the .osvignore resource file from osvSuppressions.suppressions automatically at compile time.
This project is licensed under the MIT License.