Safeguard
Developer Tools•

How do you keep test dependencies out of a Gradle SBOM?

A Gradle SBOM scans every resolvable configuration by default. Use includeConfigs and skipConfigs to keep test tooling out of the shipped inventory.

Safeguard Security Team
3 min read

Set includeConfigs and skipConfigs on the CycloneDX Gradle direct task. By default the plugin scans every resolvable configuration, which pulls test and tooling dependencies into the SBOM. List runtimeClasspath and compileClasspath to include, and skip anything matching test, so the SBOM reflects what ships.

Why the default surprises people

Gradle organizes dependencies into configurations: groups such as compile, runtime and test classpaths. The plugin README states that a direct SBOM scans every resolvable project configuration by default. Test frameworks, linters and build helpers can therefore show up beside the libraries you actually ship.

That has two costs. Customers reading the SBOM see components that never run in production. And vulnerability matching produces findings against test only libraries, which adds noise to a triage queue.

Whether you want those entries depends on the audience. An internal inventory of everything the build touches is legitimate. A file sent to a customer should describe the shipped product. Decide per audience, and produce the right file for each.

The two properties

Both are lists of full match regular expressions.

PropertyMeaning
includeConfigsConfigurations to scan. Empty means every resolvable configuration
skipConfigsConfigurations to exclude. Exclusion takes precedence over inclusion

Because matching is a full match, a pattern must cover the whole configuration name. A pattern of test alone will not match testRuntimeClasspath. That is why the README example uses a case insensitive pattern with wildcards on both sides.

An example

Kotlin DSL:

tasks.cyclonedxDirectBom {
    includeConfigs = listOf("runtimeClasspath", "compileClasspath")
    skipConfigs = listOf("(?i).*test.*")
}

Groovy DSL:

tasks.cyclonedxDirectBom {
    includeConfigs = ['runtimeClasspath', 'compileClasspath']
    skipConfigs = ['(?i).*test.*']
}

In a multi-project build, configuration belongs to each task and the plugin does not add an extension, so apply the setting to the direct task in every project that needs it, for instance from a subprojects block in the root build script.

Steps to get it right

  1. Generate the SBOM with defaults and save it.
  2. Add the two properties and generate again.
  3. Diff the two files. Everything that disappeared should be test or tooling only.
  4. If something that does ship disappeared, your include list is too narrow. Add its configuration name.
  5. Keep the settings in version control so the policy is reviewable.

Step 3 is the safety net. A pattern that is too aggressive can drop a runtime dependency, and an SBOM that omits shipped code is a worse problem than one that lists extra tooling.

When to keep test dependencies

Keep them in an internal build inventory if you want to know every component that executes on a developer machine or in CI, since a compromised test dependency can still run code in your pipeline. Many teams therefore produce two files: a shipped product SBOM for customers and a full build inventory for internal monitoring.

Safeguard can ingest both kinds and scan them for known vulnerabilities, with reachability analysis helping you see which findings sit in code your application actually calls. A free scan lets you try it on a project.

Quick check

Why did my pattern not match anything?

The patterns are full matches. A bare word will not match a longer configuration name, so wrap it in wildcards, for example with a leading and trailing wildcard.

Should customers get the test dependencies too?

Usually no. Send a shipped product SBOM and keep the broader build inventory internal, unless a contract asks otherwise.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.