DependencyTrack / DependencyTrack/dependency-track
Allow policy conditions based on a finding's analysis state and response
- Dominant language
- Java
- Stars
- 4.2k
- Forks
- 811
- Avg merge
- 8h 39m
- Merged PRs (30d)
- 237
Description
### Current Behavior
Portfolio Policies (Expression/CEL conditions) only see portfolio-global Vulnerability fields (severity, EPSS, CVSS vectors, published, ...). They have no access to a finding's per-project Analysis (analysisState, analysisResponse, analysisDetails).
This blocks us from expressing two essential release-gating checks as Portfolio Policies in Dependency Track:
- fail if any non-suppressed finding is still untriaged (analysisState is `NOT_SET`/`IN_TRIAGE`) ([Cyber Resilience Act (Regulation (EU) 2024/2847)] https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng) Article 13(7): manufacturers shall "systematically document [...] vulnerabilities of which they become aware [...] and [...] update the cybersecurity risk assessment" and Article 13(8): vulnerabilities "are handled effectively" per Annex I, Part II i.e.: an untriaged finding at release time is neither documented nor handled)
- fail if a finding's analysisState is `EXPLOITABLE` without a documented risk-acceptance decision ([CRA Annex I, Part I, point (2)(a)](https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#anx_I): "made available on the market without known exploitable vulnerabilities" and the risk-based, document-and-accept mechanism itself comes from the Commission's [guidance on applying the CRA](https://ec.europa.eu/newsroom/dae/redirection/document/131456) (C(2026) 5252, 27 July 2026), point 237, not the Regulation text)
Both map directly to Cyber Resilience Act (Regulation (EU) 2024/2847) Annex I, Part II vulnerability-handling obligations, so we need them enforced the same way as our other CRA-derived Portfolio Policies: as a policy violation, visible in the UI, driving notifications, and readable through the Policy Violation API.
Today the only way to implement these two checks is a separate script that pulls `GET /api/v1/finding/project/{uuid}` and inspects analysis fields itself, entirely outside the policy violation model.
### Proposed Behavior
We experimented a lot but haven't found a way to express the kind of expression we need. The ideal would be to expose analysis state on findings to policy conditions, so something like this becomes possible:
```cel
// fail if any non-suppressed finding is untriaged vulns.exists(v,
!has(v.analysis) || v.analysis.state in ["NOT_SET", "IN_TRIAGE"])
```
```cel
// fail if EXPLOITABLE without a documented risk-acceptance decision
vulns.exists(v, v.analysis.state == "EXPLOITABLE" && (!has(v.analysis.response)
|| v.analysis.response == "NOT_SET" || size(v.analysis.details) == 0))
```
> For the response thing, it would be nice to also allow to check for arbitrage text in the analysis response via regex.
We're also happy and open for alternative ideas to be compliant with these criteria!
### Checklist
- [x] I have read and understand the [contributing guidelines](https://github.com/DependencyTrack/dependency-track/blob/main/CONTRIBUTING.md#filing-issues)
- [x] I have checked the [existing issues](https://github.com/DependencyTrack/dependency-track/issues) for whether this enhancement was already requested
Contributor guide
Research direction
Start by tracing Portfolio Policy Expression/CEL conditions and how finding data reaches the policy evaluation path. Review the existing policy violation UI, notification flow, and Policy Violation API, then determine how analysisState, analysisResponse, and analysisDetails could be exposed. Done means both CRA checks can be expressed as policy violations and are visible in all three requested surfaces.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100