Wednesday, October 20, 2021

Integration of Dependency Track in Maven/Jenkins : changes in pom.xml

Introduction

Dependency Track (DT) is a great tool one can use in a project in order to track outdated dependency, and most importantly, review vulnerabilities that can affect one of your project dependencies. For more information, you can visit their website.

My company maintains an application using a bunch of 3rd party dependencies, including libraries with frequent releases. Hence, we have interest in using such tool.

Because we wanted to have an analysis run for each version, we worked on integration in our Jenkins server.

This schema explains the workflow between Jenkins, Maven and DT : 

Maven CycloneDX and Jenkins Dependency Track integration

  • 1: CycloneDX is a Maven plugin, and creates a SBOM file, named bom.xml. SBOM files are used to describe both direct and transitive dependencies, and their versions.
  • 2/3 : DependencyTrack plugin for Jenkins will retrieve the produced SBOM file, and will publish it to the DT instance.
  • 4: DT will run an analysis on SBOM file, and will create a report, with a list of vulnerabilities and a risk score.
  • 5: Optionaly, the report can be displayed in the job summary page.

This first article will cover step 1 above.

CycloneDX integration

The first step was to integrate the generation of a bom.xml file during the build process. Two linked constraint had to be kept in mind :

  • bom.xml generation should not slow down developers in their everyday tasks.
  • Only project releases should be analysed for versions and vulnerabilities (i.e. at the end of every sprint, 2 or 3 weeks long).

Integration of plugin is made as follows :

    <plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
<version>2.5.3</version>
<inherited>false</inherited>
<configuration>
<outputFormat>xml</outputFormat>
<skipAttach>true</skipAttach>
<skip>${skip-bom}</skip>
</configuration>
<executions>
<execution>
<id>cylonedx-aggregate</id>
<phase>package</phase>
<inherited>false</inherited>
<goals>
<goal>makeAggregateBom</goal>
</goals>
</execution>
</executions>
</plugin>

Here are the main aspects of the configuration we set up :

  • As our target here is a multi module maven project, we use the makeAggregateBom goal, so we'll have a dependency overview for the whole project, no matter what module uses a dependency.
  • We provide flag skipAttach with value true, so the generated bom.xml files for each project are not seen as generated artifacts (and I don't want them to be published to our internal Nexus when Jenkins runs our release job).
  • Finally, inherited is set to false for the execution, so the plugin just runs once for the root project, not for every single module of the project.

Our release job run on Jenkins uses a specific prod profile, that developers don't use on their local environments. Let's use this to skip generation on local environments : first, I define a new skip-bom property in properties entry of my root project :

<properties>
<!-- other properties go here -->
<skip-bom>true</skip-bom>
</properties>

In the properties section of the prod profile, I change the value of the skipBom property to false.

<profile>
<id>prod</id>
<properties>
<skip-bom>false</skip-bom>
</properties>
</profile>

Finally, I set the skip configuration entry to the current value of skipBom :

<skip>${skip-bom}</skip>

This way, only running the release job will trigger bom.xml generation! We end up with a bom.xml in the target directory.

Next article in the series will cover changes applied to the Jenkins job.

No comments:

Post a Comment