-
-
Notifications
You must be signed in to change notification settings - Fork 633
Add option to configure notifications based on severity level #4879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add option to configure notifications based on severity level #4879
Conversation
🎉 Snyk checks have passed. No issues have been found so far.✅ security/snyk check is complete. No issues have been found. (View Details) |
b76291a
to
99b53de
Compare
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Love this, I need this :) But another note: I might have overseen something, but what happens if you already have notification rules and then install this update? Did I miss some migration or default that falls back to the original behavior for already existing rules? |
Hi @rkg-mm Thanks alot! 😄 Also, regarding storing severities as a comma-separated string: It is consistent with how notifyOn was already stored, but we can change this if needed. |
0435a09
to
31eefe0
Compare
9def475
to
d0aab3d
Compare
src/main/java/org/dependencytrack/notification/NotificationRouter.java
Outdated
Show resolved
Hide resolved
3550f14
to
1d35800
Compare
dd849a2
to
6527935
Compare
Signed-off-by: Erik Myhrberg <erimy268@student.liu.se>
6527935
to
42e89ab
Compare
Signed-off-by: Erik Myhrberg <erimy268@student.liu.se>
I believe this PR is ready to merge @nscuro |
result.add(Severity.valueOf(s.trim())); | ||
} | ||
} else { | ||
return List.of(Severity.values()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with returning all severities per default is that this also "bleeds" through to the REST API. We'd then have NotificationRules
returning all severities, even if they are not configured for vulnerability-related NotificationGroup
s.
Perhaps this kind of fallback should be in NotificationRouter
instead, when notifivySeverities
is actually being evaluated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason we implemented it by returning all severities per default is to have it visually check all the checkboxes by default. I figured this would clarify the behaviour of the options to the users. Anyway, I moved the empty list check to NotificationRouter
, as you suggested, and it still works as expected. Only the visual part changed; all the checkboxes are not checked by default. But we are open to change it, if needed.
default void inform(PublishContext ctx, | ||
Notification notification, | ||
JsonObject config, | ||
List<Severity> notifySeverities) { | ||
|
||
if (notification == null || config == null) { | ||
return; | ||
} | ||
|
||
// Filter out unwanted notifications based on the configured severities | ||
if (notifySeverities != null && !notifySeverities.isEmpty() | ||
&& notification.getSubject() instanceof NewVulnerabilityIdentified vuln) { | ||
|
||
final Severity sev = vuln.getVulnerability().getSeverity(); | ||
if (sev != null && !notifySeverities.contains(sev)) { | ||
return; | ||
} | ||
} | ||
|
||
// Call the default inform method | ||
inform(ctx, notification, config); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider performing the filtering here in NotificationRouter
instead.
Notifications not eligible for publishing should never reach the Publisher
to begin with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, moved the filtering to where you suggested in NotificationRouter
, where I also added filtering to NewVulnerableDependency
.
if (notifySeverities.isEmpty()){ | ||
this.notifySeverities = null; | ||
return; | ||
} | ||
StringBuilder sb = new StringBuilder(); | ||
for (int i=0; i<notifySeverities.size(); i++) { | ||
sb.append(notifySeverities.get(i)); | ||
if (i+1 < notifySeverities.size()) { | ||
sb.append(","); | ||
} | ||
} | ||
this.notifySeverities = sb.toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (notifySeverities.isEmpty()){ | |
this.notifySeverities = null; | |
return; | |
} | |
StringBuilder sb = new StringBuilder(); | |
for (int i=0; i<notifySeverities.size(); i++) { | |
sb.append(notifySeverities.get(i)); | |
if (i+1 < notifySeverities.size()) { | |
sb.append(","); | |
} | |
} | |
this.notifySeverities = sb.toString(); | |
if (notifySeverities == null || notifySeverities.isEmpty()){ | |
this.notifySeverities = null; | |
return; | |
} | |
this.notifySeverities = notifySeverities.stream().collect(Collectors.joining(","); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
if (notifySeverities != null && !notifySeverities.isEmpty() | ||
&& notification.getSubject() instanceof NewVulnerabilityIdentified vuln) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this also apply to NEW_VULNERABLE_DEPENDENCY
notifications? In that case, a component can have multiple vulnerabilities. How do we want to treat that case? Do we drop the entire notification, or do we just filter out vulnerabilities that don't fit the configured severity criteria?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added filtering for NEW_VULNERABLE_DEPENDENCY
notifications.
It currently works by dropping the entire notification if it does not fit the configured severity filters.
466c4c6
to
31c1d65
Compare
A new commit has been made addressing the comments from @nscuro . |
31c1d65
to
516e5b6
Compare
- Move severity filtering code, so it doesn't reach the publisher - Remove some unnecessary publisher tests - Add new tests in NotificationRouterTest, SendMailPublisherTest and SlackPublisherTest Signed-off-by: Erik Myhrberg <erimy268@student.liu.se>
516e5b6
to
d779af1
Compare
Description
This PR adds support for configuring which CVE severities should trigger alert notifications.
Previously:
All NEW_VULNERABILITY_IDENTIFIED events triggered notifications, regardless of severity (e.g., low, medium, high).
Now:
Users can select which severities (e.g., only CRITICAL and HIGH) should trigger notifications. This helps reduce noise and makes it easier to focus on the most important vulnerabilities.
If no severity is selected, the system behaves as before (all severities trigger alerts).
Addressed Issue
Closes #3767
Additional Details
As mentioned by users in the issue, teams managing many microservices currently receive too many alerts for low-priority issues. This change allows them to only receive notifications for critical or high-severity vulnerabilities, reducing email overload and improving focus.
Screenshot
Also, see frontend PR
Checklist
- [] This PR fixes a defect, and I have provided tests to verify that the fix is effective- [] This PR introduces changes to the database model, and I have added corresponding update logic