Skip to content

feat(notification): add FilterExpression to NotificationRule - #65

Open
1azunna wants to merge 1 commit into
DependencyTrack:mainfrom
1azunna:add-notification-rule-filter-expression
Open

1azunna wants to merge 1 commit into
DependencyTrack:mainfrom
1azunna:add-notification-rule-filter-expression

Conversation

@1azunna

@1azunna 1azunna commented Sep 16, 2026

Copy link
Copy Markdown

Problem

DependencyTrack 5.0 added a CEL filter expression to notification rules, but NotificationRule has no corresponding field, so it cannot be read or written through this client.

It is persisted on the model (NotificationRule.java):

@Persistent
@Column(name = "FILTER_EXPRESSION", allowsNull = "true")
@JsonDeserialize(using = TrimmedStringDeserializer.class)
private String filterExpression;

and evaluated by NotificationRouter after the scope, level, group, project and tag checks:

if (!evaluateFilterExpression(rule, notification, subject)) {
    LOGGER.debug("Notification did not match the rule's filter expression");
    return false;
}

The expression environment (NotificationFilterExpressionEnv, @since 5.0.0) exposes level, scope, group, title, content, timestamp and subject, so rules can be narrowed well beyond notifyOn — for example to only notify on policy violations whose policy is at FAIL:

group != Group.GROUP_POLICY_VIOLATION
  || subject.policy_violation.condition.policy.violation_state == "FAIL"

There is a second-order problem: because the field is missing from the struct, reading a rule and passing it back to Update silently drops an expression set through the UI or API.

Change

  • NotificationRule.FilterExpression, tagged json:"filterExpression,omitempty"

omitempty means rules without an expression serialise byte-identically to before, so this is purely additive.

Tests

notification_rule_filter_test.go, written as unit tests so they run without a container, following util_test.go:

  • filterExpression is emitted when set
  • it is omitted when unset, so existing rules are unaffected
  • it round-trips on unmarshal

go build ./... and go test -run TestNotificationRule ./... pass.

Context

Found while managing notification rules with SolarFactories/terraform-provider-dependencytrack, which has no way to express this today. A follow-up PR there depends on this one.

Independent of #64, which adds ViolationType to PolicyCondition; the two touch different files and can merge in either order.

DependencyTrack 5.0 added a CEL filter expression to notification rules,
evaluated by NotificationRouter after the scope, level, group, project and
tag checks:

    if (!evaluateFilterExpression(rule, notification, subject)) {
        LOGGER.debug("Notification did not match the rule's filter expression");
        return false;
    }

It is persisted on NotificationRule as FILTER_EXPRESSION and serialised as
filterExpression, but the field is absent from this struct, so a rule's
expression cannot be read or written through this client. Round-tripping a
rule through Update also silently drops any expression set elsewhere.

The field is omitempty, so rules without an expression serialise exactly as
before.

Signed-off-by: 1azunna <26540897+1azunna@users.noreply.github.com>
@1azunna
1azunna requested a review from nscuro as a code owner September 16, 2026 08:56
@owasp-dt-bot

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants