Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/concepts/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ nav:
- About tags: tags.md
- About access control: access-control.md
- About vulnerability data sources: about-vulnerability-data-sources.md
- About vulnerability findings: vulnerability-findings.md
- About notifications: notifications.md
- About time series metrics: time-series-metrics.md
- About component policies: component-policies.md
Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/time-series-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ drift across days, weeks, and quarters.
## Snapshots, not deltas

A metrics record is a *snapshot*: a complete count of vulnerabilities,
findings, suppressions, audit progress, and policy violations at a single
[findings](vulnerability-findings.md), suppressions, audit progress, and policy violations at a single
moment, scoped to one component, project, or the portfolio. Reconstructing
trends from deltas is fragile (a missed event corrupts the rest of the
series), so Dependency-Track stores the absolute numbers and lets readers
Expand Down
126 changes: 126 additions & 0 deletions docs/concepts/vulnerability-findings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# About vulnerability findings

A finding is the association between a component in one of your projects and a vulnerability that
affects it. Findings are what you see on a project's **Audit Vulnerabilities** tab and what drives
the vulnerability counts in [time series metrics](time-series-metrics.md). Every finding carries an
audit trail and moves through a lifecycle that this page describes.

## Where findings come from

Each enabled [vulnerability analyzer](../reference/analyzers.md) matches your components
against its data source. When an analyzer concludes that a vulnerability affects a component, it
attributes the finding to itself. The same `(component, vulnerability)` pair is one finding even when
more than one analyzer identifies it. Dependency-Track records one attribution per analyzer, so a
finding remembers which sources confirmed it.

For each attribution, the finding stores the analyzer identity, the date the analyzer attributed
the finding (refreshed when the same analyzer reactivates an inactive finding), and a
reference URL the analyzer supplied.

Each finding ties to one specific vulnerability record, not to the underlying issue. When analyzers
report the same underlying vulnerability under different IDs, for example, one under a CVE and
another under its GHSA alias, the result is two separate findings on the same component. Each
finding surfaces the aliases Dependency-Track knows for its vulnerability, so the connection stays
visible during triage. [Time series metrics](time-series-metrics.md) deduplicate by alias group, so
a single underlying vulnerability counted under more than one ID still contributes once to the
project's findings total and severity counts.

## Auditing a finding

A finding carries an *analysis* that captures the team's triage decision. The analysis has four
fields:

* **Analysis state** records the triage conclusion, from initial triage through to whether the
finding is exploitable, not applicable, or already resolved.
* **Justification** explains why the component is not affected. It aligns with the CycloneDX VEX
vocabulary and is most meaningful when the analysis state is *Not Affected*.
* **Vendor response** records the intended remediation action, such as updating, rolling back, or
applying a workaround.
* **Details** is free-form text that explains the decision in context.

Suppression is part of the analysis as well, and the next section covers it on its own.

Every change to any of these fields appends an entry to the finding's audit history. The history
records who made the change, when, and what changed, and it includes the free-form comments reviewers
add as they work. The audit history is permanent. A later analyzer report never overwrites it, and
it survives when a finding goes inactive.

[Vulnerability policies](vulnerability-policies.md) apply the same audit fields automatically when a
finding matches a policy condition, and the policy's decision lands in the audit history alongside
manual entries.

## Suppression

Suppressing a finding hides it from the default views without losing any of its history. A suppressed
finding:

* Does not appear in the project's findings table or in API responses unless the caller opts in by
toggling **Show Suppressed** in the frontend, or by passing the matching flag in the REST API.
* Does not contribute to the active vulnerability counts in
[time series metrics](time-series-metrics.md), and does not raise the project's risk score.
* Counts in the dedicated suppressed-findings metric, so the portfolio still has visibility into
how much triage work has resulted in suppression.

Suppression survives across re-scans. If an analyzer reports the finding again later, the suppression
still applies. To stop suppressing, clear the flag on the finding's analysis. The audit history
records the change.

## Active and inactive findings

A finding is *active* while at least one analyzer still reports it. As long as one attribution is
live, the finding is active even if other analyzers stop reporting it.

A finding becomes *inactive* when no analyzer reports it anymore. This typically happens after a data
source correction, for example, when the upstream advisory narrows its affected range and excludes
the component's version. An inactive finding:

* Stays hidden from the project's findings table and from API responses, with no toggle to reveal it.
* Does not contribute to severity counts, the audited count, or the project's risk score in
[time series metrics](time-series-metrics.md).
* Keeps its full audit history.

If an analyzer reports the finding again later, Dependency-Track reactivates it rather than creating
a new one. The earlier audit state, including analysis state, justification, vendor response,
details, and suppression, applies as before, and any new attributions extend the same audit history.

This distinction matters during triage. A suppressed finding is a deliberate decision you can
reverse by clearing the suppression. An inactive finding is the analyzers' decision, reversed only
when an analyzer reports the finding again.

## Notifications

Lifecycle moments on a finding map to specific notification groups:

* A newly created finding fires [`NEW_VULNERABILITY`](../reference/notifications/groups.md#new_vulnerability).
Reactivation of an inactive finding fires the same group, so subscribers see both first-time
discoveries and returns under one stream.
* A finding going inactive fires
[`VULNERABILITY_RETRACTED`](../reference/notifications/groups.md#vulnerability_retracted).
* When a component appears in a project for the first time and any analyzer attributes findings to
it during the same analysis run, the project fires one
[`NEW_VULNERABLE_DEPENDENCY`](../reference/notifications/groups.md#new_vulnerable_dependency) per
new component, summarizing every finding on it.
* An audit change, whether a reviewer made it or a [vulnerability policy](vulnerability-policies.md)
applied it, fires
[`PROJECT_AUDIT_CHANGE`](../reference/notifications/groups.md#project_audit_change).

Suppressing a finding and clearing that suppression both flow through `PROJECT_AUDIT_CHANGE` rather
than a dedicated group. See [About notifications](notifications.md) for how groups, scopes, and
levels combine into alerts.

## How findings drive metrics

[Time series metrics](time-series-metrics.md) count only active, non-suppressed findings toward
severity totals and the project's risk score. The audited count is a subset of those: only findings
whose analysis state has moved past the initial triage values contribute to it. The dedicated
suppressed metric tracks suppression separately. Inactive findings do not contribute to any of
these counts.

## Further reading

* [About vulnerability data sources](about-vulnerability-data-sources.md): the analyzers and feeds
that produce findings.
* [About vulnerability policies](vulnerability-policies.md): how policies apply analyses to findings
automatically.
* [About time series metrics](time-series-metrics.md): how active, suppressed, and inactive findings
affect the project's posture trend.
2 changes: 1 addition & 1 deletion docs/concepts/vulnerability-policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Vulnerability policies let organisations encode how specific vulnerabilities should be triaged across
the portfolio. Where a [component policy](../reference/policies/component-policies.md) raises violations, a vulnerability policy acts
on the finding itself. It applies an analysis (state, justification, vendor response, details),
on the [finding](vulnerability-findings.md) itself. It applies an analysis (state, justification, vendor response, details),
optionally overrides the vulnerability's ratings, and can suppress the finding altogether.

Typical use cases include:
Expand Down
8 changes: 0 additions & 8 deletions docs/reference/notifications/groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,6 @@ Fires when an analysis or suppression state changes on a project finding.

Fires on creation of a new project.

### `PROJECT_VULN_ANALYSIS_COMPLETE`

- **Trigger:** Event
- **Level:** Informational

Fires when vulnerability analysis for a project completes.

### `VEX_CONSUMED`

- **Trigger:** Event
Expand Down Expand Up @@ -195,7 +188,6 @@ each subject schema.
| `NEW_VULNERABLE_DEPENDENCY` | [NewVulnerableDependencySubject](../schemas/notification.md#newvulnerabledependencysubject) |
| `POLICY_VIOLATION` | [PolicyViolationSubject](../schemas/notification.md#policyviolationsubject) |
| `PROJECT_AUDIT_CHANGE` | [VulnerabilityAnalysisDecisionChangeSubject](../schemas/notification.md#vulnerabilityanalysisdecisionchangesubject) or [PolicyViolationAnalysisDecisionChangeSubject](../schemas/notification.md#policyviolationanalysisdecisionchangesubject) |
| `PROJECT_VULN_ANALYSIS_COMPLETE` | [ProjectVulnAnalysisCompleteSubject](../schemas/notification.md#projectvulnanalysiscompletesubject) |
| `VEX_CONSUMED`, `VEX_PROCESSED` | [VexConsumedOrProcessedSubject](../schemas/notification.md#vexconsumedorprocessedsubject) |
| `USER_CREATED`, `USER_DELETED` | [UserSubject](../schemas/notification.md#usersubject) |
| `NEW_VULNERABILITIES_SUMMARY` | [NewVulnerabilitiesSummarySubject](../schemas/notification.md#newvulnerabilitiessummarysubject) |
Expand Down