Skip to main content

Sonatype Scan Gradle

Official plugin for scanning Gradle project dependencies using IQ Server.

icon-color.png The Sonatype for Gradle plugin is available on the Gradle Plugin Portal and Maven Central.

Supported Programming Languages

  • Java

  • Kotlin

  • Scala

  • Groovy

Note

Supported Gradle versions are ranges due to a known bug in Gradle for plugins with multi-jar dependencies. See more at GitHub and Gradle.

Using Sonatype Scan Gradle

  • Create/Clone/Download any Gradle project.

  • Edit the build.gradle file by adding the following:

    plugins {
      id 'org.sonatype.gradle.plugins.scan' version '4.0.0' // Update the version as needed
    }
  • Or build.gradle.kts:

    plugins {
      id ("org.sonatype.gradle.plugins.scan") version "4.0.0" // Update the version as needed
    }

Note

Run the plugin tasks with the log level set to INFO using -i or --info to display results in the console:

./gradlew ossIndexAudit --info
./gradlew nexusIQScan --info

IQ Server Scan Task Usage

  • Start a local instance of IQ Server, or get the URL and credentials of a remote one.

  • Configure IQ Server settings inside the nexusIQScan configuration on the file build.gradle e.g.

    Groovy:

    nexusIQScan {
        username = 'admin'
        password = 'pass'
        serverUrl = 'http://localhost:8070'
        applicationId = 'app'
        organizationId = 'orgId' 
        stage = 'build' 
        allConfigurations = false 
        resultFilePath = 'results.json' 
        modulesExcluded = ['module-1', 'module-2']
        dirExcludes = 'some-ant-pattern' 
        dirIncludes = 'some-ant-pattern' 
        variantAttributes = ['com.android.build.api.attributes.ProductFlavor:version': 'prod'] 
        scanTargets = ['package-lock.json', '**/*.lock']
        excludeCompileOnly = true 
    }

    Kotlin:

    nexusIQScan {
        username = "admin"
        password = "pass"
        serverUrl = "http://localhost:8070"
        applicationId = "app"
        organizationId = "orgId"
        stage = "build" 
        isAllConfigurations = false 
        resultFilePath = "results.json" 
        modulesExcluded = listOf("module-1", "module-2")
        dirExcludes = "some-ant-pattern" 
        dirIncludes = "some-ant-pattern" 
        variantAttributes = mapOf("com.android.build.api.attributes.ProductFlavor:version" to "prod")
        scanTargets = listOf("package-lock.json", "**/*.lock")
        excludeCompileOnly = true
    }
  • Open the console on the project's root and run gradle nexusIQScan or  ./gradlew nexusIQScan. You should see the scan report URL.

Supported Task Properties

Property

Required

Description

username

yes

IQ Server username.

Make sure to use a user with the role 'Application Evaluator' in the given IQ Server application.

password

yes

IQ Server password.

serverUrl

yes

IQ Server URL.

applicationId

yes

IQ Server application ID.

organizationId

no

IQ Server organization ID.

If provided, a validation will be done to check if the given application ID exists under the organization ID (please note this is different from the organization name). If the application doesn't exist, then it will be created under the organization.

stage

no

IQ Server stage.

Default value: build.

isAllConfigurations

no

If set to true, the scan includes the dependencies in all resolvable configurations.

By default is false, meaning only 'compileClasspath', 'runtimeClasspath', 'releaseCompileClasspath' and 'releaseRuntimeClasspath' are considered.

resultFilePath

no

Path to a JSON file that will contain the results of the evaluation.

modulesExcluded

no

For multi-module projects, the names of the sub-modules to be excluded from scanning and evaluation. Default value: empty.

dirExcludes

no

Comma separated ant-like glob patterns to select directories/archives that should be excluded.

Suggested for Android projects: '**/classes.jar, **/annotations.zip, **/lint.jar, **/internal_impl-*.jar'.

dirIncludes

no

Comma separated ant-like glob patterns to select directories/archives that should be examined.

variantAttributes

no

For projects using multiple custom variants for the release distribution, a Map can be set with the attributes names and values to match the specific variant. See more at How to Deal with Multiple Release Variants.

Use it only when the plugin can't match a variant on its own

scanTargets

no

Ant-like glob patterns for relative paths (to the project's folder) to select additional files to be scanned and evaluated.

excludeCompileOnly

no

If set to true then dependencies under the 'compileOnly' configuration will be ignored.

Default value: false

IQ Index Task Usage

Allows you to save information about the dependencies of a project into module information (module.xml) files that Sonatype CI tools can use to include these dependencies in a scan.

  • Open the console on the project's root and run gradle nexusIQIndex or  ./gradlew nexusIQIndex.

For multi-module projects, you can configure a list of sub-modules to exclude from indexing.

Groovy:

nexusIQIndex {
     modulesExcluded = ['module-1', 'module-2']
     excludeCompileOnly = true
}

Kotlin:

nexusIQIndex {
     modulesExcluded = listOf("module-1", "module-2")
     excludeCompileOnly = true 
}

Supported Task Properties

Property

Required

Description

modulesExcluded

no

For multi-module projects, the names of the sub-modules to be excluded from scanning and evaluation.

Default value: empty

excludeCompileOnly

no

If set to true, dependencies under the 'compileOnly' configuration will be ignored.

Default value: false

OSS Index Audit Task Usage

OSS Index is transitioning to Sonatype Guide. OSS Index can be used without any extra configuration, but to avoid reaching the limit for anonymous queries every user is encouraged to review the OSS Index Migration to Sonatype Guide guidance and the Sonatype Guide + OSS Index | Evolving Open Source Intelligence page, and use this plugin with your credentials.

Cache can be configured optionally.

If you are using Groovy (build.gradle file):

ossIndexAudit {
    username = 'email'
    password = 'pass'
    allConfigurations = false
    useCache = true 
    cacheDirectory = 'some/path'
    cacheExpiration = 'PT12H'
    proxyConfiguration {
        protocol = 'http' 
        host = 'proxy-host'
        port = 8080 
        authConfiguration.username = 'username' 
        authConfiguration.password = 'password' 
    }
    modulesIncluded = ['module-1', 'module-2']
    modulesExcluded = ['module-1', 'module-2'] 
    variantAttributes = ['com.android.build.api.attributes.ProductFlavor:version': 'prod']
    excludeVulnerabilityIds = ['39d74cc8-457a-4e57-89ef-a258420138c5'] 
    excludeCoordinates = ['commons-fileupload:commons-fileupload:1.3'] 
    excludeCompileOnly = true 
    failOnDetection = true
    outputFormat = 'DEFAULT'
    cycloneDxComponentType = 'LIBRARY' 
    isColorEnabled = false
    showAll = false 
    printBanner = true
}

Or if you are using Kotlin (build.gradle.kts file):

ossIndexAudit {
    username = "email"
    password = "pass"
    isAllConfigurations = false
    isUseCache = true 
    cacheDirectory = "some/path"
    cacheExpiration = "PT12H"
    proxyConfiguration { 
        protocol = "http" 
        host = "proxy-host"
        port = 8080
        authConfiguration.username = "username"
        authConfiguration.password = "password"
    }
    modulesIncluded = listOf("module-1", "module-2")
    modulesExcluded = listOf("module-1", "module-2")
    variantAttributes = mapOf("com.android.build.api.attributes.ProductFlavor:version" to "prod")
    excludeVulnerabilityIds = listOf("39d74cc8-457a-4e57-89ef-a258420138c5")
    excludeCoordinates = listOf("commons-fileupload:commons-fileupload:1.3")
    excludeCompileOnly = true 
    failOnDetection = true
    outputFormat = "DEFAULT"
    cycloneDxComponentType = "LIBRARY" 
    isColorEnabled = false 
    isShowAll = false 
    isPrintBanner = true
}
  • Open the console in the project's root and run: gradle ossIndexAudit or ./gradlew ossIndexAudit. You should see the audit result.

Supported Task Properties

Property

Required

Description

username

no

OSS Index username.

If not provided, anonymous queries will be made.

password

no

OSS Index password.

If not provided, anonymous queries will be made.

isAllConfigurations

no

If true, the scan includes the dependencies in all resolvable configurations.

By default is false, meaning only 'compileClasspath', 'runtimeClasspath', 'releaseCompileClasspath' and 'releaseRuntimeClasspath' are considered.

isUseCache

no

Default value: true.

cacheDirectory

no

By default it uses the user data directory (according to your OS).

cacheExpiration

no

It must follow the Joda Time specification at joda-time Duration specs.

Default value: PT12H (12 hours)

proxyConfiguration

no

Extra configuration when running behind a proxy without direct internet access.

protocol

no

It can be 'http' (default) or 'https'.

host

no

Hostname for the proxy.

port

no

Proxy port.

authConfiguration.username

no

The username for the proxy authentication (if credentials are required).

authConfiguration.password

no

The password for the proxy authentication (if credentials are required).

modulesIncluded

no

For multi-module projects, the names of the sub-modules to include for auditing. If not specified all modules are included.

Default value: empty

modulesExcluded

no

For multi-module projects, the names of the sub-modules to be excluded from auditing. If not specified no modules are excluded. This value is processed after 'modulesIncluded' if both are specified.

Default value: empty

variantAttributes

no

For projects using multiple custom variants for the release distribution, a Map can be set with the attributes names and values to match the specific variant. See more at How to Deal with Multiple Release Variants.

Use it only when the plugin can't match a variant on its own

excludeVulnerabilityIds

no

The list containing vulnerabilityIDs to be ignored - ossIndexAudit can be configured to exclude vulnerabilities from matching.

Default value: empty

excludeCoordinates

no

The list contains the coordinates of components which, if vulnerable, should be ignored. Default value: empty

excludeCompileOnly

no

If set to true, dependencies under the 'compileOnly' configuration will be ignored.

Default value: false

failOnDetection

no

By default, the audit scan will fail the task/build if any vulnerabilities are found.

Set this to 'false' to allow the task to succeed even when vulnerabilities are detected. Use this option only if you rely on an external tool to further process the output of this plugin (see below for output options).

outputFormat

no

Accepted values: 'DEFAULT', 'DEPENDENCY_GRAPH' - prints dependency graph showing direct/transitive dependencies, 'JSON_CYCLONE_DX_1_4' - prints a CycloneDX 1.4 SBOM in JSON format.

Default value: DEFAULT

cycloneDxComponentType

no

Only used when outputFormat = 'JSON_CYCLONE_DX_1_4' to define the type of component this project is for the BOM metadata with possible values: 'LIBRARY', 'APPLICATION', 'FRAMEWORK', 'CONTAINER', 'OPERATING_SYSTEM', 'DEVICE', 'FIRMWARE' and 'FILE'.

Default value: LIBRARY

isColorEnabled

no

If set and outputFormat \= "DEFAULT", it prints vulnerability description in color.

Default value: true

isShowAll

no

If true, it prints out all dependencies.

Default value: false - only dependencies with vulnerabilities will be printed out.

isPrintBanner

no

If true, it will print an ASCII text banner.

Default value: true

Sensitive Data - Usage Example

Sometimes it's not desirable to keep sensitive data stored on build.gradle. For such cases it's possible to use project properties (-P arguments) or system properties (-D arguments or injected from a tool) from command line or environment variables when running the nexusIQScan or ossIndexAudit tasks.

Here is an example using project properties for the credentials.

Groovy:

nexusIQScan {
    username = project['username']
    password = project['password']
    serverUrl = 'http://localhost:8070'
    applicationId = 'app'
}

ossIndexAudit {
    username = project['username']
    password = project['password']
}

Kotlin:

nexusIQScan {
    username = project["username"]
    password = project["password"]
    serverUrl = "http://localhost:8070"
    applicationId = "app"
}
ossIndexAudit {
    username = project["username"]
    password = project["password"]
}

On command line:

./gradlew nexusIQScan -Pusername=admin -Ppassword=pass

./gradlew ossIndexAudit -Pusername=admin -Ppassword=pass

Each property name can be set as needed.

Here is an example using system properties for the credentials (Groovy):

nexusIQScan {
    username = System.properties['username']
    password = System.properties['password']
    serverUrl = 'http://localhost:8070'
    applicationId = 'app'
}

ossIndexAudit {
    username = System.properties['username']
    password = System.properties['password']
}

As mentioned above the values can be set from the command line using -D arguments or injected via a tool (CI/CD for instance).

Finally, this is how environment variables can be used (usually values are injected from the local environment or by a CI tool).

Groovy:

nexusIQScan {
    username = System.getenv('username')
    password = System.getenv('password')
    serverUrl = 'http://localhost:8070'
    applicationId = 'app'
}

ossIndexAudit {
    username = System.getenv('username')
    password = System.getenv('password')
}

Kotlin:

nexusIQScan {
    username = System.getenv("username")
    password = System.getenv("password")
    serverUrl = "http://localhost:8070"
    applicationId = "app"
}

ossIndexAudit {
    username = System.getenv("username")
    password = System.getenv("password")
}

Multi-module projects

Just apply the plugin on the root project and all sub-modules will be processed and the output will be a single report with all components found in each module. This includes Android projects.

How to Deal with Multiple Release Variants

This plugin makes its best effort to find the release (production) configuration and variant to get the dependencies to analyze.

However, a Gradle project can have multiple custom release variants and the plugin might not be able to tell Gradle which one to pick, resulting in an error like this:

> Could not resolve all dependencies for configuration 'sonatypeCopyConfiguration0'.
   > Could not resolve project :common-lib.
     Required by:
         project :app
      > The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release'. However we cannot choose between the following variants of project :baseapp:
          - ciReleaseRuntimeElements
          - prodReleaseRuntimeElements
        All of them match the consumer attributes:
          - Variant 'ciReleaseRuntimeElements' capability common-lib:1.0.0 declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.2.2' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'ci' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'ciRelease' but the consumer didn't ask for it
                  - Provides a library but the consumer didn't ask for it
                  - Provides attribute 'org.gradle.jvm.environment' with value 'android' but the consumer didn't ask for it
          - Variant 'prodReleaseRuntimeElements' capability common-lib:1.0.0 declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release':
              - Unmatched attributes:
                  - Provides attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.2.2' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'prod' but the consumer didn't ask for it
                  - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'prodRelease' but the consumer didn't ask for it
                  - Provides a library but the consumer didn't ask for it
                  - Provides attribute 'org.gradle.jvm.environment' with value 'android' but the consumer didn't ask for it

From that output we can see the value of the attribute com.android.build.api.attributes.ProductFlavor:version can be used to distinguish between the available variants.

Since attribute names and values can be customized on each project, this plugin allows you to set the attributes needed to match the right variant using the property variantAttributes.

In the example above, the following configuration would allow the plugin to choose the prodReleaseRuntimeElements variant:

Groovy:

nexusIQScan {
    variantAttributes = ['com.android.build.api.attributes.ProductFlavor:version': 'prod']
}

ossIndexAudit {
    variantAttributes = ['com.android.build.api.attributes.ProductFlavor:version': 'prod']
}

Kotlin:

nexusIQScan {
    variantAttributes = mapOf("com.android.build.api.attributes.ProductFlavor:version" to "prod")
}

ossIndexAudit {
    variantAttributes = mapOf("com.android.build.api.attributes.ProductFlavor:version" to "prod")
}

For more information about attributes matching for variant selection, see: https://docs.gradle.org/current/userguide/variant_model.html#sec:variant-select-errors