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:
- Validation: The
before_scriptblock checks for the existence of the required API keys and URLs. - Tool Installation: The
cyclonedx-php-composerplugin is installed globally usingcomposer global require. - SBOM Generation: The command
composer CycloneDX:make-sbomcreates an XML file containing the project's dependency graph. - Data Transformation: Because the Dependency Track API requires the SBOM to be Base64 encoded within a JSON wrapper, the script uses
base64 --wrap=0to encode the XML and wraps it in a JSON object containing theprojectidentifier. - Transmission: A
curlcommand performs aPUTrequest to the/api/v1/bomendpoint, 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.ymland setting the variableDS_ENFORCE_NEW_ANALYZERtotrue. - Using Scan Execution Policies: Applying the latest template and setting
DS_ENFORCE_NEW_ANALYZERtotrue. - 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-scanningjob. - CI/CD Stage: The component's stage must be explicitly defined in the
.gitlab-ci.ymlfile. - Runner Configuration: For self-managed runners, a GitLab Runner with either a
dockerorkubernetesexecutor 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_reportsfeature 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_reportswas 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.