Adopting and Integrating Dependency Track
After understanding extensibility in Backstage Plugins, this document explains how to deploy OWASP Dependency-Track and visualize each component's SBOM (Software Bill of Materials) and vulnerability status inside Backstage. The result: from any service in the catalog you can see at a glance "what vulnerabilities does this service have right now?"
1. What is Dependency-Track
OWASP Dependency-Track is a continuous SCA (Software Composition Analysis) platform built around the SBOM.
- It inventories the open-source dependencies an app uses and continuously tracks known vulnerabilities (CVEs), licenses, and outdatedness.
- Because it ingests and stores SBOMs rather than scanning at a point in time, it can retroactively match newly disclosed vulnerabilities against existing components.
- Vulnerability intelligence syncs with sources such as NVD, GitHub Advisories, OSV, and Sonatype OSS Index.
Relationship with SBOM (CycloneDX)
Dependency-Track takes CycloneDX-format SBOMs as input. An SBOM is a "bill of materials" for software, enumerating dependent libraries and their versions, hashes, and licenses.
For the fundamentals of SBOM and vulnerability scanning, see SBOM and Vulnerability Scanning; for the broader context, see DevSecOps and Static Security Scanning.
2. Deploying Dependency-Track
Dependency-Track consists of two components: the API Server and the Frontend (SPA). The Frontend only calls the API Server, so the API Server is the core.
Deployment methods
A minimal setup runs with Docker Compose.
# docker-compose.yml (excerpt / conceptual)
services:
dtrack-apiserver:
image: dependencytrack/apiserver
volumes:
- dtrack-data:/data # persistence (H2 by default; external DB in prod)
ports:
- "8081:8080"
dtrack-frontend:
image: dependencytrack/frontend
environment:
- API_BASE_URL=http://localhost:8081
ports:
- "8080:8080"
volumes:
dtrack-data:
| Item | Recommendation |
|---|---|
| Production deployment | Kubernetes (official Helm chart) or managed containers |
| Database | PostgreSQL (H2 is for evaluation only) |
| Memory | Allocate at least ~4GB to the API Server (vulnerability DB mirroring is heavy) |
Initial setup and issuing API keys
- Open the Frontend, log in as the initial admin (
admin), and change the password. - Enable syncing of vulnerability sources (NVD, OSV, GitHub Advisories).
- Under Administration → Access Management → Teams, create a team for CI and issue an API key.
- Grant that team only the permissions it needs, such as
BOM_UPLOAD/VIEW_PORTFOLIO(least privilege).
Store the issued API key in your CI/CD secret store (e.g., GitHub Actions Secrets) and never leave it in repositories or logs.
3. Ingesting SBOMs
Generating CycloneDX SBOMs
Each language has an official CycloneDX tool.
| Language / ecosystem | Generation tool |
|---|---|
| .NET | dotnet CycloneDX (CycloneDX .NET tool) |
| Node.js | @cyclonedx/cyclonedx-npm |
| Java | cyclonedx-maven-plugin / cyclonedx-gradle-plugin |
| Python | cyclonedx-py |
| Generic (containers, etc.) | syft (detects across multiple ecosystems) |
BOM upload API
PUT the generated SBOM to the BOM Upload API. Adding autoCreate=true auto-creates the target project on first upload.
curl -X POST "https://dtrack.example.com/api/v1/bom" \
-H "X-Api-Key: $DTRACK_API_KEY" \
-F "autoCreate=true" \
-F "projectName=payment-api" \
-F "projectVersion=1.4.0" \
-F "[email protected]"
Automated upload from CI/CD pipelines
Make SBOM generation and upload a standard build step.
Keep projectName aligned with the catalog Component name to make integration easy. Put a release version or commit SHA in projectVersion so you can trace which build an SBOM came from.
4. Integration with Backstage
Using @backstage-community/plugin-dependencytrack (a community plugin), you can show a vulnerability summary on the entity page.
Installation flow
-
Install the plugin — add the card to the frontend and place it on the Component Overview, etc.
-
Proxy configuration — configure the route to the Dependency-Track API and the API key under
proxyinapp-config.yaml. This keeps the API key out of the browser.proxy:endpoints:'/dependencytrack/api':target: 'https://dtrack.example.com/api'headers:X-Api-Key: ${DTRACK_API_KEY} -
Configure catalog-info.yaml annotations — link the Component to its Dependency-Track project.
metadata:annotations:dependencytrack.io/project-id: '<UUID>'# or specify by name/version (depends on plugin support) -
Show vulnerabilities on the entity page — counts by severity and policy violations appear on the card.
The API key is added by the Backstage backend proxy, not the browser. Put only the UUID or project name in annotations, and never write secrets into catalog-info.yaml.
5. Operational flow
Don't let accumulated vulnerabilities sit — evaluate and triage them continuously.
| Step | Content |
|---|---|
| Evaluate / triage | Classify each vulnerability as Exploitable / In Triage / False Positive / Not Affected, etc. |
| Policy | Define policy conditions on version, license, and severity, and detect violations |
| Notification | Notify policy violations and new vulnerabilities via Slack / Webhook / email |
| Suppress false positives | For vulnerabilities deemed non-impacting, record Not Affected via VEX (Vulnerability Exploitability eXchange) to suppress re-display |
VEX is a machine-readable way to assert "does this vulnerability actually affect me?" Even with the same dependency, you can record that there is no call path, so it has no impact — continuously reducing noise.
6. CI/CD gating
Dependency-Track lets you build a "gate" that queries policy evaluation results from the pipeline and fails the build when thresholds are exceeded.
- After upload, query the project's policy violations / counts by severity via the API.
- Examples: "fail if there is even one Critical," "block merges on a new High."
- Official CI integrations (e.g.,
dependency-track/gh-upload-sbom-action) bundle upload and result evaluation together.
For the philosophy of security gates in the pipeline, also see DevSecOps and Static Security Scanning.
Best Practices
- Make SBOM generation a standard build step — don't rely on manual uploads; automatically ingest a fresh SBOM on every build. Embedding it in the initial setup via Software Templates makes adoption stick.
- Unify component naming conventions — align
projectNamewith the catalog Component name to both ease Backstage linking and avoid duplicate registrations. - Set triage SLAs by severity — define deadlines like "Critical within N days" and operate them with policies and notifications.
- Continuously suppress false positives with VEX — ignored noise makes the tool a dead letter. Keep recording
Not Affecteddecisions. - Avoid anti-patterns — relying on manual uploads, ignored vulnerabilities, and stopping at visualization without a gate.