Skip to content

CycloneDX/cyclonedx-gradle-plugin

CycloneDX Gradle Plugin

Build Status Gradle Plugin License Website Slack Invite Group Discussion Twitter

The CycloneDX Gradle plugin creates an aggregate of all direct and transitive dependencies of a project and creates a valid CycloneDX SBOM. CycloneDX is a lightweight software bill of materials (SBOM) specification designed for use in application security contexts and supply chain component analysis.

Table of Contents

Features

  • âś… Per-Project SBOMs: Generate individual SBOM documents for each project
  • âś… Multi-Project Aggregation: Create consolidated SBOMs for entire project hierarchies
  • âś… Multiple Output Formats: JSON and XML format support with CycloneDX specification compliance
  • âś… Flexible Configuration: Include/exclude specific dependencies, configurations, and projects
  • âś… Metadata Enrichment: Include license information, build system details, and organizational data
  • âś… Gradle Integration: Native Gradle task integration with proper incremental build support
  • âś… Dependency Analysis: Analyzes all direct and transitive resolved dependencies (not just declared ones)

Installation

Apply the plugin to your project:

Groovy DSL:

plugins {
    id 'org.cyclonedx.bom' version '3.0.0-alpha-0'
}

Kotlin DSL:

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
}

Important

Plugin will register aggregate task cyclonedxBom only in the project where it is applied. This task aggregates SBOMs from the project and all subprojects in multi-project builds.

Important

Although the plugin is compatible with Java versions starting from 8, support of all versions prior to 17 is deprecated it will be removed in future releases.

Quick Start

  1. Apply the plugin to your root project
  2. Run the SBOM generation task:
# Generate per-project SBOMs
./gradlew cyclonedxDirectBom

# Generate aggregated SBOM (for multi-project builds)
./gradlew cyclonedxBom
  1. Find your SBOM files:
    • Per-project: build/reports/cyclonedx-direct/bom.{json,xml}
    • Aggregated: build/reports/cyclonedx/bom.{json,xml}

Usage

Per-Project SBOM Generation

The cyclonedxDirectBom task generates individual SBOM documents for each project in your build. This is useful when you want to analyze dependencies at a granular level.

# Generate SBOMs for all projects
./gradlew cyclonedxDirectBom

# Generate with verbose logging
./gradlew cyclonedxDirectBom --info

# Generate for specific project only
./gradlew :subproject:cyclonedxDirectBom

Output locations:

  • JSON: {project}/build/reports/cyclonedx-direct/bom.json
  • XML: {project}/build/reports/cyclonedx-direct/bom.xml

Multi-Project Aggregation

The cyclonedxBom task creates a single, consolidated SBOM containing dependencies from all projects in your build. This provides a complete view of your application's supply chain.

# Generate aggregated SBOM
./gradlew cyclonedxBom

Output locations:

  • JSON: build/reports/cyclonedx/bom.json
  • XML: build/reports/cyclonedx/bom.xml

Configuration

Configure the plugin using the cyclonedxBom extension in your root project's build file:

cyclonedxBom {
    // Configuration properties
}

Configuration Properties

Property Type Default Description
includeConfigs List<String> [] (all configurations) Configurations to include in SBOM generation. Supports regex patterns
skipConfigs List<String> [] Configurations to exclude from SBOM generation. Supports regex patterns
skipProjects List<String> [] Project names to exclude from aggregated SBOM generation
projectType String "library" Type of project ("application", "library", "framework", "container", etc.)
schemaVersion SchemaVersion VERSION_16 CycloneDX schema version to use
includeBomSerialNumber boolean true Include unique BOM serial number
includeLicenseText boolean true Include full license text in components
includeMetadataResolution boolean true Include complete metadata resolution for components
includeBuildSystem boolean true Include build system URL from CI environment
buildSystemEnvironmentVariable String - Custom environment variable for build system URL
componentVersion String Project version Override the main component version
componentName String Project name Override the main component name
componentGroup String Project group Override the main component group
organizationalEntity OrganizationalEntity - Organizational metadata for the project, including name, URLs, and contacts
externalReferences List<ExternalReference> Git remote URL External references for the project, such as documentation or issue trackers
licenseChoice LicenseChoice - License information for the main component

Output Configuration

Configure output files using explicit properties for each task. The plugin supports both JSON and XML formats simultaneously or individually:

allprojects {
    tasks.withType<CyclonedxDirectTask> {
        // Configure JSON output (default: build/reports/cyclonedx/bom.json)
        jsonOutput.set(file("build/reports/cyclonedx/${project.name}-bom.json"))
        // Configure XML output (default: build/reports/cyclonedx/bom.xml)
        xmlOutput.set(file("build/reports/cyclonedx/${project.name}-bom.xml"))
    }
    tasks.withType<CyclonedxAggregateTask> {
        // Configure JSON output (default: build/reports/cyclonedx-aggregate/bom.json)
        jsonOutput.set(file("build/reports/cyclonedx-aggregate/${project.name}-bom.json"))
        // Configure XML output (default: build/reports/cyclonedx-aggregate/bom.xml)
        xmlOutput.set(file("build/reports/cyclonedx-aggregate/${project.name}-bom.xml"))
    }
}

Disabling Output Formats

To generate only one format, you can disable the other by unsetting its convention:

tasks.withType<CyclonedxDirectTask> {
    // Generate only JSON format
    xmlOutput.unsetConvention()
    // Or generate only XML format
    jsonOutput.unsetConvention()
}
tasks.withType<CyclonedxAggregateTask> {
    // Generate only JSON format
    xmlOutput.unsetConvention()
    // Or generate only XML format
    jsonOutput.unsetConvention()
}

Advanced Configuration

cyclonedxBom {
    // Include only runtime dependencies
    includeConfigs = ["runtimeClasspath", "compileClasspath"]

    // Exclude all test-related configurations using regex
    skipConfigs = [".*test.*", ".*Test.*"]

    // Skip specific projects from aggregation
    skipProjects = ["test-utils", "integration-tests"]

    // Set application metadata
    projectType = "application"
    componentName = "my-microservice"
    componentVersion = "2.0.0-SNAPSHOT"

    // Schema configuration
    schemaVersion = org.cyclonedx.model.schema.SchemaVersion.VERSION_16

    // Metadata options
    includeBomSerialNumber = true
    includeLicenseText = true
    includeMetadataResolution = true
    includeBuildSystem = true

    // Custom build system URL template
    buildSystemEnvironmentVariable = '${CI_PIPELINE_URL}/jobs/${CI_JOB_ID}'

    // Custom output locations
    jsonOutput = file("build/reports/sbom/${project.name}-sbom.json")
    xmlOutput = file("build/reports/sbom/${project.name}-sbom.xml")
}

Tasks

Task Description Scope Type Output Location
cyclonedxDirectBom Generates per-project SBOM documents Individual projects CyclonedxDirectTask build/reports/cyclonedx-direct/
cyclonedxBom Generates aggregated SBOM for multi-project builds Entire project hierarchy CyclonedxAggregateTask build/reports/cyclonedx/

Both tasks support:

  • Incremental builds
  • Parallel execution
  • Configuration cache
  • Build cache

Examples

Simple Java Application

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
    id("application")
}

cyclonedxBom {
    projectType = "application"
    includeConfigs = listOf("runtimeClasspath")
}

Multi-Project with Filtering

// Root build.gradle.kts
plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
}

cyclonedxBom {
    // Exclude test and development subprojects
    skipProjects = listOf("test-utils", "dev-tools", "benchmarks")

    // Include only production dependencies
    includeConfigs = listOf("runtimeClasspath", "compileClasspath")
    skipConfigs = listOf("testRuntimeClasspath", "testCompileClasspath")

    // Application metadata
    projectType = "application"
    componentGroup = "com.example"
    componentName = "my-enterprise-app"
    componentVersion = "1.0.0"

    // Enable build system tracking
    includeBuildSystem = true
}

Organizational Entity

import org.cyclonedx.model.*
import org.cyclonedx.model.schema.*

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
    id("java")
}

cyclonedxBom {
    // Project configuration
    projectType = "application"
    schemaVersion = SchemaVersion.VERSION_16

    // Component details
    componentName = "acme-payment-service"
    componentVersion = "3.1.0"

    // Dependency filtering
    includeConfigs = listOf("runtimeClasspath", "compileClasspath")
    skipConfigs = listOf(".*test.*", ".*benchmark.*")

    // Metadata options
    includeBomSerialNumber = true
    includeLicenseText = true
    includeMetadataResolution = true
    includeBuildSystem = true
    buildSystemEnvironmentVariable = "\${BUILD_URL}"

    // Organizational metadata
    organizationalEntity = OrganizationalEntity().apply {
        name = "ACME Corporation"
        urls = listOf("https://www.acme.com", "https://security.acme.com")
        addContact(OrganizationalContact().apply {
            name = "Security Team"
            email = "[email protected]"
            phone = "+1-555-SECURITY"
        })
    }
}

External Reference Example

import org.cyclonedx.model.*

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
    id("java")
}

cyclonedxBom {
    externalReferences = listOf(
        ExternalReference().apply {
            url = "https://cyclonedx.org/"
            type = ExternalReference.Type.WEBSITE
        }
    )
}

Licenses Example

import org.cyclonedx.model.*

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
    id("java")
}
cyclonedxBom {
    // Specify licenses for the main component
    licenseChoice = LicenseChoice().apply {
        addLicense(License().apply {
            name = "Apache-2.0"
            url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
        })
    }
}

CI Metadata Example

plugins {
    id("org.cyclonedx.bom") version "3.0.0-alpha-0"
    id("java")
}

cyclonedxBom {
    projectType = "application"

    // Dynamic versioning for CI/CD
    componentVersion = System.getenv("BUILD_VERSION") ?: project.version.toString()

    // Build system integration
    includeBuildSystem = true
    buildSystemEnvironmentVariable = "\${BUILD_URL}"

    // Conditional configuration based on environment
    if (System.getenv("CI") == "true") {
        // CI environment - include all runtime dependencies
        includeConfigs = listOf("runtimeClasspath", "compileClasspath")
        skipConfigs = listOf("testRuntimeClasspath")
    } else {
        // Local development - lighter analysis
        includeConfigs = listOf("runtimeClasspath")
    }
}

tasks.withType<CyclonedxAggregateTask> {
    // Timestamped output artifacts (WARNING: will disable Gradle cache)
    jsonOutput = file("build/artifacts/sbom-${Instant.now()}.json")
    xmlOutput.unsetConvention()
}

For detailed metadata structure information, refer to the CycloneDX specification.

Gradle Support

The following table provides information on the version of this Gradle plugin, the Gradle version supported.

Version Gradle Version
3.0.x Gradle 8.4+
2.x.x Gradle 8.0+
1.x.x Gradle <8.0

CycloneDX Schema Support

The following table provides information on the version of this Gradle plugin, the CycloneDX schema version supported, as well as the output format options. Use the latest possible version of this plugin that is the compatible with the CycloneDX version supported by the target system.

Version Schema Version Format(s)
3.x.x CycloneDX v1.6 XML/JSON
2.x.x CycloneDX v1.6 XML/JSON
1.10.x CycloneDX v1.6 XML/JSON
1.9.x CycloneDX v1.6 XML/JSON
1.8.x CycloneDX v1.5 XML/JSON
1.7.x CycloneDX v1.4 XML/JSON
1.6.x CycloneDX v1.4 XML/JSON
1.5.x CycloneDX v1.3 XML/JSON
1.4.x CycloneDX v1.3 XML/JSON
1.2.x CycloneDX v1.2 XML/JSON
1.1.x CycloneDX v1.1 XML
1.0x CycloneDX v1.0 XML

Copyright & License

CycloneDX Gradle Plugin is Copyright (c) OWASP Foundation. All Rights Reserved.

Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the LICENSE file for the full license.