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] Handle negative lookback in rule upgrade flyout #204317

Merged

Conversation

maximpn
Copy link
Contributor

@maximpn maximpn commented Dec 14, 2024

Fixes: #202715
Fixes: #204714

Summary

This PR makes inconsistent/wrong rule's look-back duration prominent for a user. It falls back to a default 1 minute value in rule upgrade workflow.

Details

Negative/wrong lookback problem

There is a difference between rule schedule value in a saved object and value represented to users

  • Saved object (and rule management API) has interval, from and to fields representing rule schedule. interval shows how often a rule runs in task runner. from and to stored in date math format like now-10m represent a date time range used to fetch source events. Task manager strives to run rules exactly every interval but it's not always possible due to multiple reasons like system load and various delays. To avoid any gaps to appear from point in time usually stands earlier than current time minus interval, for example interval is 10 minutes and from is now-12m meaning rule will analyze events starting from 12 minutes old. to represents the latest point in time source events will be analyzed.
  • Diffable rule and UI represent rule schedule as interval and lookback. Where interval is the same as above and lookback and a time duration before current time minus interval. For example interval is 10 minutes and lookback is 2 minutes it means a rule will analyzing events starting with 12 minutes old until the current moment in time.

Literally interval, from and to mean a rule runs every interval and analyzes events starting from from until to. Technically from and to may not have any correlation with interval, for example a rule may analyze one year old events. While it's reasonable for manual rule runs and gap remediation the same approach doesn't work well for usual rule schedule. Transformation between interval/from/to and interval/lookback works only when to is equal the current moment in time i.e. now.

Rule management APIs allow to set any from and to values resulting in inconsistent rule schedule. Transformed interval/lookback value won't represent real time interval used to fetch source events for analysis. On top of that negative lookback value may puzzle users on the meaning of the negative sign.

Prebuilt rules with interval/from/to resulting in negative lookback

Some prebuilt rules have such interval, from and to field values thatnegative lookback is expected, for example Multiple Okta Sessions Detected for a Single User. It runs every 60 minutes but has from field set to now-30m and to equals now. In the end we have lookback equals to - from - interval = 30 minutes - 60 minutes = -30 minutes.

Our UI doesn't handle negative lookback values. It simply discards a negative sign and substitutes the rest for editing. In the case above 30 minutes will be suggested for editing. Saving the form will result in changing from to now-90m

image

Changes in this PR

This PR mitigates rule schedule inconsistencies caused by to fields not using the current point in time i.e. now. The following was done

  • DiffableRule's rule_schedule was changed to have interval, from and to fields instead of interval and lookback
  • _perform rule upgrade API endpoint was adapted to the new DIffableRule's rule_schedule
  • Rule upgrade flyout calculates and shows interval and lookback in Diff View, readonly view and field form when lookback is non-negative and to equals now
  • Rule upgrade flyout shows interval, from and to in Diff View, readonly view and field form when to isn't equal now or calculated lookback is negative
  • Rule upgrade flyout shows a warning when to isn't equal now or calculated lookback is negative
  • Rule upgrade flyout's JSON Diff shows interval and lookback when lookback is non-negative and to equals now and shows interval, from and to in any other case
  • Rule details page shows interval, from and to in Diff View, readonly view and field form when to isn't equal now or calculated lookback is negative
  • maxValue was added to ScheduleItemField to have an ability to restrict input at reasonable values

Screenshots

  • Rule upgrade workflow (negative look-back)
Screenshot 2025-01-02 at 13 16 59 Screenshot 2025-01-02 at 13 17 20 Screenshot 2025-01-02 at 13 18 24
  • Rule upgrade workflow (positive look-back)
Screenshot 2025-01-02 at 13 19 12 Screenshot 2025-01-02 at 13 25 31
  • JSON view
Screenshot 2025-01-02 at 13 31 37
  • Rule details page
Screenshot 2025-01-02 at 13 13 16 Screenshot 2025-01-02 at 13 14 10

How to test?

  • Ensure the prebuiltRulesCustomizationEnabled feature flag is enabled
  • Allow internal APIs via adding server.restrictInternalApis: false to kibana.dev.yaml
  • Clear Elasticsearch data
  • Run Elasticsearch and Kibana locally (do not open Kibana in a web browser)
  • Install an outdated version of the security_detection_engine Fleet package
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 2023-10-31" -d '{"force":true}' http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1
  • Install prebuilt rules
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 1" -d '{"mode":"ALL_RULES"}' http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform
  • Set "inconsistent" rule schedule for Suspicious File Creation via Kworker rule by running a query below
curl -X PATCH --user elastic:changeme -H "Content-Type: application/json" -H "elastic-api-version: 2023-10-31" -H "kbn-xsrf: 123" -d '{"rule_id":"ae343298-97bc-47bc-9ea2-5f2ad831c16e","interval":"10m","from":"now-5m","to":"now-2m"}' http://localhost:5601/kbn/api/detection_engine/rules
  • Open rule upgrade flyout for Suspicious File Creation via Kworker rule

@maximpn maximpn added bug Fixes for quality problems that affect the customer experience release_note:skip Skip the PR/issue when compiling release notes impact:high Addressing this issue will have a high level of impact on the quality/strength of our product. v9.0.0 Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detection Rule Management Security Detection Rule Management Team Feature:Prebuilt Detection Rules Security Solution Prebuilt Detection Rules area backport:version Backport to applied version labels v8.18.0 labels Dec 14, 2024
@maximpn maximpn self-assigned this Dec 14, 2024
@maximpn maximpn force-pushed the handle-negative-lookback-in-rule-upgrade-flyout branch 4 times, most recently from 3254df1 to a8dacbc Compare December 17, 2024 08:25
@maximpn maximpn marked this pull request as ready for review December 17, 2024 10:55
@maximpn maximpn requested review from a team as code owners December 17, 2024 10:55
@maximpn maximpn requested review from rylnd and xcrzx December 17, 2024 10:55
@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

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

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detection-rule-management (Team:Detection Rule Management)

@rylnd
Copy link
Contributor

rylnd commented Dec 18, 2024

@maximpn when I follow your instructions and attempt to open the upgrade flyout for the modified rule, I receive the following error, which looks to have been thrown by parseDuration:

Screenshot 2024-12-18 at 1 45 07 PM
The above error occurred in ErrorBoundary:
    at ErrorBoundary (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:173844:7)
    at DragDropContext (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:182244:23)
    at DragDropContextWrapperComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:123797:3)
    at TourContextProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:125963:3)
    at http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.10.js:3132:3
    at div
    at P (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:416847:19797)
    at HomePageComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:119685:3)
    at FilesContext (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/cases/1.0.0/cases.plugin.js:4051:3)
    at QueryClientProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:201457:3)
    at CasesProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/cases/1.0.0/cases.plugin.js:12930:3)
    at Suspense
    at CasesProviderLazyWrapper (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/cases/1.0.0/cases.plugin.js:10620:3)
    at CasesProviderLazyWrapperWithRegistry (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/cases/1.0.0/cases.plugin.js:10648:5)
    at Route (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:365980:29)
    at Route (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:52215:3)
    at Switch (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:366182:29)
    at Routes (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:52349:3)
    at http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:124866:3
    at RenderedRoute (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:364147:5)
    at Routes (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:364708:5)
    at Router (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:364646:15)
    at CompatRouter (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:362673:5)
    at Router (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:365599:30)
    at Router (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:52305:3)
    at ManageRoutesSpyComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:141727:3)
    at PageRouterComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:119811:3)
    at AssistantProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:89064:3)
    at AssistantProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:121929:3)
    at DiscoverInTimelineContextProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:123268:86)
    at http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:135727:3
    at CellActionsProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.7.js:8148:3)
    at QueryClientProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:201457:3)
    at http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.default~lazy_app_links.js:593:3
    at NavigationProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.plugin.js:762:3)
    at ManageUserInfo (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:146394:3)
    at UserPrivilegesProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:135990:3)
    at http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:131967:3
    at Le (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:416847:17442)
    at KibanaStyledComponentsThemeProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/kibanaReact/1.0.0/kibanaReact.plugin.js:2009:3)
    at Provider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:359229:20)
    at ManageGlobalToaster (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.0.js:884:3)
    at ErrorBoundaryInternal (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.js:63384:5)
    at KibanaErrorBoundary (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.js:63445:110)
    at KibanaErrorBoundaryProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.js:63205:3)
    at EuiContext (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:71325:24)
    at IntlProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.js:237142:47)
    at I18nProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.js:57310:3)
    at I18nContext (http://localhost:5601/XXXXXXXXXXXX/bundles/core/core.entry.js:21999:9)
    at EuiComponentDefaultsProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:127252:36)
    at CurrentEuiBreakpointProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:152993:23)
    at ThemeProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:164284:63)
    at EuiEmotionThemeProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:158268:23)
    at EuiThemeMemoizedStylesProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:158743:23)
    at EuiThemeProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:158537:22)
    at EuiSystemColorModeProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:127579:23)
    at EuiCacheProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:127173:20)
    at EuiProviderNestedCheck (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:127405:23)
    at EuiProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js:127465:25)
    at KibanaEuiProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:51630:3)
    at KibanaRootContextProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:51751:3)
    at KibanaRenderContextProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:51528:3)
    at StartAppComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:119310:3)
    at CloudContextProvider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/cloud/1.0.0/cloud.plugin.js:599:7)
    at Provider (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/kibanaReact/1.0.0/kibanaReact.plugin.js:2813:15)
    at SecurityAppComponent (http://localhost:5601/XXXXXXXXXXXX/bundles/plugin/securitySolution/1.0.0/securitySolution.chunk.lazy_application_dependencies.js:119342:3)
    ```
  </details>

@maximpn maximpn force-pushed the handle-negative-lookback-in-rule-upgrade-flyout branch from a8dacbc to 1a0d56f Compare December 19, 2024 00:16
@maximpn
Copy link
Contributor Author

maximpn commented Dec 19, 2024

Hi @rylnd,

are you sure you pulled the latest PR changes? I double checked and it works for me locally as described in the PR description. Could you try removing the branch and pull the latest changes?

@maximpn maximpn force-pushed the handle-negative-lookback-in-rule-upgrade-flyout branch 4 times, most recently from ad57b91 to 54ed57a Compare January 16, 2025 16:04
@banderror
Copy link
Contributor

@elasticmachine merge upstream

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.

Checked the latest code changes and re-tested the app locally.

LGTM, thanks @maximpn.

@banderror
Copy link
Contributor

Files by Code Owner

elastic/kibana-localization

  • x-pack/platform/plugins/private/translations/translations/fr-FR.json
  • x-pack/platform/plugins/private/translations/translations/ja-JP.json
  • x-pack/platform/plugins/private/translations/translations/zh-CN.json

elastic/security-detection-engine

  • x-pack/solutions/security/packages/kbn-securitysolution-utils/date_math.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/kibana.jsonc
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/date_math/calc_date_math_diff.test.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/date_math/calc_date_math_diff.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/date_math/index.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/date_math/normalize_date_math.test.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/date_math/normalize_date_math.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/time_duration/time_duration.test.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/src/time_duration/time_duration.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/time_duration.ts
  • x-pack/solutions/security/packages/kbn-securitysolution-utils/tsconfig.json
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.test.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/history_window_start_edit/history_window_start_edit.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_field/schedule_item_field.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_field/schedule_item_field.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts

elastic/security-detection-rule-management

  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.test.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/per_field_diff/get_field_diffs_for_grouped_fields.test.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/per_field_diff/get_field_diffs_for_grouped_fields.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_diff_tab.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_schedule_section.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/full_rule_schedule_adapter.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/full_rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/index.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/simple_rule_schedule_adapter.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/simple_rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/translations.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/validators/date_math_validator.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/validators/translations.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx
  • x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/diffable_rule_fields_mappings.test.ts
  • x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/diffable_rule_fields_mappings.ts

elastic/security-engineering-productivity

  • x-pack/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts
  • x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules_preview.ts
  • x-pack/test/security_solution_cypress/cypress/tsconfig.json

elastic/security-solution

  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.test.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/to_simple_rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_field_types.ts
  • x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/diffable_rule/diffable_rule.ts
  • x-pack/solutions/security/plugins/security_solution/common/detection_engine/prebuilt_rules/diff/extract_rule_schedule.test.ts
  • x-pack/solutions/security/plugins/security_solution/common/detection_engine/prebuilt_rules/diff/extract_rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/history_window_start_edit/history_window_start_edit.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_field/schedule_item_field.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation/components/schedule_item_field/schedule_item_field.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_schedule_rule/index.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/per_field_diff/get_field_diffs_for_grouped_fields.test.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/per_field_diff/get_field_diffs_for_grouped_fields.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_diff_tab.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_schedule_section.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/comparison_side/get_subfield_changes/rule_schedule.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/full_rule_schedule_adapter.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/full_rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/index.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/simple_rule_schedule_adapter.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/simple_rule_schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/translations.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/validators/date_math_validator.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule/validators/translations.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.stories.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/rule_schedule/rule_schedule.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/translations.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/schedule_form.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx
  • x-pack/solutions/security/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx
  • x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/diffable_rule_fields_mappings.test.ts
  • x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/diffable_rule_fields_mappings.ts

Copy link

@vgomez-el vgomez-el left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@rylnd rylnd left a comment

Choose a reason for hiding this comment

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

@maximpn thank you for taking the time to address feedback, brainstorm, and provide a well-factored solution, here. And thanks as well to @banderror for the thorough review.

Detection engine changes LGTM.

import { calcDateMathDiff } from './calc_date_math_diff';

/**
* Normalizes date math
Copy link
Contributor

Choose a reason for hiding this comment

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

I know we have the tests to demonstrate functionality, but perhaps we could expound here as well:

Suggested change
* Normalizes date math
* Normalizes date math strings by reducing time units, when possible
* Example: "now-60s" -> "now-1h"
* Example: "now-72s" -> "now-72s"

@banderror
Copy link
Contributor

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 6578 6594 +16

Async chunks

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

id before after diff
securitySolution 21.2MB 21.2MB +14.8KB

History

cc @maximpn

@banderror banderror merged commit 30bb71a into elastic:main Jan 20, 2025
9 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.x

https://github.com/elastic/kibana/actions/runs/12869321034

@kibanamachine
Copy link
Contributor

💔 All backports failed

Status Branch Result
8.x Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 204317

Questions ?

Please refer to the Backport tool documentation

@maximpn maximpn deleted the handle-negative-lookback-in-rule-upgrade-flyout branch January 21, 2025 09:01
@maximpn
Copy link
Contributor Author

maximpn commented Jan 21, 2025

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

maximpn added a commit to maximpn/kibana that referenced this pull request Jan 21, 2025
…lastic#204317)

**Fixes: elastic#202715
**Fixes: elastic#204714

## Summary

This PR makes inconsistent/wrong rule's look-back duration prominent for
a user. It falls back to a default 1 minute value in rule upgrade
workflow.

## Details

### Negative/wrong `lookback` problem

There is a difference between rule schedule value in a saved object and
value represented to users

- Saved object (and rule management API) has `interval`, `from` and `to`
fields representing rule schedule. `interval` shows how often a rule
runs in task runner. `from` and `to` stored in date math format like
`now-10m` represent a date time range used to fetch source events. Task
manager strives to run rules exactly every `interval` but it's not
always possible due to multiple reasons like system load and various
delays. To avoid any gaps to appear `from` point in time usually stands
earlier than current time minus `interval`, for example `interval` is
`10 minutes` and `from` is `now-12m` meaning rule will analyze events
starting from 12 minutes old. `to` represents the latest point in time
source events will be analyzed.
- Diffable rule and UI represent rule schedule as `interval` and
`lookback`. Where `interval` is the same as above and `lookback` and a
time duration before current time minus `interval`. For example
`interval` is `10 minutes` and lookback is `2 minutes` it means a rule
will analyzing events starting with 12 minutes old until the current
moment in time.

Literally `interval`, `from` and `to` mean a rule runs every `interval`
and analyzes events starting from `from` until `to`. Technically `from`
and `to` may not have any correlation with `interval`, for example a
rule may analyze one year old events. While it's reasonable for manual
rule runs and gap remediation the same approach doesn't work well for
usual rule schedule. Transformation between `interval`/`from`/`to` and
`interval`/`lookback` works only when `to` is equal the current moment
in time i.e. `now`.

Rule management APIs allow to set any `from` and `to` values resulting
in inconsistent rule schedule. Transformed `interval`/`lookback` value
won't represent real time interval used to fetch source events for
analysis. On top of that negative `lookback` value may puzzle users on
the meaning of the negative sign.

### Prebuilt rules with `interval`/`from`/`to` resulting in negative
`lookback`

Some prebuilt rules have such `interval`, `from` and `to` field values
thatnegative `lookback` is expected, for example `Multiple Okta Sessions
Detected for a Single User`. It runs every `60 minutes` but has `from`
field set to `now-30m` and `to` equals `now`. In the end we have
`lookback` equals `to` - `from` - `interval` = `30 minutes` - `60
minutes` = `-30 minutes`.

Our UI doesn't handle negative `lookback` values. It simply discards a
negative sign and substitutes the rest for editing. In the case above
`30 minutes` will be suggested for editing. Saving the form will result
in changing `from` to `now-90m`

<img width="1712" alt="image"
src="https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2"
/>

### Changes in this PR

This PR mitigates rule schedule inconsistencies caused by `to` fields
not using the current point in time i.e. `now`. The following was done

- `DiffableRule`'s `rule_schedule` was changed to have `interval`,
`from` and `to` fields instead of `interval` and `lookback`
- `_perform` rule upgrade API endpoint was adapted to the new
`DIffableRule`'s `rule_schedule`
- Rule upgrade flyout calculates and shows `interval` and `lookback` in
Diff View, readonly view and field form when `lookback` is non-negative
and `to` equals `now`
- Rule upgrade flyout shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- Rule upgrade flyout shows a warning when `to` isn't equal `now` or
calculated `lookback` is negative
- Rule upgrade flyout's JSON Diff shows `interval` and `lookback` when
`lookback` is non-negative and `to` equals `now` and shows `interval`,
`from` and `to` in any other case
- Rule details page shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- `maxValue` was added to `ScheduleItemField` to have an ability to
restrict input at reasonable values

## Screenshots

- Rule upgrade workflow (negative look-back)

<img width="2558" alt="Screenshot 2025-01-02 at 13 16 59"
src="https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a"
/>

<img width="2553" alt="Screenshot 2025-01-02 at 13 17 20"
src="https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 18 24"
src="https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993"
/>

- Rule upgrade workflow (positive look-back)

<img width="2555" alt="Screenshot 2025-01-02 at 13 19 12"
src="https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 25 31"
src="https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63"
/>

- JSON view

<img width="2559" alt="Screenshot 2025-01-02 at 13 31 37"
src="https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00"
/>

- Rule details page

<img width="2555" alt="Screenshot 2025-01-02 at 13 13 16"
src="https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 14 10"
src="https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173"
/>

## How to test?

- Ensure the `prebuiltRulesCustomizationEnabled` feature flag is enabled
- Allow internal APIs via adding `server.restrictInternalApis: false` to
`kibana.dev.yaml`
- Clear Elasticsearch data
- Run Elasticsearch and Kibana locally (do not open Kibana in a web
browser)
- Install an outdated version of the `security_detection_engine` Fleet
package
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 2023-10-31" -d '{"force":true}' http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1
```

- Install prebuilt rules
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 1" -d '{"mode":"ALL_RULES"}' http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform
```

- Set "inconsistent" rule schedule for `Suspicious File Creation via
Kworker` rule by running a query below
```bash
curl -X PATCH --user elastic:changeme -H "Content-Type: application/json" -H "elastic-api-version: 2023-10-31" -H "kbn-xsrf: 123" -d '{"rule_id":"ae343298-97bc-47bc-9ea2-5f2ad831c16e","interval":"10m","from":"now-5m","to":"now-2m"}' http://localhost:5601/kbn/api/detection_engine/rules
```

- Open rule upgrade flyout for `Suspicious File Creation via Kworker`
rule

---------

Co-authored-by: Elastic Machine <[email protected]>
(cherry picked from commit 30bb71a)

# Conflicts:
#	.github/CODEOWNERS
maximpn added a commit that referenced this pull request Jan 21, 2025
…yout (#204317) (#207302)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Security Solution] Handle negative lookback in rule upgrade flyout
(#204317)](#204317)

<!--- Backport version: 9.6.4 -->

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

<!--BACKPORT [{"author":{"name":"Maxim
Palenov","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-01-20T13:41:23Z","message":"[Security
Solution] Handle negative lookback in rule upgrade flyout
(#204317)\n\n**Fixes:
https://github.com/elastic/kibana/issues/202715**\r\n**Fixes:
https://github.com/elastic/kibana/issues/204714**\r\n\r\n##
Summary\r\n\r\nThis PR makes inconsistent/wrong rule's look-back
duration prominent for\r\na user. It falls back to a default 1 minute
value in rule upgrade\r\nworkflow.\r\n\r\n## Details\r\n\r\n###
Negative/wrong `lookback` problem\r\n\r\nThere is a difference between
rule schedule value in a saved object and\r\nvalue represented to
users\r\n\r\n- Saved object (and rule management API) has `interval`,
`from` and `to`\r\nfields representing rule schedule. `interval` shows
how often a rule\r\nruns in task runner. `from` and `to` stored in date
math format like\r\n`now-10m` represent a date time range used to fetch
source events. Task\r\nmanager strives to run rules exactly every
`interval` but it's not\r\nalways possible due to multiple reasons like
system load and various\r\ndelays. To avoid any gaps to appear `from`
point in time usually stands\r\nearlier than current time minus
`interval`, for example `interval` is\r\n`10 minutes` and `from` is
`now-12m` meaning rule will analyze events\r\nstarting from 12 minutes
old. `to` represents the latest point in time\r\nsource events will be
analyzed.\r\n- Diffable rule and UI represent rule schedule as
`interval` and\r\n`lookback`. Where `interval` is the same as above and
`lookback` and a\r\ntime duration before current time minus `interval`.
For example\r\n`interval` is `10 minutes` and lookback is `2 minutes` it
means a rule\r\nwill analyzing events starting with 12 minutes old until
the current\r\nmoment in time.\r\n\r\nLiterally `interval`, `from` and
`to` mean a rule runs every `interval`\r\nand analyzes events starting
from `from` until `to`. Technically `from`\r\nand `to` may not have any
correlation with `interval`, for example a\r\nrule may analyze one year
old events. While it's reasonable for manual\r\nrule runs and gap
remediation the same approach doesn't work well for\r\nusual rule
schedule. Transformation between `interval`/`from`/`to`
and\r\n`interval`/`lookback` works only when `to` is equal the current
moment\r\nin time i.e. `now`.\r\n\r\nRule management APIs allow to set
any `from` and `to` values resulting\r\nin inconsistent rule schedule.
Transformed `interval`/`lookback` value\r\nwon't represent real time
interval used to fetch source events for\r\nanalysis. On top of that
negative `lookback` value may puzzle users on\r\nthe meaning of the
negative sign.\r\n\r\n### Prebuilt rules with `interval`/`from`/`to`
resulting in negative\r\n`lookback`\r\n\r\nSome prebuilt rules have such
`interval`, `from` and `to` field values\r\nthatnegative `lookback` is
expected, for example `Multiple Okta Sessions\r\nDetected for a Single
User`. It runs every `60 minutes` but has `from`\r\nfield set to
`now-30m` and `to` equals `now`. In the end we have\r\n`lookback` equals
`to` - `from` - `interval` = `30 minutes` - `60\r\nminutes` = `-30
minutes`.\r\n\r\nOur UI doesn't handle negative `lookback` values. It
simply discards a\r\nnegative sign and substitutes the rest for editing.
In the case above\r\n`30 minutes` will be suggested for editing. Saving
the form will result\r\nin changing `from` to `now-90m`\r\n\r\n<img
width=\"1712\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2\"\r\n/>\r\n\r\n###
Changes in this PR\r\n\r\nThis PR mitigates rule schedule
inconsistencies caused by `to` fields\r\nnot using the current point in
time i.e. `now`. The following was done\r\n\r\n- `DiffableRule`'s
`rule_schedule` was changed to have `interval`,\r\n`from` and `to`
fields instead of `interval` and `lookback`\r\n- `_perform` rule upgrade
API endpoint was adapted to the new\r\n`DIffableRule`'s
`rule_schedule`\r\n- Rule upgrade flyout calculates and shows `interval`
and `lookback` in\r\nDiff View, readonly view and field form when
`lookback` is non-negative\r\nand `to` equals `now`\r\n- Rule upgrade
flyout shows `interval`, `from` and `to` in Diff View,\r\nreadonly view
and field form when `to` isn't equal `now` or calculated\r\n`lookback`
is negative\r\n- Rule upgrade flyout shows a warning when `to` isn't
equal `now` or\r\ncalculated `lookback` is negative\r\n- Rule upgrade
flyout's JSON Diff shows `interval` and `lookback` when\r\n`lookback` is
non-negative and `to` equals `now` and shows `interval`,\r\n`from` and
`to` in any other case\r\n- Rule details page shows `interval`, `from`
and `to` in Diff View,\r\nreadonly view and field form when `to` isn't
equal `now` or calculated\r\n`lookback` is negative\r\n- `maxValue` was
added to `ScheduleItemField` to have an ability to\r\nrestrict input at
reasonable values\r\n\r\n## Screenshots\r\n\r\n- Rule upgrade workflow
(negative look-back)\r\n\r\n<img width=\"2558\" alt=\"Screenshot
2025-01-02 at 13 16
59\"\r\nsrc=\"https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a\"\r\n/>\r\n\r\n<img
width=\"2553\" alt=\"Screenshot 2025-01-02 at 13 17
20\"\r\nsrc=\"https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 18
24\"\r\nsrc=\"https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993\"\r\n/>\r\n\r\n-
Rule upgrade workflow (positive look-back)\r\n\r\n<img width=\"2555\"
alt=\"Screenshot 2025-01-02 at 13 19
12\"\r\nsrc=\"https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 25
31\"\r\nsrc=\"https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63\"\r\n/>\r\n\r\n-
JSON view\r\n\r\n<img width=\"2559\" alt=\"Screenshot 2025-01-02 at 13
31
37\"\r\nsrc=\"https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00\"\r\n/>\r\n\r\n-
Rule details page\r\n\r\n<img width=\"2555\" alt=\"Screenshot 2025-01-02
at 13 13
16\"\r\nsrc=\"https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 14
10\"\r\nsrc=\"https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173\"\r\n/>\r\n\r\n##
How to test?\r\n\r\n- Ensure the `prebuiltRulesCustomizationEnabled`
feature flag is enabled\r\n- Allow internal APIs via adding
`server.restrictInternalApis: false` to\r\n`kibana.dev.yaml`\r\n- Clear
Elasticsearch data\r\n- Run Elasticsearch and Kibana locally (do not
open Kibana in a web\r\nbrowser)\r\n- Install an outdated version of the
`security_detection_engine` Fleet\r\npackage\r\n```bash\r\ncurl -X POST
--user elastic:changeme -H 'Content-Type: application/json' -H
'kbn-xsrf: 123' -H \"elastic-api-version: 2023-10-31\" -d
'{\"force\":true}'
http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1\r\n```\r\n\r\n-
Install prebuilt rules\r\n```bash\r\ncurl -X POST --user
elastic:changeme -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'
-H \"elastic-api-version: 1\" -d '{\"mode\":\"ALL_RULES\"}'
http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform\r\n```\r\n\r\n-
Set \"inconsistent\" rule schedule for `Suspicious File Creation
via\r\nKworker` rule by running a query below\r\n```bash\r\ncurl -X
PATCH --user elastic:changeme -H \"Content-Type: application/json\" -H
\"elastic-api-version: 2023-10-31\" -H \"kbn-xsrf: 123\" -d
'{\"rule_id\":\"ae343298-97bc-47bc-9ea2-5f2ad831c16e\",\"interval\":\"10m\",\"from\":\"now-5m\",\"to\":\"now-2m\"}'
http://localhost:5601/kbn/api/detection_engine/rules\r\n```\r\n\r\n-
Open rule upgrade flyout for `Suspicious File Creation via
Kworker`\r\nrule\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"30bb71a516cf0e8e83caab99f9119057a3b1bc82","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","impact:high","v9.0.0","Team:Detections
and Resp","Team: SecuritySolution","Team:Detection Rule
Management","Feature:Prebuilt Detection
Rules","backport:version","v8.18.0"],"title":"[Security Solution] Handle
negative lookback in rule upgrade
flyout","number":204317,"url":"https://github.com/elastic/kibana/pull/204317","mergeCommit":{"message":"[Security
Solution] Handle negative lookback in rule upgrade flyout
(#204317)\n\n**Fixes:
https://github.com/elastic/kibana/issues/202715**\r\n**Fixes:
https://github.com/elastic/kibana/issues/204714**\r\n\r\n##
Summary\r\n\r\nThis PR makes inconsistent/wrong rule's look-back
duration prominent for\r\na user. It falls back to a default 1 minute
value in rule upgrade\r\nworkflow.\r\n\r\n## Details\r\n\r\n###
Negative/wrong `lookback` problem\r\n\r\nThere is a difference between
rule schedule value in a saved object and\r\nvalue represented to
users\r\n\r\n- Saved object (and rule management API) has `interval`,
`from` and `to`\r\nfields representing rule schedule. `interval` shows
how often a rule\r\nruns in task runner. `from` and `to` stored in date
math format like\r\n`now-10m` represent a date time range used to fetch
source events. Task\r\nmanager strives to run rules exactly every
`interval` but it's not\r\nalways possible due to multiple reasons like
system load and various\r\ndelays. To avoid any gaps to appear `from`
point in time usually stands\r\nearlier than current time minus
`interval`, for example `interval` is\r\n`10 minutes` and `from` is
`now-12m` meaning rule will analyze events\r\nstarting from 12 minutes
old. `to` represents the latest point in time\r\nsource events will be
analyzed.\r\n- Diffable rule and UI represent rule schedule as
`interval` and\r\n`lookback`. Where `interval` is the same as above and
`lookback` and a\r\ntime duration before current time minus `interval`.
For example\r\n`interval` is `10 minutes` and lookback is `2 minutes` it
means a rule\r\nwill analyzing events starting with 12 minutes old until
the current\r\nmoment in time.\r\n\r\nLiterally `interval`, `from` and
`to` mean a rule runs every `interval`\r\nand analyzes events starting
from `from` until `to`. Technically `from`\r\nand `to` may not have any
correlation with `interval`, for example a\r\nrule may analyze one year
old events. While it's reasonable for manual\r\nrule runs and gap
remediation the same approach doesn't work well for\r\nusual rule
schedule. Transformation between `interval`/`from`/`to`
and\r\n`interval`/`lookback` works only when `to` is equal the current
moment\r\nin time i.e. `now`.\r\n\r\nRule management APIs allow to set
any `from` and `to` values resulting\r\nin inconsistent rule schedule.
Transformed `interval`/`lookback` value\r\nwon't represent real time
interval used to fetch source events for\r\nanalysis. On top of that
negative `lookback` value may puzzle users on\r\nthe meaning of the
negative sign.\r\n\r\n### Prebuilt rules with `interval`/`from`/`to`
resulting in negative\r\n`lookback`\r\n\r\nSome prebuilt rules have such
`interval`, `from` and `to` field values\r\nthatnegative `lookback` is
expected, for example `Multiple Okta Sessions\r\nDetected for a Single
User`. It runs every `60 minutes` but has `from`\r\nfield set to
`now-30m` and `to` equals `now`. In the end we have\r\n`lookback` equals
`to` - `from` - `interval` = `30 minutes` - `60\r\nminutes` = `-30
minutes`.\r\n\r\nOur UI doesn't handle negative `lookback` values. It
simply discards a\r\nnegative sign and substitutes the rest for editing.
In the case above\r\n`30 minutes` will be suggested for editing. Saving
the form will result\r\nin changing `from` to `now-90m`\r\n\r\n<img
width=\"1712\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2\"\r\n/>\r\n\r\n###
Changes in this PR\r\n\r\nThis PR mitigates rule schedule
inconsistencies caused by `to` fields\r\nnot using the current point in
time i.e. `now`. The following was done\r\n\r\n- `DiffableRule`'s
`rule_schedule` was changed to have `interval`,\r\n`from` and `to`
fields instead of `interval` and `lookback`\r\n- `_perform` rule upgrade
API endpoint was adapted to the new\r\n`DIffableRule`'s
`rule_schedule`\r\n- Rule upgrade flyout calculates and shows `interval`
and `lookback` in\r\nDiff View, readonly view and field form when
`lookback` is non-negative\r\nand `to` equals `now`\r\n- Rule upgrade
flyout shows `interval`, `from` and `to` in Diff View,\r\nreadonly view
and field form when `to` isn't equal `now` or calculated\r\n`lookback`
is negative\r\n- Rule upgrade flyout shows a warning when `to` isn't
equal `now` or\r\ncalculated `lookback` is negative\r\n- Rule upgrade
flyout's JSON Diff shows `interval` and `lookback` when\r\n`lookback` is
non-negative and `to` equals `now` and shows `interval`,\r\n`from` and
`to` in any other case\r\n- Rule details page shows `interval`, `from`
and `to` in Diff View,\r\nreadonly view and field form when `to` isn't
equal `now` or calculated\r\n`lookback` is negative\r\n- `maxValue` was
added to `ScheduleItemField` to have an ability to\r\nrestrict input at
reasonable values\r\n\r\n## Screenshots\r\n\r\n- Rule upgrade workflow
(negative look-back)\r\n\r\n<img width=\"2558\" alt=\"Screenshot
2025-01-02 at 13 16
59\"\r\nsrc=\"https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a\"\r\n/>\r\n\r\n<img
width=\"2553\" alt=\"Screenshot 2025-01-02 at 13 17
20\"\r\nsrc=\"https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 18
24\"\r\nsrc=\"https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993\"\r\n/>\r\n\r\n-
Rule upgrade workflow (positive look-back)\r\n\r\n<img width=\"2555\"
alt=\"Screenshot 2025-01-02 at 13 19
12\"\r\nsrc=\"https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 25
31\"\r\nsrc=\"https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63\"\r\n/>\r\n\r\n-
JSON view\r\n\r\n<img width=\"2559\" alt=\"Screenshot 2025-01-02 at 13
31
37\"\r\nsrc=\"https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00\"\r\n/>\r\n\r\n-
Rule details page\r\n\r\n<img width=\"2555\" alt=\"Screenshot 2025-01-02
at 13 13
16\"\r\nsrc=\"https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 14
10\"\r\nsrc=\"https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173\"\r\n/>\r\n\r\n##
How to test?\r\n\r\n- Ensure the `prebuiltRulesCustomizationEnabled`
feature flag is enabled\r\n- Allow internal APIs via adding
`server.restrictInternalApis: false` to\r\n`kibana.dev.yaml`\r\n- Clear
Elasticsearch data\r\n- Run Elasticsearch and Kibana locally (do not
open Kibana in a web\r\nbrowser)\r\n- Install an outdated version of the
`security_detection_engine` Fleet\r\npackage\r\n```bash\r\ncurl -X POST
--user elastic:changeme -H 'Content-Type: application/json' -H
'kbn-xsrf: 123' -H \"elastic-api-version: 2023-10-31\" -d
'{\"force\":true}'
http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1\r\n```\r\n\r\n-
Install prebuilt rules\r\n```bash\r\ncurl -X POST --user
elastic:changeme -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'
-H \"elastic-api-version: 1\" -d '{\"mode\":\"ALL_RULES\"}'
http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform\r\n```\r\n\r\n-
Set \"inconsistent\" rule schedule for `Suspicious File Creation
via\r\nKworker` rule by running a query below\r\n```bash\r\ncurl -X
PATCH --user elastic:changeme -H \"Content-Type: application/json\" -H
\"elastic-api-version: 2023-10-31\" -H \"kbn-xsrf: 123\" -d
'{\"rule_id\":\"ae343298-97bc-47bc-9ea2-5f2ad831c16e\",\"interval\":\"10m\",\"from\":\"now-5m\",\"to\":\"now-2m\"}'
http://localhost:5601/kbn/api/detection_engine/rules\r\n```\r\n\r\n-
Open rule upgrade flyout for `Suspicious File Creation via
Kworker`\r\nrule\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"30bb71a516cf0e8e83caab99f9119057a3b1bc82"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/204317","number":204317,"mergeCommit":{"message":"[Security
Solution] Handle negative lookback in rule upgrade flyout
(#204317)\n\n**Fixes:
https://github.com/elastic/kibana/issues/202715**\r\n**Fixes:
https://github.com/elastic/kibana/issues/204714**\r\n\r\n##
Summary\r\n\r\nThis PR makes inconsistent/wrong rule's look-back
duration prominent for\r\na user. It falls back to a default 1 minute
value in rule upgrade\r\nworkflow.\r\n\r\n## Details\r\n\r\n###
Negative/wrong `lookback` problem\r\n\r\nThere is a difference between
rule schedule value in a saved object and\r\nvalue represented to
users\r\n\r\n- Saved object (and rule management API) has `interval`,
`from` and `to`\r\nfields representing rule schedule. `interval` shows
how often a rule\r\nruns in task runner. `from` and `to` stored in date
math format like\r\n`now-10m` represent a date time range used to fetch
source events. Task\r\nmanager strives to run rules exactly every
`interval` but it's not\r\nalways possible due to multiple reasons like
system load and various\r\ndelays. To avoid any gaps to appear `from`
point in time usually stands\r\nearlier than current time minus
`interval`, for example `interval` is\r\n`10 minutes` and `from` is
`now-12m` meaning rule will analyze events\r\nstarting from 12 minutes
old. `to` represents the latest point in time\r\nsource events will be
analyzed.\r\n- Diffable rule and UI represent rule schedule as
`interval` and\r\n`lookback`. Where `interval` is the same as above and
`lookback` and a\r\ntime duration before current time minus `interval`.
For example\r\n`interval` is `10 minutes` and lookback is `2 minutes` it
means a rule\r\nwill analyzing events starting with 12 minutes old until
the current\r\nmoment in time.\r\n\r\nLiterally `interval`, `from` and
`to` mean a rule runs every `interval`\r\nand analyzes events starting
from `from` until `to`. Technically `from`\r\nand `to` may not have any
correlation with `interval`, for example a\r\nrule may analyze one year
old events. While it's reasonable for manual\r\nrule runs and gap
remediation the same approach doesn't work well for\r\nusual rule
schedule. Transformation between `interval`/`from`/`to`
and\r\n`interval`/`lookback` works only when `to` is equal the current
moment\r\nin time i.e. `now`.\r\n\r\nRule management APIs allow to set
any `from` and `to` values resulting\r\nin inconsistent rule schedule.
Transformed `interval`/`lookback` value\r\nwon't represent real time
interval used to fetch source events for\r\nanalysis. On top of that
negative `lookback` value may puzzle users on\r\nthe meaning of the
negative sign.\r\n\r\n### Prebuilt rules with `interval`/`from`/`to`
resulting in negative\r\n`lookback`\r\n\r\nSome prebuilt rules have such
`interval`, `from` and `to` field values\r\nthatnegative `lookback` is
expected, for example `Multiple Okta Sessions\r\nDetected for a Single
User`. It runs every `60 minutes` but has `from`\r\nfield set to
`now-30m` and `to` equals `now`. In the end we have\r\n`lookback` equals
`to` - `from` - `interval` = `30 minutes` - `60\r\nminutes` = `-30
minutes`.\r\n\r\nOur UI doesn't handle negative `lookback` values. It
simply discards a\r\nnegative sign and substitutes the rest for editing.
In the case above\r\n`30 minutes` will be suggested for editing. Saving
the form will result\r\nin changing `from` to `now-90m`\r\n\r\n<img
width=\"1712\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2\"\r\n/>\r\n\r\n###
Changes in this PR\r\n\r\nThis PR mitigates rule schedule
inconsistencies caused by `to` fields\r\nnot using the current point in
time i.e. `now`. The following was done\r\n\r\n- `DiffableRule`'s
`rule_schedule` was changed to have `interval`,\r\n`from` and `to`
fields instead of `interval` and `lookback`\r\n- `_perform` rule upgrade
API endpoint was adapted to the new\r\n`DIffableRule`'s
`rule_schedule`\r\n- Rule upgrade flyout calculates and shows `interval`
and `lookback` in\r\nDiff View, readonly view and field form when
`lookback` is non-negative\r\nand `to` equals `now`\r\n- Rule upgrade
flyout shows `interval`, `from` and `to` in Diff View,\r\nreadonly view
and field form when `to` isn't equal `now` or calculated\r\n`lookback`
is negative\r\n- Rule upgrade flyout shows a warning when `to` isn't
equal `now` or\r\ncalculated `lookback` is negative\r\n- Rule upgrade
flyout's JSON Diff shows `interval` and `lookback` when\r\n`lookback` is
non-negative and `to` equals `now` and shows `interval`,\r\n`from` and
`to` in any other case\r\n- Rule details page shows `interval`, `from`
and `to` in Diff View,\r\nreadonly view and field form when `to` isn't
equal `now` or calculated\r\n`lookback` is negative\r\n- `maxValue` was
added to `ScheduleItemField` to have an ability to\r\nrestrict input at
reasonable values\r\n\r\n## Screenshots\r\n\r\n- Rule upgrade workflow
(negative look-back)\r\n\r\n<img width=\"2558\" alt=\"Screenshot
2025-01-02 at 13 16
59\"\r\nsrc=\"https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a\"\r\n/>\r\n\r\n<img
width=\"2553\" alt=\"Screenshot 2025-01-02 at 13 17
20\"\r\nsrc=\"https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 18
24\"\r\nsrc=\"https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993\"\r\n/>\r\n\r\n-
Rule upgrade workflow (positive look-back)\r\n\r\n<img width=\"2555\"
alt=\"Screenshot 2025-01-02 at 13 19
12\"\r\nsrc=\"https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 25
31\"\r\nsrc=\"https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63\"\r\n/>\r\n\r\n-
JSON view\r\n\r\n<img width=\"2559\" alt=\"Screenshot 2025-01-02 at 13
31
37\"\r\nsrc=\"https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00\"\r\n/>\r\n\r\n-
Rule details page\r\n\r\n<img width=\"2555\" alt=\"Screenshot 2025-01-02
at 13 13
16\"\r\nsrc=\"https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe\"\r\n/>\r\n\r\n<img
width=\"2558\" alt=\"Screenshot 2025-01-02 at 13 14
10\"\r\nsrc=\"https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173\"\r\n/>\r\n\r\n##
How to test?\r\n\r\n- Ensure the `prebuiltRulesCustomizationEnabled`
feature flag is enabled\r\n- Allow internal APIs via adding
`server.restrictInternalApis: false` to\r\n`kibana.dev.yaml`\r\n- Clear
Elasticsearch data\r\n- Run Elasticsearch and Kibana locally (do not
open Kibana in a web\r\nbrowser)\r\n- Install an outdated version of the
`security_detection_engine` Fleet\r\npackage\r\n```bash\r\ncurl -X POST
--user elastic:changeme -H 'Content-Type: application/json' -H
'kbn-xsrf: 123' -H \"elastic-api-version: 2023-10-31\" -d
'{\"force\":true}'
http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1\r\n```\r\n\r\n-
Install prebuilt rules\r\n```bash\r\ncurl -X POST --user
elastic:changeme -H 'Content-Type: application/json' -H 'kbn-xsrf: 123'
-H \"elastic-api-version: 1\" -d '{\"mode\":\"ALL_RULES\"}'
http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform\r\n```\r\n\r\n-
Set \"inconsistent\" rule schedule for `Suspicious File Creation
via\r\nKworker` rule by running a query below\r\n```bash\r\ncurl -X
PATCH --user elastic:changeme -H \"Content-Type: application/json\" -H
\"elastic-api-version: 2023-10-31\" -H \"kbn-xsrf: 123\" -d
'{\"rule_id\":\"ae343298-97bc-47bc-9ea2-5f2ad831c16e\",\"interval\":\"10m\",\"from\":\"now-5m\",\"to\":\"now-2m\"}'
http://localhost:5601/kbn/api/detection_engine/rules\r\n```\r\n\r\n-
Open rule upgrade flyout for `Suspicious File Creation via
Kworker`\r\nrule\r\n\r\n---------\r\n\r\nCo-authored-by: Elastic Machine
<[email protected]>","sha":"30bb71a516cf0e8e83caab99f9119057a3b1bc82"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <[email protected]>
cqliu1 pushed a commit to cqliu1/kibana that referenced this pull request Jan 21, 2025
…lastic#204317)

**Fixes: elastic#202715
**Fixes: elastic#204714

## Summary

This PR makes inconsistent/wrong rule's look-back duration prominent for
a user. It falls back to a default 1 minute value in rule upgrade
workflow.

## Details

### Negative/wrong `lookback` problem

There is a difference between rule schedule value in a saved object and
value represented to users

- Saved object (and rule management API) has `interval`, `from` and `to`
fields representing rule schedule. `interval` shows how often a rule
runs in task runner. `from` and `to` stored in date math format like
`now-10m` represent a date time range used to fetch source events. Task
manager strives to run rules exactly every `interval` but it's not
always possible due to multiple reasons like system load and various
delays. To avoid any gaps to appear `from` point in time usually stands
earlier than current time minus `interval`, for example `interval` is
`10 minutes` and `from` is `now-12m` meaning rule will analyze events
starting from 12 minutes old. `to` represents the latest point in time
source events will be analyzed.
- Diffable rule and UI represent rule schedule as `interval` and
`lookback`. Where `interval` is the same as above and `lookback` and a
time duration before current time minus `interval`. For example
`interval` is `10 minutes` and lookback is `2 minutes` it means a rule
will analyzing events starting with 12 minutes old until the current
moment in time.

Literally `interval`, `from` and `to` mean a rule runs every `interval`
and analyzes events starting from `from` until `to`. Technically `from`
and `to` may not have any correlation with `interval`, for example a
rule may analyze one year old events. While it's reasonable for manual
rule runs and gap remediation the same approach doesn't work well for
usual rule schedule. Transformation between `interval`/`from`/`to` and
`interval`/`lookback` works only when `to` is equal the current moment
in time i.e. `now`.

Rule management APIs allow to set any `from` and `to` values resulting
in inconsistent rule schedule. Transformed `interval`/`lookback` value
won't represent real time interval used to fetch source events for
analysis. On top of that negative `lookback` value may puzzle users on
the meaning of the negative sign.

### Prebuilt rules with `interval`/`from`/`to` resulting in negative
`lookback`

Some prebuilt rules have such `interval`, `from` and `to` field values
thatnegative `lookback` is expected, for example `Multiple Okta Sessions
Detected for a Single User`. It runs every `60 minutes` but has `from`
field set to `now-30m` and `to` equals `now`. In the end we have
`lookback` equals `to` - `from` - `interval` = `30 minutes` - `60
minutes` = `-30 minutes`.

Our UI doesn't handle negative `lookback` values. It simply discards a
negative sign and substitutes the rest for editing. In the case above
`30 minutes` will be suggested for editing. Saving the form will result
in changing `from` to `now-90m`

<img width="1712" alt="image"
src="https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2"
/>

### Changes in this PR

This PR mitigates rule schedule inconsistencies caused by `to` fields
not using the current point in time i.e. `now`. The following was done

- `DiffableRule`'s `rule_schedule` was changed to have `interval`,
`from` and `to` fields instead of `interval` and `lookback`
- `_perform` rule upgrade API endpoint was adapted to the new
`DIffableRule`'s `rule_schedule`
- Rule upgrade flyout calculates and shows `interval` and `lookback` in
Diff View, readonly view and field form when `lookback` is non-negative
and `to` equals `now`
- Rule upgrade flyout shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- Rule upgrade flyout shows a warning when `to` isn't equal `now` or
calculated `lookback` is negative
- Rule upgrade flyout's JSON Diff shows `interval` and `lookback` when
`lookback` is non-negative and `to` equals `now` and shows `interval`,
`from` and `to` in any other case
- Rule details page shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- `maxValue` was added to `ScheduleItemField` to have an ability to
restrict input at reasonable values

## Screenshots

- Rule upgrade workflow (negative look-back)

<img width="2558" alt="Screenshot 2025-01-02 at 13 16 59"
src="https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a"
/>

<img width="2553" alt="Screenshot 2025-01-02 at 13 17 20"
src="https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 18 24"
src="https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993"
/>

- Rule upgrade workflow (positive look-back)

<img width="2555" alt="Screenshot 2025-01-02 at 13 19 12"
src="https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 25 31"
src="https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63"
/>

- JSON view

<img width="2559" alt="Screenshot 2025-01-02 at 13 31 37"
src="https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00"
/>

- Rule details page

<img width="2555" alt="Screenshot 2025-01-02 at 13 13 16"
src="https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 14 10"
src="https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173"
/>

## How to test?

- Ensure the `prebuiltRulesCustomizationEnabled` feature flag is enabled
- Allow internal APIs via adding `server.restrictInternalApis: false` to
`kibana.dev.yaml`
- Clear Elasticsearch data
- Run Elasticsearch and Kibana locally (do not open Kibana in a web
browser)
- Install an outdated version of the `security_detection_engine` Fleet
package
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 2023-10-31" -d '{"force":true}' http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1
```

- Install prebuilt rules
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 1" -d '{"mode":"ALL_RULES"}' http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform
```

- Set "inconsistent" rule schedule for `Suspicious File Creation via
Kworker` rule by running a query below
```bash
curl -X PATCH --user elastic:changeme -H "Content-Type: application/json" -H "elastic-api-version: 2023-10-31" -H "kbn-xsrf: 123" -d '{"rule_id":"ae343298-97bc-47bc-9ea2-5f2ad831c16e","interval":"10m","from":"now-5m","to":"now-2m"}' http://localhost:5601/kbn/api/detection_engine/rules
```

- Open rule upgrade flyout for `Suspicious File Creation via Kworker`
rule

---------

Co-authored-by: Elastic Machine <[email protected]>
viduni94 pushed a commit to viduni94/kibana that referenced this pull request Jan 23, 2025
…lastic#204317)

**Fixes: elastic#202715
**Fixes: elastic#204714

## Summary

This PR makes inconsistent/wrong rule's look-back duration prominent for
a user. It falls back to a default 1 minute value in rule upgrade
workflow.

## Details

### Negative/wrong `lookback` problem

There is a difference between rule schedule value in a saved object and
value represented to users

- Saved object (and rule management API) has `interval`, `from` and `to`
fields representing rule schedule. `interval` shows how often a rule
runs in task runner. `from` and `to` stored in date math format like
`now-10m` represent a date time range used to fetch source events. Task
manager strives to run rules exactly every `interval` but it's not
always possible due to multiple reasons like system load and various
delays. To avoid any gaps to appear `from` point in time usually stands
earlier than current time minus `interval`, for example `interval` is
`10 minutes` and `from` is `now-12m` meaning rule will analyze events
starting from 12 minutes old. `to` represents the latest point in time
source events will be analyzed.
- Diffable rule and UI represent rule schedule as `interval` and
`lookback`. Where `interval` is the same as above and `lookback` and a
time duration before current time minus `interval`. For example
`interval` is `10 minutes` and lookback is `2 minutes` it means a rule
will analyzing events starting with 12 minutes old until the current
moment in time.

Literally `interval`, `from` and `to` mean a rule runs every `interval`
and analyzes events starting from `from` until `to`. Technically `from`
and `to` may not have any correlation with `interval`, for example a
rule may analyze one year old events. While it's reasonable for manual
rule runs and gap remediation the same approach doesn't work well for
usual rule schedule. Transformation between `interval`/`from`/`to` and
`interval`/`lookback` works only when `to` is equal the current moment
in time i.e. `now`.

Rule management APIs allow to set any `from` and `to` values resulting
in inconsistent rule schedule. Transformed `interval`/`lookback` value
won't represent real time interval used to fetch source events for
analysis. On top of that negative `lookback` value may puzzle users on
the meaning of the negative sign.

### Prebuilt rules with `interval`/`from`/`to` resulting in negative
`lookback`

Some prebuilt rules have such `interval`, `from` and `to` field values
thatnegative `lookback` is expected, for example `Multiple Okta Sessions
Detected for a Single User`. It runs every `60 minutes` but has `from`
field set to `now-30m` and `to` equals `now`. In the end we have
`lookback` equals `to` - `from` - `interval` = `30 minutes` - `60
minutes` = `-30 minutes`.

Our UI doesn't handle negative `lookback` values. It simply discards a
negative sign and substitutes the rest for editing. In the case above
`30 minutes` will be suggested for editing. Saving the form will result
in changing `from` to `now-90m`

<img width="1712" alt="image"
src="https://github.com/user-attachments/assets/05519743-9562-4874-8a73-5596eeccacf2"
/>

### Changes in this PR

This PR mitigates rule schedule inconsistencies caused by `to` fields
not using the current point in time i.e. `now`. The following was done

- `DiffableRule`'s `rule_schedule` was changed to have `interval`,
`from` and `to` fields instead of `interval` and `lookback`
- `_perform` rule upgrade API endpoint was adapted to the new
`DIffableRule`'s `rule_schedule`
- Rule upgrade flyout calculates and shows `interval` and `lookback` in
Diff View, readonly view and field form when `lookback` is non-negative
and `to` equals `now`
- Rule upgrade flyout shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- Rule upgrade flyout shows a warning when `to` isn't equal `now` or
calculated `lookback` is negative
- Rule upgrade flyout's JSON Diff shows `interval` and `lookback` when
`lookback` is non-negative and `to` equals `now` and shows `interval`,
`from` and `to` in any other case
- Rule details page shows `interval`, `from` and `to` in Diff View,
readonly view and field form when `to` isn't equal `now` or calculated
`lookback` is negative
- `maxValue` was added to `ScheduleItemField` to have an ability to
restrict input at reasonable values

## Screenshots

- Rule upgrade workflow (negative look-back)

<img width="2558" alt="Screenshot 2025-01-02 at 13 16 59"
src="https://github.com/user-attachments/assets/b8bf727f-11ca-424f-892b-b024ba7f847a"
/>

<img width="2553" alt="Screenshot 2025-01-02 at 13 17 20"
src="https://github.com/user-attachments/assets/9f751ea4-0ce0-4a23-a3b7-0a16494d957e"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 18 24"
src="https://github.com/user-attachments/assets/6908ab02-4011-4a6e-85ce-e60d5eac7993"
/>

- Rule upgrade workflow (positive look-back)

<img width="2555" alt="Screenshot 2025-01-02 at 13 19 12"
src="https://github.com/user-attachments/assets/06208210-c6cd-4842-8aef-6ade5d13bd36"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 25 31"
src="https://github.com/user-attachments/assets/aed38bb0-ccfb-479a-bb3b-e5442c518e63"
/>

- JSON view

<img width="2559" alt="Screenshot 2025-01-02 at 13 31 37"
src="https://github.com/user-attachments/assets/07575a81-676f-418e-8b98-48eefe11ab00"
/>

- Rule details page

<img width="2555" alt="Screenshot 2025-01-02 at 13 13 16"
src="https://github.com/user-attachments/assets/e977b752-9d50-4049-917a-af2e8e3f0dfe"
/>

<img width="2558" alt="Screenshot 2025-01-02 at 13 14 10"
src="https://github.com/user-attachments/assets/06d6f477-5730-48ca-a240-b5e7592bf173"
/>

## How to test?

- Ensure the `prebuiltRulesCustomizationEnabled` feature flag is enabled
- Allow internal APIs via adding `server.restrictInternalApis: false` to
`kibana.dev.yaml`
- Clear Elasticsearch data
- Run Elasticsearch and Kibana locally (do not open Kibana in a web
browser)
- Install an outdated version of the `security_detection_engine` Fleet
package
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 2023-10-31" -d '{"force":true}' http://localhost:5601/kbn/api/fleet/epm/packages/security_detection_engine/8.14.1
```

- Install prebuilt rules
```bash
curl -X POST --user elastic:changeme  -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 1" -d '{"mode":"ALL_RULES"}' http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform
```

- Set "inconsistent" rule schedule for `Suspicious File Creation via
Kworker` rule by running a query below
```bash
curl -X PATCH --user elastic:changeme -H "Content-Type: application/json" -H "elastic-api-version: 2023-10-31" -H "kbn-xsrf: 123" -d '{"rule_id":"ae343298-97bc-47bc-9ea2-5f2ad831c16e","interval":"10m","from":"now-5m","to":"now-2m"}' http://localhost:5601/kbn/api/detection_engine/rules
```

- Open rule upgrade flyout for `Suspicious File Creation via Kworker`
rule

---------

Co-authored-by: Elastic Machine <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:version Backport to applied version labels bug Fixes for quality problems that affect the customer experience Feature:Prebuilt Detection Rules Security Solution Prebuilt Detection Rules area impact:high Addressing this issue will have a high level of impact on the quality/strength of our product. release_note:skip Skip the PR/issue when compiling 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.18.0 v9.0.0
Projects
None yet
6 participants