Skip to content
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][Detections] Updates Rule Details to show all historical alerts for a given Rule #120053

Merged
merged 10 commits into from
Dec 8, 2021

Conversation

spong
Copy link
Member

@spong spong commented Dec 1, 2021

Summary

Resolves Part II of #118935 which fixes a bug where pre-8.x alerts are not displayed on the Rule Details page if the Rule SO ID had been re-generated as part of the upgrade to 8.x. As discussed with the team and relevant product folks, we're resolving this issue by updating the alerts query to filter by ruleId instead of the Rule SO ID, which will result in a slight workflow change where all alerts for a given ruleId will be displayed rather than just the latest instance -- i.e. create pre-package rule, generate alerts, delete/re-create pre-package rule, generate alerts, alerts are displayed from both Rule instances instead of just the most recent. This also updates the exceptions workflow such that if the user specifies close all associated alerts when creating a Rule Exception, it will now close all alerts matching the exception for all historical instances of the rule, maintaining consistent behavior when managing alerts from a rule.

The Previous Rule Deleted functionality stays mostly the same -- if you navigate to Rule Details from an older alert whose rule has been deleted, the Rule Details page will still re-construct the rule's details from the alert, and now show all alerts (as above) instead of just that instances' alerts.

Also cleaned up a lot of duplicate/redundant code over in default_config.tsx that was leftover from the RuleRegsitry feature flag. Now condensed back to one function each for generating filters/columns/config.

Test Instructions:

Clear es-data, and start 7.16 ES

rm -rf $DEV_HOME/es-data
es snapshot --license trial -E xpack.security.authc.api_key.enabled=true -E path.data=$DEV_HOME/es-data --version=7.16.0

Navigate to kibana-7.16, checkout and yarn start
Login, create a rule, then inject some data

node x-pack/plugins/security_solution/scripts/endpoint/resolver_generator.js --node http://elastic:[email protected]:9200 --kibana http://elastic:changeme@localhost:5601/kbn --numHosts=5 --numDocs=2  --fleet

Verify Alerts, kill kibana, kill es, then start es 8.1.0 (run from kibana-main or use --version=8.1.0)

es snapshot --license trial -E xpack.security.authc.api_key.enabled=true -E path.data=$DEV_HOME/es-data

Navigate to kibana-main, checkout and yarn start
Login, navigate to previous rule (toggling enable/disable to bypass this bug), then inject some data (previous resolver_generator data-gen command should've created enough future events, but if not re-run w/o --fleet flag)

Verify 7.16 and 8.1 alerts are visible in both the Alerts Histogram and Alerts Table:

Note, Severity/Risk Score will not display for pre-8.x alerts see this comment for details.

Verify 7.16 and 8.1 alerts are closed when adding a Rule Exception (that of course matches all alerts ;) and selecting Close all alerts that match this exception.

Note: Initial approach was to plumb through the legacyId through the Read Rules route (#119031), so we can always revisit that method if necessary.

Checklist

Delete any items that are not applicable to this PR.

@spong spong added bug Fixes for quality problems that affect the customer experience v8.0.0 release_note:skip Skip the PR/issue when compiling release notes Feature:Detection Rules Security Solution rules and Detection Engine Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. auto-backport Deprecated - use backport:version if exact versions are needed v8.1.0 Team:Detection Rule Management Security Detection Rule Management Team labels Dec 1, 2021
@spong spong self-assigned this Dec 1, 2021
@@ -238,7 +238,7 @@ export const getFailingRules = async (
try {
const errorRules = await Promise.all(
ids.map(async (id) =>
rulesClient.get({
rulesClient.resolve({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a bug where the RuleStatus wouldn't be found because it was querying with the old legacyId. This would result in an error toast along with the redirect toast:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a catch! I see that now with this PR getFailingRules is called only from the INTERNAL_DETECTION_ENGINE_RULE_STATUS_URL route, and I think we should be able to get rid of it completely when we rewrite this route to only return events from the rule execution log.

@yctercero
Copy link
Contributor

Hey @spong , I come in peace I promise 😅 I'd been chatting with @dhurley14 and @rylnd about id vs rule_id stuff this week as platform's been working on some related id regeneration stuff. I know this PR is limited in scope to the filter query for the alerts table but there are a few questions that came up in thinking through all this.

  1. In thinking about RAC/the goal of unified rules/alerts - how, if at all, does observability use rule_id or the concept of SIDs? Would using rule_id here in any way hinder the idea of unified rules/alerts in the scenario where lets say a user would be viewing alerts across solutions? My context might be outdated here, but it seemed back in August we'd been hoping that with RAC we'd move away from our own endpoints to a shared alerts/rule client?

  2. Would we need to implement logic around space-awareness with rule_id in order to align with where Kibana core is heading with shared SOs? That would worry me a little bit just seeing how much work we are currently needing to do in order to align with share-ability when it comes to our own import/export APIs and exposing the origin id. We're still trying to make the move over to the SOM as soon as possible, but with that also comes the uncertainty of being able to have import logic that relies on rule_id like our current implementation.

Please don't take this as me saying rule_id should not be used - it's clear SIDs are important within the security context and rule sharing, but I'm hesitant about using it in a programatic sense here and relying on it to correlate rules <--> signals. I know it's been discussed a ton already, but I'd love to hear what you think about some of this stuff as I haven't been as involved in the rule registry/RAC for a few months and maybe there's context I'm missing.

@spong
Copy link
Member Author

spong commented Dec 3, 2021

Peace offering accepted, haha! 🕊️ 😅 No worries at all @yctercero -- thank you for taking the time to think through the implications and potential externalities here, I really appreciate the extra 👀's and 🧠🔋!

To summarize from our conversation for others (we chatted offline a bit), regardless of the path forward to resolve #118935 (whether pushing down legacyId to the front end, or querying via ruleId), we're going to have to deal with the two concerns outlined above since Security Solution already supports this notion of a secondary static id/SID (signature ID) for our rules. So whether we're aligning for RAC with Stack, O11y and other solutions, or adding support for shared SO's and exposing Security Rules in the SOM, these are bridges we're going to have to cross.

Zooming out, the commonality that surfaced when we were discussing this is a platform need (of the SO Client most likely) to support specifying additional static field(s) when creating SO's. This pattern of specifying secondary static id's exists in quite a few places already within Security Solution (Timeline Templates, Exceptions/Trusted Apps, Rules), and all of these objects are going to need special care when SO sharing or SOM support are introduced if this functionality isn't added.

At the very least, this change specifically is reversible, and if we need to go back to querying alerts via rule.id at some point in the future, we'll have that flexibility. Now if we were making more sweeping (non read-only) correlations between rules <--> alerts, then I would have a bit more concern about the reversibility of these changes, but since it's a read-only operation, and we're still maintaining all the same data as before, I have less hesitation that this change would be reasonable to make at this time.

As an output, we discussed auditing Security Solution for two things:

  1. Auditing the Rules API's for usage of rule.id vs rule.rule_id to ensure we have a solid map of where these touchpoints are and so we can better understand the implications of around questions 1&2 above when that time comes.
  2. Auditing the usage of SO's leveraging secondary static id's so we can get a better picture for a platform requirement for these types of SO's and have a universal way of getting them to work with SO sharing and importing/exporting via SOM (so additional solution-specific middleware validation isn't necessary).

@spong spong requested review from a team December 3, 2021 03:49
@spong spong marked this pull request as ready for review December 3, 2021 03:50
@spong spong requested a review from a team as a code owner December 3, 2021 03:50
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

...buildShowBuildingBlockFilter(showBuildingBlockAlerts),
...buildAlertStatusFilter(filterGroup),
]),
...buildAlertsRuleIdFilter(rule?.rule_id ?? ''),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to refactor this component so that these checks aren't necessary. Right now we're fetching the rule via useRuleWithFallback and have the page in a loading state while rule == null, and all these filters that are being generated aren't needed till the rule returns anyway.

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/rule-data-utils 71 72 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
cases 297.4KB 297.5KB +103.0B
infra 990.9KB 991.3KB +412.0B
observability 362.4KB 362.5KB +103.0B
securitySolution 4.6MB 4.5MB -1.6KB
total -1.0KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
apm 29.3KB 29.4KB +103.0B
securitySolution 243.1KB 243.2KB +103.0B
timelines 164.5KB 164.6KB +103.0B
uptime 23.2KB 23.3KB +103.0B
total +412.0B
Unknown metric groups

API count

id before after diff
@kbn/rule-data-utils 74 75 +1

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @spong

Copy link
Contributor

@banderror banderror left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 Thank you so much for all the thought put into solving this issue, finding a better solution than just passing the legacy id to the FE, adjusting the exceptions logic, for the cleanup and super helpful comments in the code. So much great stuff in this PR!

I went through the code changes and didn't find any issues. Checked the filter used in useRuleWithFallback for fetching the last alert for the rule - seems like @madirey already updated it in her previous PR.

Sorry I didn't test the PR though, I hope that folks could help with that.

Comment on lines +130 to +134
const alertStatusFilter = buildAlertStatusesFilter([
'open',
'acknowledged',
'in-progress',
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Garrett, do you know if a go/no-go decision has been made regarding going live with rule_registry in 8.0? There's still some ongoing discussions regarding AAD schema which is extremely concerning considering where we are in the release cycle. Wondering what are chances of us being asked to revert this stuff back to .siem-signals-* (which means we'd need the ruleRegistryEnabled feature flag in the code):

          // TODO: Once we are past experimental phase this code should be removed
          const alertStatusFilter = ruleRegistryEnabled
            ? buildAlertStatusesFilterRuleRegistry(['open', 'acknowledged', 'in-progress'])
            : buildAlertStatusesFilter(['open', 'acknowledged', 'in-progress']);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified RuleRegistry is a go for security in 8.0, so all good here 🙂

Comment on lines 28 to +34
term: {
'kibana.alert.workflow_status': status,
[ALERT_WORKFLOW_STATUS]: status,
},
},
{
term: {
'kibana.alert.workflow_status': 'in-progress',
[ALERT_WORKFLOW_STATUS]: 'in-progress',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for all the clean up 🙏

Comment on lines +89 to +96
/**
* Builds Kuery filter for fetching alerts for a specific rule. Takes the rule's
* static id, i.e. `rule.ruleId` (not rule.id), so that alerts for _all
* historical instances_ of the rule are returned.
*
* @param ruleStaticId Rule's static id: `rule.ruleId`
*/
export const buildAlertsFilter = (ruleStaticId: string | null): Filter[] =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And thank you for the detailed comments on ruleStaticId explaining what it is and what are the implications of using it ("so that alerts for all historical instances of the rule are returned"). This is really helpful!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course! It gets so confusing between rule.id and rule.rule_id I needed to start clearing things up with differentiating nomenclature. If we're consistent going forward with naming rule.rule_id params as ruleStaticId it should make things a bit easier to grok.

@@ -238,7 +238,7 @@ export const getFailingRules = async (
try {
const errorRules = await Promise.all(
ids.map(async (id) =>
rulesClient.get({
rulesClient.resolve({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a catch! I see that now with this PR getFailingRules is called only from the INTERNAL_DETECTION_ENGINE_RULE_STATUS_URL route, and I think we should be able to get rid of it completely when we rewrite this route to only return events from the rule execution log.

@banderror
Copy link
Contributor

Oh sorry, one more thing

Note, Severity/Risk Score will not display for pre-8.x alerts see this comment for details.

So is this a known issue that is going to be fixed? Do we have a ticket?

@spong
Copy link
Member Author

spong commented Dec 7, 2021

Oh sorry, one more thing

Note, Severity/Risk Score will not display for pre-8.x alerts see this comment for details.

So is this a known issue that is going to be fixed? Do we have a ticket?

This is known (found during that review) and @marshallmain said he would have a fix for this in a follow-up PR, so no specific issue that I'm aware of. I'll check with Marshall to see if there's a draft PR floating around and create an issue if not just so we don't lose it. 👍

edit: Yup, this was added and being tracked as part of this issue/comment: https://github.com/elastic/security-team/issues/1018#issuecomment-937323352

  • Severity and risk_score overrides are being written to kibana.alert.rule.<severity | risk_score instead of kibana.alert.<severity | risk_score>

@spong spong merged commit 3d9bfe2 into elastic:main Dec 8, 2021
@spong spong deleted the rule-details-ruleId branch December 8, 2021 00:13
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Dec 8, 2021
…y RuleId instead of Rule SO ID (elastic#120053)

* Switches RuleDetails to query alerts by ruleId instead of SO id

* Increases integrity of test outputs

* Cleans up duplicate RuleRegistry functions

* Removes support for rule.id for alerts filter and updates exceptions to use new filter
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
8.0

This backport PR will be merged automatically after passing CI.

spong added a commit to spong/kibana that referenced this pull request Dec 8, 2021
…y RuleId instead of Rule SO ID (elastic#120053)

* Switches RuleDetails to query alerts by ruleId instead of SO id

* Increases integrity of test outputs

* Cleans up duplicate RuleRegistry functions

* Removes support for rule.id for alerts filter and updates exceptions to use new filter
spong added a commit that referenced this pull request Dec 8, 2021
…y RuleId instead of Rule SO ID (#120053) (#120710)

* Switches RuleDetails to query alerts by ruleId instead of SO id

* Increases integrity of test outputs

* Cleans up duplicate RuleRegistry functions

* Removes support for rule.id for alerts filter and updates exceptions to use new filter
@spong
Copy link
Member Author

spong commented Dec 16, 2021

As per elastic/security-docs#1321 (comment), updating title and adding to release notes so the behavioral changes are appropriately communicated.

@spong spong changed the title [Security Solution][Detections] Updates RuleDetails to query alerts by RuleId instead of Rule SO ID [Security Solution][Detections] Updates Rule Details to show all historical alerts for a given Rule Dec 16, 2021
@spong spong added release_note:feature Makes this part of the condensed release notes and removed release_note:skip Skip the PR/issue when compiling release notes labels Dec 16, 2021
TinLe pushed a commit to TinLe/kibana that referenced this pull request Dec 22, 2021
…y RuleId instead of Rule SO ID (elastic#120053)

* Switches RuleDetails to query alerts by ruleId instead of SO id

* Increases integrity of test outputs

* Cleans up duplicate RuleRegistry functions

* Removes support for rule.id for alerts filter and updates exceptions to use new filter
nkhristinin added a commit that referenced this pull request Nov 23, 2022
## Closing alerts from flyout effect only alerts related to this rule

Fix: #145675

For the exceptions component, we need to have `rule.rule_id` which
wasn't initially in the timeline response.
We can't safely use `rule.id`, it is [described
here](#120053).

Co-authored-by: Kibana Machine <[email protected]>
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Nov 23, 2022
## Closing alerts from flyout effect only alerts related to this rule

Fix: elastic#145675

For the exceptions component, we need to have `rule.rule_id` which
wasn't initially in the timeline response.
We can't safely use `rule.id`, it is [described
here](elastic#120053).

Co-authored-by: Kibana Machine <[email protected]>
(cherry picked from commit 6102f0e)
kibanamachine referenced this pull request Nov 23, 2022
# Backport

This will backport the following commits from `main` to `8.6`:
- [Fix close alerts from flyout
(#145939)](#145939)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Khristinin
Nikita","email":"[email protected]"},"sourceCommit":{"committedDate":"2022-11-23T17:21:04Z","message":"Fix
close alerts from flyout (#145939)\n\n## Closing alerts from flyout
effect only alerts related to this rule\r\n\r\nFix:
https://github.com/elastic/kibana/issues/145675\r\n\r\nFor the
exceptions component, we need to have `rule.rule_id` which\r\nwasn't
initially in the timeline response.\r\nWe can't safely use `rule.id`, it
is
[described\r\nhere](https://github.com/elastic/kibana/pull/120053).\r\n\r\nCo-authored-by:
Kibana Machine
<[email protected]>","sha":"6102f0e39b1b4053886e1dc6ccd8696fe1bf6967","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Security
Solution
Platform","backport:prev-minor","v8.7.0"],"number":145939,"url":"https://github.com/elastic/kibana/pull/145939","mergeCommit":{"message":"Fix
close alerts from flyout (#145939)\n\n## Closing alerts from flyout
effect only alerts related to this rule\r\n\r\nFix:
https://github.com/elastic/kibana/issues/145675\r\n\r\nFor the
exceptions component, we need to have `rule.rule_id` which\r\nwasn't
initially in the timeline response.\r\nWe can't safely use `rule.id`, it
is
[described\r\nhere](https://github.com/elastic/kibana/pull/120053).\r\n\r\nCo-authored-by:
Kibana Machine
<[email protected]>","sha":"6102f0e39b1b4053886e1dc6ccd8696fe1bf6967"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/145939","number":145939,"mergeCommit":{"message":"Fix
close alerts from flyout (#145939)\n\n## Closing alerts from flyout
effect only alerts related to this rule\r\n\r\nFix:
https://github.com/elastic/kibana/issues/145675\r\n\r\nFor the
exceptions component, we need to have `rule.rule_id` which\r\nwasn't
initially in the timeline response.\r\nWe can't safely use `rule.id`, it
is
[described\r\nhere](https://github.com/elastic/kibana/pull/120053).\r\n\r\nCo-authored-by:
Kibana Machine
<[email protected]>","sha":"6102f0e39b1b4053886e1dc6ccd8696fe1bf6967"}}]}]
BACKPORT-->

Co-authored-by: Khristinin Nikita <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed bug Fixes for quality problems that affect the customer experience Feature:Detection Rules Security Solution rules and Detection Engine release_note:feature Makes this part of the condensed release notes Team:Detection Rule Management Security Detection Rule Management Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.0.0 v8.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants