Integrating Dependency Track with GitLab CI for Software Composition Analysis

The modern software supply chain is inherently complex, relying on a vast web of open-source libraries and third-party modules. As projects scale, the risk of incorporating dependencies with known vulnerabilities increases, making Software Composition Analysis (SCA) a critical component of the DevSecOps lifecycle. One of the most effective ways to manage this risk is by integrating Dependency Track—an intelligent Component Analysis platform—directly into the GitLab CI/CD pipeline. This integration allows organizations to transition from reactive security patching to a proactive posture where every build is audited for vulnerabilities in real-time. By generating a Software Bill of Materials (SBOM) in the CycloneDX format and transmitting it to a Dependency Track instance, developers gain a centralized view of their dependency graph, enabling them to track transitive dependencies and respond to newly disclosed CVEs without needing to manually trigger pipeline runs.

The Architecture of Dependency Scanning in GitLab

GitLab provides a sophisticated ecosystem for identifying security vulnerabilities within a project's dependencies, including runtime, development, and nested transitive packages. The evolution of these tools has led to several distinct scanning methodologies, each designed for different organizational needs.

The primary shift in recent GitLab versions is the move toward SBOM-first workflows. Dependency scanning using SBOM is currently the recommended method for new projects. This approach separates the detection of dependencies (the creation of the SBOM) from the analysis of those dependencies (matching them against the GitLab Advisory Database).

The current landscape of scanning methods is detailed in the following table:

Method Status Trigger Best for
Dependency Scanning using SBOM General Availability Pipeline New projects, SBOM-first workflows
Continuous Dependency Scanning General Availability Advisory DB update Catching newly disclosed CVEs without re-running pipelines
Dependency Scanning with Gemnasium Deprecated (17.9) Pipeline Existing projects pending migration
Analyze dependencies for behaviors Experiment Pipeline Detecting malicious package behavior

The transition from Gemnasium to SBOM-based scanning represents a strategic shift in how GitLab handles security. While Gemnasium was the original pipeline-based analyzer, the new analyzer focuses on producing CycloneDX SBOM reports. This allows for better interoperability with other tools, such as Dependency Track, and enables Continuous Dependency Scanning. Continuous scanning is particularly powerful because it rescans the SBOM from the latest successful pipeline on the default branch whenever the GitLab Advisory Database is updated, ensuring that zero-day vulnerabilities are surfaced immediately without requiring a new code commit or pipeline execution.

Implementing Dependency Track via GitLab CI

Integrating a dedicated Dependency Track instance provides a level of granularity and historical tracking that exceeds standard pipeline reports. To achieve this integration, the pipeline must be configured to generate a CycloneDX SBOM and then push that data to the Dependency Track API.

Essential Configuration Variables

For the integration to function, specific environment variables must be defined within the GitLab CI/CD Variables settings. These variables act as the authentication and routing mechanism between the GitLab runner and the Dependency Track server.

  • DEPENDENCYTRACKAPIURL: This is the base URL of the Dependency Track API service (e.g., https://dt-api.example.org). Without this, the runner cannot locate the API endpoint to upload the SBOM.
  • DEPENDENCYTRACKAPIKEY: The unique API key used for reporting. This key is typically found by navigating to Administration > Access Management > Teams within Dependency Track, where the "Automation" team usually has an assigned key.
  • DEPENDENCYTRACK_PROJECT: The unique Object Identifier for the specific project. This is retrieved by navigating to Projects > {selected project} > View Details and copying the identifier (e.g., 615683fe-abcd-1234-abcd-a04a7514e7f5).

If these variables are not configured, the CI job is designed to fail immediately with a configuration warning to prevent silent failures in the security chain.

Technical Implementation for PHP Composer Projects

In a PHP environment, the integration involves using the cyclonedx-php-composer tool. The process is structured to keep the SBOM generation tool separate from the project's own dependencies to avoid polluting the production environment.

The following configuration outlines the necessary .gitlab-ci.yml job:

yaml report dependencies: stage: check image: composer:2 rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' needs: - composer install before_script: - > if [ -z "${DEPENDENCYTRACK_API_KEY}" -o -z "${DEPENDENCYTRACK_API_URL}" -o -z "${DEPENDENCYTRACK_PROJECT}" ]; then echo "Configure DEPENDENCYTRACK_API_KEY, DEPENDENCYTRACK_API_URL and DEPENDENCYTRACK_PROJECT to report to Dependency Track." exit 1 fi - composer global config --no-plugins allow-plugins.cyclonedx/cyclonedx-php-composer true - composer global require cyclonedx/cyclonedx-php-composer script: - composer CycloneDX:make-sbom --output-format=XML --output-file="${CI_PROJECT_DIR}/composer-sbom.cdx.xml" - > echo "{ \"project\": \"${DEPENDENCYTRACK_PROJECT}\", \"bom\": \"$( base64 --wrap=0 ${CI_PROJECT_DIR}/composer-sbom.cdx.xml )\" }" > ${CI_PROJECT_DIR}/report-bom.json - > curl -X "PUT" "${DEPENDENCYTRACK_API_URL}/api/v1/bom" \ -H "Content-Type: application/json" \ -H "X-API-Key: ${DEPENDENCYTRACK_API_KEY}" \ -d @${CI_PROJECT_DIR}/report-bom.json

The operational flow of this job is as follows:

  1. Validation: The before_script block checks for the existence of the required API keys and URLs.
  2. Tool Installation: The cyclonedx-php-composer plugin is installed globally using composer global require.
  3. SBOM Generation: The command composer CycloneDX:make-sbom creates an XML file containing the project's dependency graph.
  4. Data Transformation: Because the Dependency Track API requires the SBOM to be Base64 encoded within a JSON wrapper, the script uses base64 --wrap=0 to encode the XML and wraps it in a JSON object containing the project identifier.
  5. Transmission: A curl command performs a PUT request to the /api/v1/bom endpoint, transmitting the encoded SBOM for analysis.

Leveraging the Native GitLab Dependency Scanning Analyzer

For those who prefer to use GitLab's built-in capabilities rather than an external Dependency Track instance, the native Dependency Scanning analyzer provides a streamlined path to vulnerability management.

Enabling the New Analyzer

GitLab has introduced a new lockfile-based analyzer that is more efficient than the deprecated Gemnasium tool. This analyzer produces a CycloneDX SBOM report that is fully compatible with GitLab's internal security dashboard.

To enable this analyzer, users have several options:

  • Using the latest CI/CD template: By including Jobs/Dependency-Scanning.latest.gitlab-ci.yml and setting the variable DS_ENFORCE_NEW_ANALYZER to true.
  • Using Scan Execution Policies: Applying the latest template and setting DS_ENFORCE_NEW_ANALYZER to true.
  • Using the Dependency Scanning CI/CD component: Utilizing version 0.4.0 or later, which supports the lockfile-based analyzer.

The configuration for the template method looks as follows:

```yaml
include:
- template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml

variables:
DSENFORCENEW_ANALYZER: 'true'
```

Prerequisites and Requirements

For the native analyzer to function correctly, certain technical prerequisites must be met:

  • Lock Files: A supported lock file or dependency graph must exist in the repository or be passed as an artifact to the dependency-scanning job.
  • CI/CD Stage: The component's stage must be explicitly defined in the .gitlab-ci.yml file.
  • Runner Configuration: For self-managed runners, a GitLab Runner with either a docker or kubernetes executor is required. SaaS runners on GitLab.com have this enabled by default.
  • Tier Requirements: This functionality is available for the Ultimate tier across GitLab.com, GitLab Self-Managed, and GitLab Dedicated offerings.

Vulnerability Analysis and PURL Support

The effectiveness of dependency scanning relies on the ability to match components found in an SBOM against a known database of vulnerabilities. GitLab utilizes the Package URL (PURL) standard to uniquely identify software packages across different ecosystems.

The GitLab SBOM Vulnerability Scanner can report vulnerabilities for components using the following PURL types:

  • cargo
  • composer
  • conan
  • gem
  • golang
  • maven
  • npm
  • nuget
  • pypi

If a component in the SBOM does not have a corresponding entry in the GitLab Advisory Database, it cannot be analyzed for vulnerabilities. This underscores the importance of using standardized SBOM formats like CycloneDX, which ensure that package identifiers are consistent across different tools and databases.

Evolution and Roadmap of Dependency Scanning

The transition toward the current SBOM-centric model has been an iterative process. The history of the feature reflects a movement toward standardization and continuous monitoring.

The timeline of development is as follows:

  • GitLab 17.1: The feature was introduced and tracked under Epic 14636, initially controlled by the dependency_scanning_using_sbom_reports feature flag.
  • GitLab 17.3: Official release of the feature via the aforementioned flag.
  • GitLab 17.4: The lockfile-based Dependency Scanning analyzer was released as an Experiment.
  • GitLab 17.5: The feature was enabled by default for GitLab.com, Self-Managed, and Dedicated. Additionally, the Dependency Scanning CI/CD Component version 0.4.0 was released.
  • GitLab 17.9: The new analyzer became the default for Cargo, Conda, Cocoapods, and Swift templates.
  • GitLab 17.10: The feature flag dependency_scanning_using_sbom_reports was completely removed, signaling the full transition to the new architecture.

Analysis of the Integrated Security Workflow

The integration of Dependency Track and GitLab CI creates a symbiotic relationship between continuous integration and continuous security. While GitLab's native tools provide immediate feedback within the merge request (MR) flow, Dependency Track provides a long-term repository of a project's security health.

One of the most significant advantages of this architecture is the handling of transitive dependencies. Most modern vulnerabilities do not exist in the top-level libraries a developer explicitly adds, but in the dependencies of those libraries. By generating a full SBOM, both GitLab and Dependency Track can map the entire tree, ensuring that hidden vulnerabilities are exposed.

Furthermore, the use of the composer:2 image and global installation of the CycloneDX tool demonstrates a best-practice approach to CI environment isolation. By avoiding the installation of security tools within the project's composer.json, the production artifact remains lean and free of development-time tools, reducing the attack surface of the deployed application.

The shift from Gemnasium to the new SBOM analyzer reflects a broader industry trend toward "SBOM-first" security. By treating the SBOM as a primary artifact, organizations can share this document with clients or regulatory bodies to prove compliance with software supply chain security standards (such as Executive Order 14028 in the US).

In conclusion, the combination of GitLab CI's orchestration capabilities and Dependency Track's analysis engine allows for a comprehensive SCA strategy. Whether utilizing the native GitLab Ultimate features or a custom integration with Dependency Track, the goal remains the same: ensuring that no known vulnerability makes it into the production environment. The transition to SBOM-based scanning not only improves the speed and accuracy of detection but also enables a continuous monitoring state where security is an ongoing process rather than a point-in-time check.

Sources

  1. Chris Burgers - Dependency Track GitLab CI
  2. GitLab Documentation - Dependency Scanning SBOM
  3. GitLab Documentation - Dependency Scanning

Related Posts