From 2947efbf096f5d50458fe2135f90a7d189169a27 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Wed, 2 Jul 2025 12:54:45 +0200 Subject: [PATCH] [Attack Discovery][Scheduling] Make "For each alert" a default action frequency (#225890) ## Summary This came from a testing party which we did with the team on June 30th. There are a list of attack specific fields which are helpful for the user while creating an action for the attack discovery schedule. Those fields are present within the context when the actions frequency set to `"For each alert"` and located under the `context.attack.*`. While testing this functionality, @peluja1012 and @stephmilovic found it not clear that attack context fields are only present in case of `"For each alert"` frequency. One of the reasons was the fact that we set the `"Summary of alerts"` frequency as a default one. Screenshot 2025-06-30 at 19 02 31 With these changes we improve the behaviour and make `"For each alert"` frequency a default one. This way user will have immediately the access to those context fields and more likely to use them. Screenshot 2025-06-30 at 19 03 23 ### To test 1. Navigate to the Attack Discovery page 2. Open Settings flyout 3. Open Schedule tab 4. Click "Create new schedule" button 5. Select one of the actions to add (slack, email etc.) **Expected behaviour**: the `"For each alert"` frequency should be selected by default and `context.attack.*` fields should be available in the `"Add variable"` popover. ## NOTES The feature is hidden behind the feature flag (in `kibana.dev.yml`): ``` feature_flags.overrides: securitySolution.attackDiscoveryAlertsEnabled: true securitySolution.assistantAttackDiscoverySchedulingEnabled: true ``` (cherry picked from commit f606dec7d5fbef8fc8b48847221ace3a4cf28924) --- .../schedule/edit_form/edit_form.test.tsx | 22 ++++++++++++++++--- .../schedule/edit_form/edit_form.tsx | 6 +++++ .../components/rule_actions_field/index.tsx | 10 ++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.test.tsx index 7170086e16867..e851f97f21648 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.test.tsx @@ -79,6 +79,8 @@ const renderComponent = async () => { const getBooleanValueMock = jest.fn(); describe('EditForm', () => { + const mockTriggersActionsUi = triggersActionsUiMock.createStart(); + beforeEach(() => { jest.clearAllMocks(); @@ -92,9 +94,7 @@ describe('EditForm', () => { lens: { EmbeddableComponent: () =>
, }, - triggersActionsUi: { - ...triggersActionsUiMock.createStart(), - }, + triggersActionsUi: mockTriggersActionsUi, uiSettings: { get: jest.fn(), }, @@ -178,4 +178,20 @@ describe('EditForm', () => { expect(onChangeMock).toHaveBeenCalled(); }); + + it('should override default action frequency to `for each alert` instead of `summary of alerts`', async () => { + mockTriggersActionsUi.getActionForm = jest.fn(); + + await renderComponent(); + + expect(mockTriggersActionsUi.getActionForm).toHaveBeenCalledWith( + expect.objectContaining({ + defaultRuleFrequency: { + notifyWhen: 'onActiveAlert', + summary: false, + throttle: null, + }, + }) + ); + }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.tsx b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.tsx index ccfbcbd5a4505..f152d0948f5cc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/schedule/edit_form/edit_form.tsx @@ -8,6 +8,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID } from '@kbn/elastic-assistant-common'; import { getSchema } from './schema'; import type { AttackDiscoveryScheduleSchema } from './types'; @@ -140,6 +141,11 @@ export const EditForm: React.FC = React.memo((props) => { componentProps={{ ruleTypeId: ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID, messageVariables, + defaultRuleFrequency: { + notifyWhen: RuleNotifyWhen.ACTIVE, + throttle: null, + summary: false, + }, }} /> diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/rule_actions_field/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/rule_actions_field/index.tsx index e9d1c452e4e8a..528486db7d0a9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/rule_actions_field/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/rule_actions_field/index.tsx @@ -20,6 +20,7 @@ import type { import type { RuleAction, RuleActionAlertsFilterProperty, + RuleActionFrequency, RuleActionParam, } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; @@ -83,6 +84,7 @@ interface Props { field: FieldHook; messageVariables: ActionVariables; summaryMessageVariables: ActionVariables; + defaultRuleFrequency?: RuleActionFrequency; } const DEFAULT_ACTION_GROUP_ID = 'default'; @@ -119,6 +121,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables, summaryMessageVariables, + defaultRuleFrequency = NOTIFICATION_DEFAULT_FREQUENCY, }) => { const [fieldErrors, setFieldErrors] = useState(null); const form = useFormContext(); @@ -224,14 +227,14 @@ export const RuleActionsField: React.FC = ({ updatedActions[index] = { ...updatedActions[index], frequency: { - ...(updatedActions[index].frequency ?? NOTIFICATION_DEFAULT_FREQUENCY), + ...(updatedActions[index].frequency ?? defaultRuleFrequency), [key]: value, }, }; return updatedActions; }); }, - [field] + [defaultRuleFrequency, field] ); const isFormValidated = isValid !== undefined; @@ -255,7 +258,7 @@ export const RuleActionsField: React.FC = ({ hideActionHeader: true, hasAlertsMappings: true, notifyWhenSelectOptions: NOTIFY_WHEN_OPTIONS, - defaultRuleFrequency: NOTIFICATION_DEFAULT_FREQUENCY, + defaultRuleFrequency, disableErrorMessages: !isFormValidated, }), [ @@ -269,6 +272,7 @@ export const RuleActionsField: React.FC = ({ setActionFrequency, setActionAlertsFilterProperty, ruleTypeId, + defaultRuleFrequency, isFormValidated, ] );