-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Security Solution][Alerts] Alert suppression time window #148868
[Security Solution][Alerts] Alert suppression time window #148868
Conversation
Pinging @elastic/security-solution (Team: SecuritySolution) |
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Show resolved
Hide resolved
x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts
Outdated
Show resolved
Hide resolved
x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/query.ts
Show resolved
Hide resolved
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.
Thanks for putting up the PR for rule registry changes! I left a question before continuing my review.
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Show resolved
Hide resolved
const suppressionDuration = runOpts.completeRule.ruleParams.alertSuppression?.duration; | ||
|
||
if (suppressionDuration) { | ||
const suppressionWindow = `now-${suppressionDuration.value}${suppressionDuration.unit}`; |
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.
Curious about the case where a rule not configured with suppression is run, it creates some alerts, then is disabled, edited to have a suppression time period covering the previous execution, and is re-enabled. In this situation the next execution (as triggered by the re-enable) will run with suppression enabled and will suppress any new alerts that would match those alerts from the previous execution, correct?
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 suppression across rule runs depends on existing alerts having the kibana.alert.instance.id
field populated. If the first rule execution has no suppression configured at all, then the initial alerts won't populate an instance ID. When suppression is configured, with or without a duration, the instance ID does get populated (the instance ID calculation depends on the field chosen for suppression and the value in that field, so we'd have to do a runtime computation of each alert's instance ID if the suppression field is allowed to be chosen after the alert is created).
In the scenario you described, after suppression is configured for the first time the next rule execution will still create new alerts even if the previous execution created alerts within the suppression duration with the same host name or whatever field is chosen as the suppression field.
Alternatively, if per rule execution is chosen initially and then the duration is added (without changing the suppression field) then the existing alerts from the per rule execution run would be updated, assuming they're still within the suppression duration.
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.
Perfect, thank you for the clarification here!
isDisabled={ | ||
groupByFields?.length === 0 || | ||
groupByRadioSelection.value !== GroupByOptions.PerTimePeriod |
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.
Whoops -- one even more corner case here with regards to being on basic license and then duplicating a prebuilt rule that has alert_suppression
:
isDisabled={ | |
groupByFields?.length === 0 || | |
groupByRadioSelection.value !== GroupByOptions.PerTimePeriod | |
isDisabled={ | |
!license.isAtLeast(minimumLicenseForSuppression) || | |
groupByFields?.length === 0 || | |
groupByRadioSelection.value !== GroupByOptions.PerTimePeriod |
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.
Checked out, tested locally, and code reviewed -- rules area changes LGTM! 👍
Performed a bunch of different tests, from testing locally hosted prebuilt rules with alert_suppression
configured, license changes, and general functionality of the time window feature during rule execution.
Thank you @marshallmain for replying to all my comments and providing further context/test scenarios -- really appreciate it! 🙂 🚀
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.
LGTM
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.
I reviewed the changes in the rule registry, looking good! A few questions and comments but after this we should be good to go! 🚀
@@ -48,6 +48,7 @@ const ALERT_BUILDING_BLOCK_TYPE = `${ALERT_NAMESPACE}.building_block_type` as co | |||
const ALERT_EVALUATION_THRESHOLD = `${ALERT_NAMESPACE}.evaluation.threshold` as const; | |||
const ALERT_EVALUATION_VALUE = `${ALERT_NAMESPACE}.evaluation.value` as const; | |||
const ALERT_INSTANCE_ID = `${ALERT_NAMESPACE}.instance.id` as const; | |||
const ALERT_LAST_DETECTED = `${ALERT_NAMESPACE}.last_detected_at` as const; |
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.
Can we move this field to the default_alerts_as_data.ts
file to make it available for all alerts and have it renamed to last_detected
for consistency with start
and end
?
return { | ||
...alert, | ||
_source: { | ||
[ALERT_LAST_DETECTED]: includeLastDetected ? currentTimeOverride ?? new Date() : undefined, |
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.
Can we always set ALERT_LAST_DETECTED
? The framework plans to rely on this field to know when an alert was last detected, even if it was just once (persistent alerts).
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Show resolved
Hide resolved
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Show resolved
Hide resolved
throw new Error('Failed to parse suppression window'); | ||
} | ||
|
||
const suppressionAlertSearchRequest = { |
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.
Can we make this query work with ALERT_START
instead of TIMESTAMP
? It will make it easier for the framework to enable suppression for O11y and stack alerts too (given timestamp behaves differently in O11y / stack vs security solution) we need to look at the first detected time.
We will need to set ALERT_START
for newly detected alerts within augmentAlerts
to make this work.
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Show resolved
Hide resolved
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.
Changes LGTM! Just one place left to use ALERT_START
🚀
x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts
Outdated
Show resolved
Hide resolved
…ule_type_wrapper.ts Co-authored-by: Mike Côté <[email protected]>
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Unknown metric groupsAPI count
ESLint disabled in files
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
…8868) ## Summary Adds ability to specify a time window with alert suppression on Query rules. If more alerts are detected with the same value in the "group by" field in subsequent rule executions, the existing alert will be updated to reflect the new doc count and suppression end time rather than creating a new alert. ### Create Rule ![image](https://user-images.githubusercontent.com/55718608/212997145-cee96a7d-fc3b-4b08-8845-5a9c7876fa0a.png) ### Rule Details ![image](https://user-images.githubusercontent.com/55718608/212997293-69d93392-f74e-4e4e-925a-befbee531659.png) --------- Co-authored-by: kibanamachine <[email protected]> Co-authored-by: Mike Côté <[email protected]>
Summary
Adds ability to specify a time window with alert suppression on Query rules. If more alerts are detected with the same value in the "group by" field in subsequent rule executions, the existing alert will be updated to reflect the new doc count and suppression end time rather than creating a new alert.
Create Rule
Rule Details