OWASP Dependency-Track holds the component inventory and vulnerability triage history for every application you upload, which makes its own access model, API keys and integrations a supply chain asset that needs securing. Dependency-Track is an OWASP project that describes itself as an intelligent Component Analysis platform: it ingests CycloneDX SBOMs, matches components against vulnerability sources, evaluates policies and records audit decisions. This guide covers how identity and access work in the platform, how to run its automation identities safely, what to log, and a hardening baseline for production. It is written for the AppSec and platform engineers who operate the server, and assumes you already know what an SBOM is. The facts here come from the project's own v5 documentation and architecture decision records, checked on 27 October 2026; v4 is in maintenance and the project states it reaches end of life in December 2026.
Key takeaways
- Permissions are a union, never a downgrade. A user's effective rights are their direct permissions plus every team's permissions, so one over-privileged team quietly widens everyone in it.
- Portfolio Access Control is the tenancy boundary. Without it, anyone holding
VIEW_PORTFOLIOsees every project; with it, a principal needs the permission and a team on the project's ACL. - Team API keys are long-lived secrets. They do not expire and cannot be made to; the project positions service accounts with workload identity federation as their replacement from 5.2.0.
- Integration tokens belong in the secret store. Tokens for OSS Index, Snyk, Trivy and Jira are managed secrets protected by envelope encryption, and every instance must share the same key encryption key.
- The default
adminaccount is for first login only. Production should authenticate people through OIDC or LDAP, with team synchronisation mapped from identity provider groups.
How identity and access work in Dependency-Track
Dependency-Track uses role-based access control built from permissions, teams and users. Permissions can be assigned to teams or directly to users, and the documentation is explicit that effective permissions are the union of both: team membership never removes a right. The authentication method decides how identity is verified, not what the identity can do.
| Principal type | How it authenticates | Use it for | Watch for |
|---|---|---|---|
| Managed user | Local username and password held by Dependency-Track | Evaluation and break-glass only | The quickstart ships admin / admin and forces a change on first login |
| LDAP user | Bind against LDAP or Active Directory | Organisations without an OIDC provider | Bind password is an infrastructure secret; load it from a file |
| OIDC user | OpenID Connect identity provider (Keycloak, Entra ID, Google, GitLab, Auth0, OneLogin, Cognito examples documented) | The default for people in production | Group claims must be mapped deliberately for team sync |
| Service account (5.2.0 and later) | Its own API keys, or workload identity federation | CI pipelines, scanners, scripts | Cannot log in; username always starts with svc: |
| Team API key | X-Api-Key header, carries the team's permissions | Legacy integrations | No expiry, no individual identity in requests |
Permissions are coarse or fine grained
The permission model has two levels. A coarse permission such as PORTFOLIO_MANAGEMENT implies all of its fine variants (_CREATE, _READ, _UPDATE, _DELETE). Grant the fine variants when a role needs only one operation. The groups that matter most for security are:
- Portfolio:
BOM_UPLOAD,PROJECT_CREATION_UPLOAD,VIEW_PORTFOLIO,PORTFOLIO_MANAGEMENTand its fine variants, andPORTFOLIO_ACCESS_CONTROL_BYPASS. - Vulnerability analysis:
VIEW_VULNERABILITY,VULNERABILITY_ANALYSIS(analysis decisions and VEX data), with_CREATEfor VEX upload and_UPDATEfor decisions. - Vulnerability management: create, read, update and delete internal (private) vulnerabilities.
- Policy management:
POLICY_MANAGEMENT,POLICY_VIOLATION_ANALYSIS,VIEW_POLICY_VIOLATION. - Administration:
ACCESS_MANAGEMENT,SYSTEM_CONFIGURATION,SECRET_MANAGEMENTandTAG_MANAGEMENT.
Portfolio Access Control and project ACLs
By default every principal with VIEW_PORTFOLIO can see every project. Portfolio Access Control (PAC), enabled under Administration > Access Management > Portfolio Access Control, makes the per-project list of teams (the project's ACL) a gate on every operation: viewing, BOM upload, editing, deletion and triage. Permissions say what a principal can do; ACLs say on which projects. ACL grants inherit down the project hierarchy, so assign teams at the top of a tree rather than on every leaf.
The documentation describes a useful pattern: permission teams that hold capabilities but are assigned to no project, and access teams that hold no permissions but sit on project ACLs. A user joins one of each, which emulates per-project roles that the model does not natively support.
Two behaviours catch teams out. Enabling PAC on an existing instance leaves every project with no team assignment, so projects become invisible to non-administrators until someone assigns teams. And when a team API key or service account creates a project through BOM upload, Dependency-Track adds the first team in alphabetical order to the new ACL; a service account in no team adds none.
Admin roles and privileged access
Dependency-Track creates three default teams on first start: Administrators (all permissions), Portfolio Managers (manage projects without administration) and Automation (intended for CI, typically BOM_UPLOAD and PROJECT_CREATION_UPLOAD). Treat the following permissions as privileged and review their holders like any other admin role:
| Permission | Why it is privileged | Suggested holders |
|---|---|---|
ACCESS_MANAGEMENT | Manages users, service accounts, teams, API keys and workload identity providers and bindings; a holder can mint keys or grant themselves any permission | Two or three named administrators |
SYSTEM_CONFIGURATION | Controls notifications, repositories, analyzers and email settings, including outbound destinations | Platform owners |
SECRET_MANAGEMENT | Creates and updates integration secrets used by analyzers and publishers | Platform owners |
PORTFOLIO_ACCESS_CONTROL_BYPASS | Sees every project as if PAC were off | Administrators and genuinely portfolio-wide automation only |
VULNERABILITY_ANALYSIS / POLICY_VIOLATION_ANALYSIS | Can mark findings Not Affected or suppress them, which hides risk from every downstream report and VEX export | AppSec analysts, scoped by access team |
VULNERABILITY_MANAGEMENT | Can create or alter internal vulnerability records that drive matching | AppSec leads |
Triage rights deserve more attention than they usually get. Every change to a finding's analysis appends to a permanent audit history, but a suppression still removes the finding from metrics and dashboards. Vulnerability policies can apply the same decisions automatically, so the people who can write policies can silence findings at scale. Keep POLICY_MANAGEMENT narrower than triage rights.
Integrations, API tokens and service accounts
Automation is where Dependency-Track's non-human identities live: CI jobs that upload BOMs, scripts that export VEX, and the server's own outbound tokens for analyzers and notification publishers. See the CI/CD Pipeline Identity Security Guide for the wider pipeline view.
Inbound: how automation reaches the API
- Team API keys: sent in the
X-Api-Keyheader to endpoints such as/api/v1/bom. Architecture decision record 041 (accepted September 2026) states that team keys do not get an expiry and operators cannot make them expire. They are exactly the long-lived static secret that the API Key Management Guide warns about. - Service account keys (5.2.0 and later): each service account owns its keys, requests are attributed to the
svc:username in audit records, and suspension stops all its keys at once. ADR 041 adds an expiry to keys, mandatory for new service account keys; check your release notes for the version that ships it. - Workload identity federation (5.2.0 and later): a GitHub Actions job, GitLab CI job, Kubernetes pod or SPIFFE workload exchanges its platform-issued token for a session of a service account. The workload stores no Dependency-Track credential. The
gh-upload-sbomaction supports this withworkload-identity-provider,service-accountandoidc-audienceinputs and the job permissionid-token: write. See the Workload Identity Federation Guide.
How federation is constrained
A provider names a trusted issuer, the audience tokens must carry, the key source and the session lifetime. Provider types are OIDC (the iss claim must equal the configured issuer) and SPIFFE (the subject must start with spiffe://<trust-domain>/). A binding belongs to one service account and matches a subject exactly or by prefix, optionally narrowed by a CEL condition over any token claim; bindings cannot point at a human user. Sessions last the provider's configured lifetime, capped at 24 hours. Deleting a binding or provider does not end existing sessions; suspending the service account does, immediately.
The design choices worth copying into your own review: bind on exact subjects (a specific repository and branch, not a whole organisation prefix), keep session lifetimes close to the length of a BOM upload and analysis, and use one service account per pipeline family so audit records name the tool. The GitHub Actions OIDC Federation Hardening Guide covers subject claim pitfalls on the GitHub side.
Outbound: tokens the server holds
Analyzer tokens (OSS Index username and API token, Snyk organisation ID and token, the Trivy server URL and token), Jira credentials and webhook targets are integration secrets held in the runtime secret store. The default database provider stores them in the SECRET table using envelope encryption: each secret has its own data encryption key, protected by a key encryption key (KEK). By default each instance generates a KEK keyset on first start; in a cluster all instances must share one KEK and refuse to start on a mismatch, so provision a keyset once and mount it, and plan KEK rotation. A read-only env provider (dt.secret-management.provider=env) reads prefixed environment variables instead. See the Envelope Encryption Guide for the pattern.
Infrastructure secrets (database password, LDAP bind password) load at start-up. The production guide says to mount them as files and reference them as ${file::/path/to/file} rather than passing clear-text environment variables.
| Automation option | Credential stored in CI | Expiry | Attribution | Choose when |
|---|---|---|---|---|
| Team API key | Yes, long-lived | None, cannot be set | Team only | Legacy tools that cannot be changed yet; plan migration |
| Service account API key | Yes | Required for new keys once ADR 041 ships | svc: username | Platforms without OIDC or SPIFFE tokens |
| Service account with workload identity federation | No | Session capped at 24 hours, platform token minutes | svc: username plus token subject in the exchange log | GitHub Actions, GitLab CI, Kubernetes, SPIRE |
Logging and detection
Dependency-Track logs through Logback to stdout. Container images ship a JSON configuration, logback-json.xml, activated with EXTRA_JAVA_OPTIONS="-Dlogback.configurationFile=logback-json.xml", which is the better choice for shipping to a SIEM. Prometheus metrics are on /metrics at port 9000, with health endpoints /health/live, /health/ready and /health/started; the public REST API is on 8080.
Security events to collect
- Workload identity: the API server logs provider and binding create, update and delete; successful exchanges with provider, service account, matched binding, subject and
jti; and refused exchanges, including the claims when the token verified but no binding matched. Subject tokens are never logged. - Expired keys: per ADR 041, a rejected expired key is recorded as a security failure with the key's public ID. The same ADR notes that successful API key authentications are not logged, so you cannot reconstruct normal key use from the server alone: correlate with reverse proxy logs.
- Notification groups: system scope groups include
CONFIGURATION,INTEGRATION,REPOSITORY,ANALYZER,DATASOURCE_MIRRORING,USER_CREATEDandUSER_DELETED. Portfolio scope includesBOM_PROCESSING_FAILED,BOM_VALIDATION_FAILED,NEW_VULNERABILITY,POLICY_VIOLATION,PROJECT_AUDIT_CHANGEandVEX_PROCESSED. RouteUSER_CREATED,CONFIGURATIONandPROJECT_AUDIT_CHANGEto a webhook your SOC reads. - Reverse proxy: forward
X-Forwarded-ForandX-Forwarded-Protoso audit records and notification links carry the real client and public URL.
Detections worth writing
| Signal | Source | Possible meaning |
|---|---|---|
| Refused workload identity exchange where the token verified | API server security log | A pipeline outside the intended repository or branch trying to act as a service account |
USER_CREATED outside a change window, or a new member of Administrators | Notification webhook | Persistence by a compromised admin |
| Burst of findings moved to Not Affected or suppressed by one principal | PROJECT_AUDIT_CHANGE | Risk being hidden ahead of a release gate |
| BOM uploads for many projects from one team key from a new source IP | Reverse proxy log | Leaked key used to poison inventory |
Repeated BOM_VALIDATION_FAILED | Notification | Broken generator, or probing with malformed input |
Metrics that show the control is working
- Percentage of BOM uploads authenticated through workload identity federation rather than API keys (target rising each quarter).
- Number of team API keys still active, and age of the oldest one.
- Count of principals holding
ACCESS_MANAGEMENT,SYSTEM_CONFIGURATIONorPORTFOLIO_ACCESS_CONTROL_BYPASS. - Share of projects with at least one team on their ACL once PAC is enabled (target 100%).
- Suppressions and Not Affected decisions per month with a recorded justification, reviewed by a second analyst.
Hardening baseline
The project's production guidance and reference pages support the following baseline. Roll it out in order on a staging instance first.
- Pin images: deploy a full
X.Y.Ztag or image digest, neverlatestor snapshot tags. During the v4 to v5 transition the project states:latestdeliberately does not flip to v5 on the GA date. - Replace local logins: configure OIDC (for example
dt.oidc.username-claim=preferred_username) withdt.oidc.team-synchronization=trueanddt.oidc.teams-claim=groups. Entra ID emits group object IDs by default, so map teams to those or configure the groups claim to emit names. Change theadminpassword, then keep one managed account as documented break-glass. - Terminate TLS in front: handle TLS at a reverse proxy or ingress, expose only
8080, and scrape9000from an internal network. If internal services use a private CA, add it to the Java trust store as the internal CA guide describes rather than disabling validation. - Externalise secrets: mount infrastructure secrets as files, keep integration tokens in the secret store, and provision one shared KEK keyset for the cluster.
- Restrict outbound destinations: notification publishers only connect to destinations allowed by
dt.outbound.allowed-destinations(5.2.0 and later; earlier releases used per-publisher local connection settings). Workload identity key fetches accept onlyhttpsURLs, refuse loopback and link-local addresses and do not follow redirects. - Enable PAC with a plan: create access teams, assign them at the top of each project hierarchy, then switch PAC on, so no project goes dark.
- Move automation to service accounts: one per pipeline family, permissions limited to
BOM_UPLOADand, only where needed,PROJECT_CREATION_UPLOAD. Federate where the CI platform issues tokens; delete the team key once traffic has moved. - Run PostgreSQL properly: v5 supports only PostgreSQL. Run it on a dedicated host with monitoring and automated backups, and rehearse a restore. A standard PostgreSQL backup covers everything Dependency-Track persists, including encrypted secrets, so protect backups and the KEK separately.
- Verify before go-live: confirm
/health/readyon every instance, sign in through the identity provider, upload a sample BOM and confirm analysis completes, and check metrics arrive.
Rollback: keep the team API key valid but unused for one release cycle after moving a pipeline to federation, so a broken binding can be reverted by switching the pipeline input back; disable PAC only as a last resort, because projects keep their data either way. For large estates the project documents running v4 and v5 in parallel during migration.
Common misconfigurations
- One shared Automation key for everything: every pipeline uploads with the same team key, so a leak from any repository lets an attacker overwrite any project's inventory and nothing in the logs tells you which pipeline leaked it. The Codecov breach showed how CI secrets taken from one tool are reused far beyond it.
PROJECT_CREATION_UPLOADgranted by default: automation can create unlimited projects, and under PAC each new project lands on whichever of its teams sorts first alphabetically, which may expose it to the wrong audience.- PAC enabled without assignments: projects disappear for developers, someone grants
PORTFOLIO_ACCESS_CONTROL_BYPASSto a broad team to "fix" it, and the tenancy boundary is gone. - Prefix bindings that are too wide: a workload identity binding on an organisation-level subject prefix lets any repository in that organisation, including a fork-driven workflow, act as the service account. Match exact subjects and add a CEL condition on branch or environment.
- Different KEKs per instance: instances refuse to start, and the quick fix of wiping the keyset destroys every stored integration secret.
- Triage as an unreviewed free-for-all: wide
VULNERABILITY_ANALYSISrights plus policies that auto-suppress mean exported VEX documents tell customers components are not affected without evidence. See the VEX Guide.
Framework mapping
| Dependency-Track control | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | Threat addressed |
|---|---|---|---|
| SBOM ingestion and component inventory | CM-8 System Component Inventory; SR-4 Provenance | ID.AM-02 | ATT&CK T1195.001 Compromise Software Dependencies and Development Tools |
| Vulnerability analysis and triage history | RA-5 Vulnerability Monitoring and Scanning | ID.RA-01 | Known vulnerable components shipped unnoticed |
| Outdated component and policy checks | SA-22 Unsupported System Components; SR-3 | GV.SC-04 | End-of-life dependencies |
| Teams, fine-grained permissions, PAC | AC-6 Least Privilege | PR.AA-05 | Over-privileged analysts and automation |
| Service accounts, key expiry, federation | IA-5 Authenticator Management | PR.AA-01 | T1552.001 Credentials In Files (keys in CI configs) |
| Security event logging and notifications | AU-2 Event Logging | DE.CM-09 | Undetected admin or key misuse |
Practitioner checklist
- Pin the image to a full release tag or digest and record the version against the 5.2.0 features you rely on.
- Configure OIDC or LDAP with team synchronisation, change the
adminpassword and document the break-glass account. - List every holder of
ACCESS_MANAGEMENT,SYSTEM_CONFIGURATION,SECRET_MANAGEMENTandPORTFOLIO_ACCESS_CONTROL_BYPASS; cut to named owners. - Design permission teams and access teams, assign access teams at hierarchy roots, then enable PAC.
- Inventory team API keys, create one service account per pipeline family, federate where possible and delete the old keys.
- Mount infrastructure secrets as files, store integration tokens as managed secrets and share one KEK across instances.
- Set
dt.outbound.allowed-destinations, keep port9000internal and front8080with TLS. - Switch to JSON logging, ship security events and the
USER_CREATED,CONFIGURATIONandPROJECT_AUDIT_CHANGEnotifications to the SOC. - Require a second reviewer for suppressions and Not Affected decisions on critical projects.
- Back up PostgreSQL, store the KEK separately and rehearse a restore twice a year.
Standards and references
- OWASP: Dependency-Track project
- OWASP Dependency-Track: Documentation (access control, permissions, workload identity, deploying to production)
- OWASP Dependency-Track: Architecture decision records 040 Service accounts and 041 API key expiry
- OWASP Dependency-Track: gh-upload-sbom GitHub Action
- CycloneDX: Specification overview (ECMA-424)
- NIST: SP 800-53 Rev. 5
- NIST: Cybersecurity Framework 2.0
- MITRE ATT&CK: Compromise Software Dependencies and Development Tools
Related NHI Mgmt Group resources: SBOM Guide · VEX Guide · Workload Identity Federation Guide · CI/CD Pipeline Identity Security Guide · API Key Management Guide