Skip to content

Commit 393dabf

Browse files
christinewengclintandrewhall
authored andcommitted
[Security Solution] Enable endpoint actions for events (elastic#206857)
## Summary This PR enabled endpoint actions for generic events (in addition to alerts). We want to allow users to perform endpoint related actions like isolate host and respond in the flyout. Main use case is to perform endpoint actions when investigating in analyzer. **Before** ![image](https://github.com/user-attachments/assets/29464129-49ad-4816-9713-c5b3c6c0f06e) **After** Enabled for events when host uses elastic defend ![image](https://github.com/user-attachments/assets/0298022e-5606-4878-8ccd-b63a83d1feb0) Disabled when host cannot be isolated ![image](https://github.com/user-attachments/assets/6aaf8fee-c83c-47f7-909b-5042be066f48) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
1 parent e029f73 commit 393dabf

File tree

11 files changed

+19
-43
lines changed

11 files changed

+19
-43
lines changed

x-pack/platform/plugins/private/translations/translations/fr-FR.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41509,7 +41509,6 @@
4150941509
"xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, =0 {ligne} =1 {ligne} other {lignes}}",
4151041510
"xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, other {processus}}",
4151141511
"xpack.securitySolution.useAlertResponseActionsSupport.missingAgentIdField": "Alerte, les données d'événement ne comportent pas le champ d'identificateur d'agent {agentTypeName} ({missingField}",
41512-
"xpack.securitySolution.useAlertResponseActionsSupport.notAnAlert": "Les actions de réponse ne sont prises en charge que pour les alertes (et non pour les événements)",
4151341512
"xpack.securitySolution.useConsoleActionSubmitter.actionRequestFailure": "Échec de la création d'une requête d'action.",
4151441513
"xpack.securitySolution.useInputHints.exampleInstructions": "Ex : [ {exampleUsage} ]",
4151541514
"xpack.securitySolution.useInputHints.noArguments": "Appuyez sur Entrée pour exécuter",

x-pack/platform/plugins/private/translations/translations/ja-JP.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41484,7 +41484,6 @@
4148441484
"xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, other {行}}",
4148541485
"xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, other {プロセス}}",
4148641486
"xpack.securitySolution.useAlertResponseActionsSupport.missingAgentIdField": "{agentTypeName}エージェントIDフィールド({missingField})が見つからないイベントデータを警告",
41487-
"xpack.securitySolution.useAlertResponseActionsSupport.notAnAlert": "対応アクションはアラートでのみサポートされています(イベントはサポートされていません)",
4148841487
"xpack.securitySolution.useConsoleActionSubmitter.actionRequestFailure": "アクションリクエストを作成できませんでした。",
4148941488
"xpack.securitySolution.useInputHints.exampleInstructions": "例:[ {exampleUsage} ]",
4149041489
"xpack.securitySolution.useInputHints.noArguments": "Enterを押すと実行します",

x-pack/platform/plugins/private/translations/translations/zh-CN.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41547,7 +41547,6 @@
4154741547
"xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, other {行}}",
4154841548
"xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, other {个进程}}",
4154941549
"xpack.securitySolution.useAlertResponseActionsSupport.missingAgentIdField": "告警事件数据缺少 {agentTypeName} 代理标识符字段 ({missingField})",
41550-
"xpack.securitySolution.useAlertResponseActionsSupport.notAnAlert": "仅告警(而不是事件)支持响应操作",
4155141550
"xpack.securitySolution.useConsoleActionSubmitter.actionRequestFailure": "无法创建操作请求。",
4155241551
"xpack.securitySolution.useInputHints.exampleInstructions": "例如:[ {exampleUsage} ]",
4155341552
"xpack.securitySolution.useInputHints.noArguments": "按 Enter 键以执行",

x-pack/solutions/security/plugins/security_solution/public/common/components/endpoint/host_isolation/from_alerts/use_host_isolation_action.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ describe('useHostIsolationAction', () => {
108108
expect(hookProps.closePopover).toHaveBeenCalled();
109109
});
110110

111-
it('should NOT return the menu item for Events', () => {
111+
it('should return the menu item for Events', () => {
112112
hookProps.detailsData = endpointAlertDataMock.generateAlertDetailsItemDataForAgentType('foo', {
113113
'kibana.alert.rule.uuid': undefined,
114114
});
115115
const { result } = render();
116116

117-
expect(result.current).toHaveLength(0);
117+
expect(result.current).toHaveLength(1);
118118
});
119119

120120
it('should NOT return menu item if user does not have authz', async () => {

x-pack/solutions/security/plugins/security_solution/public/common/components/endpoint/host_isolation/from_alerts/use_host_isolation_action.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export interface UseHostIsolationActionProps {
2525
onAddIsolationStatusClick: (action: 'isolateHost' | 'unisolateHost') => void;
2626
}
2727

28+
const emptyArray: AlertTableContextMenuItem[] = [];
29+
2830
export const useHostIsolationAction = ({
2931
closePopover,
3032
detailsData,
@@ -33,7 +35,6 @@ export const useHostIsolationAction = ({
3335
}: UseHostIsolationActionProps): AlertTableContextMenuItem[] => {
3436
const {
3537
isSupported: hostSupportsResponseActions,
36-
isAlert,
3738
unsupportedReason,
3839
details: {
3940
agentType,
@@ -76,9 +77,9 @@ export const useHostIsolationAction = ({
7677
}, [hostSupportsResponseActions, agentStatus]);
7778

7879
return useMemo<AlertTableContextMenuItem[]>(() => {
79-
// If not an Alert OR user has no Authz, then don't show the menu item at all
80-
if (!isAlert || (isHostIsolated && !canUnIsolateHost) || !canIsolateHost) {
81-
return [];
80+
// If user has no Authz, then don't show the menu item at all
81+
if ((isHostIsolated && !canUnIsolateHost) || !canIsolateHost) {
82+
return emptyArray;
8283
}
8384

8485
const menuItem: AlertTableContextMenuItem = {
@@ -109,7 +110,6 @@ export const useHostIsolationAction = ({
109110

110111
return [menuItem];
111112
}, [
112-
isAlert,
113113
isHostIsolated,
114114
canUnIsolateHost,
115115
canIsolateHost,

x-pack/solutions/security/plugins/security_solution/public/common/components/endpoint/responder/from_alerts/use_responder_action_item.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ describe('useResponderActionItem', () => {
5151
expect(renderHook().result.current).toHaveLength(0);
5252
});
5353

54-
it('should NOT return the Respond action menu item for Events', () => {
54+
it('should return the Respond action menu item for Events', () => {
5555
alertDetailItemData = endpointAlertDataMock.generateAlertDetailsItemDataForAgentType('foo', {
5656
'kibana.alert.rule.uuid': undefined,
5757
});
5858

59-
expect(renderHook().result.current).toHaveLength(0);
59+
expect(renderHook().result.current).toHaveLength(1);
6060
});
6161
});

x-pack/solutions/security/plugins/security_solution/public/common/components/endpoint/responder/from_alerts/use_responder_action_item.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import React, { useMemo } from 'react';
99
import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common';
1010
import { FormattedMessage } from '@kbn/i18n-react';
11-
import { useAlertResponseActionsSupport } from '../../../../hooks/endpoint/use_alert_response_actions_support';
1211
import { useUserPrivileges } from '../../../user_privileges';
1312
import type { AlertTableContextMenuItem } from '../../../../../detections/components/alerts_table/types';
1413
import { useWithResponderActionDataFromAlert } from './use_responder_action_data';
@@ -19,7 +18,6 @@ export const useResponderActionItem = (
1918
): AlertTableContextMenuItem[] => {
2019
const { loading: isAuthzLoading, canAccessResponseConsole } =
2120
useUserPrivileges().endpointPrivileges;
22-
const { isAlert } = useAlertResponseActionsSupport(eventDetailsData);
2321
const { handleResponseActionsClick, isDisabled, tooltip } = useWithResponderActionDataFromAlert({
2422
onClick,
2523
eventData: eventDetailsData,
@@ -28,7 +26,7 @@ export const useResponderActionItem = (
2826
return useMemo(() => {
2927
const actions: AlertTableContextMenuItem[] = [];
3028

31-
if (!isAuthzLoading && canAccessResponseConsole && isAlert) {
29+
if (!isAuthzLoading && canAccessResponseConsole) {
3230
actions.push({
3331
key: 'endpointResponseActions-action-item',
3432
'data-test-subj': 'endpointResponseActions-action-item',
@@ -46,12 +44,5 @@ export const useResponderActionItem = (
4644
}
4745

4846
return actions;
49-
}, [
50-
canAccessResponseConsole,
51-
handleResponseActionsClick,
52-
isAlert,
53-
isAuthzLoading,
54-
isDisabled,
55-
tooltip,
56-
]);
47+
}, [canAccessResponseConsole, handleResponseActionsClick, isAuthzLoading, isDisabled, tooltip]);
5748
};

x-pack/solutions/security/plugins/security_solution/public/common/hooks/endpoint/use_alert_response_actions_support.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
import type { AlertResponseActionsSupport } from './use_alert_response_actions_support';
1818
import {
1919
ALERT_EVENT_DATA_MISSING_AGENT_ID_FIELD,
20-
RESPONSE_ACTIONS_ONLY_SUPPORTED_ON_ALERTS,
2120
useAlertResponseActionsSupport,
2221
} from './use_alert_response_actions_support';
2322
import { isAgentTypeAndActionSupported } from '../../lib/endpoint';
@@ -96,7 +95,6 @@ describe('When using `useAlertResponseActionsSupport()` hook', () => {
9695
{
9796
isAlert: false,
9897
isSupported: false,
99-
unsupportedReason: RESPONSE_ACTIONS_ONLY_SUPPORTED_ON_ALERTS,
10098
details: {
10199
agentId: '',
102100
agentIdField: '',
@@ -109,7 +107,7 @@ describe('When using `useAlertResponseActionsSupport()` hook', () => {
109107
);
110108
});
111109

112-
it('should set `isSupported` to `false` for if not an Alert', () => {
110+
it('should set `isSupported` to `true` for if it is not an Alert but supported', () => {
113111
alertDetailItemData = endpointAlertDataMock.generateAlertDetailsItemDataForAgentType(
114112
'sentinel_one',
115113
{ 'kibana.alert.rule.uuid': undefined }
@@ -118,8 +116,7 @@ describe('When using `useAlertResponseActionsSupport()` hook', () => {
118116
expect(renderHook().result.current).toEqual(
119117
getExpectedResult({
120118
isAlert: false,
121-
isSupported: false,
122-
unsupportedReason: RESPONSE_ACTIONS_ONLY_SUPPORTED_ON_ALERTS,
119+
isSupported: true,
123120
details: {
124121
agentType: 'sentinel_one',
125122
agentIdField: RESPONSE_ACTIONS_ALERT_AGENT_ID_FIELDS.sentinel_one[0],

x-pack/solutions/security/plugins/security_solution/public/common/hooks/endpoint/use_alert_response_actions_support.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ export const ALERT_EVENT_DATA_MISSING_AGENT_ID_FIELD = (
3737
);
3838
};
3939

40-
export const RESPONSE_ACTIONS_ONLY_SUPPORTED_ON_ALERTS = i18n.translate(
41-
'xpack.securitySolution.useAlertResponseActionsSupport.notAnAlert',
42-
{ defaultMessage: 'Response actions are only supported for Alerts (not events)' }
43-
);
44-
4540
export interface AlertResponseActionsSupport {
4641
/** Does the host/agent for the given alert have support for response actions */
4742
isSupported: boolean;
@@ -135,8 +130,8 @@ export const useAlertResponseActionsSupport = (
135130
}, [agentType, eventData]);
136131

137132
const doesHostSupportResponseActions = useMemo(() => {
138-
return Boolean(isFeatureEnabled && isAlert && agentId && agentType);
139-
}, [agentId, agentType, isAlert, isFeatureEnabled]);
133+
return Boolean(isFeatureEnabled && agentId && agentType);
134+
}, [agentId, agentType, isFeatureEnabled]);
140135

141136
const supportedActions = useMemo(() => {
142137
return RESPONSE_ACTION_API_COMMANDS_NAMES.reduce<AlertAgentActionsSupported>(
@@ -167,10 +162,6 @@ export const useAlertResponseActionsSupport = (
167162

168163
const unsupportedReason = useMemo(() => {
169164
if (!doesHostSupportResponseActions) {
170-
if (!isAlert) {
171-
return RESPONSE_ACTIONS_ONLY_SUPPORTED_ON_ALERTS;
172-
}
173-
174165
if (!agentType) {
175166
// No message is provided for this condition because the
176167
// return from this hook will always default to `endpoint`
@@ -181,7 +172,7 @@ export const useAlertResponseActionsSupport = (
181172
return ALERT_EVENT_DATA_MISSING_AGENT_ID_FIELD(getAgentTypeName(agentType), agentIdField);
182173
}
183174
}
184-
}, [agentId, agentIdField, agentType, doesHostSupportResponseActions, isAlert]);
175+
}, [agentId, agentIdField, agentType, doesHostSupportResponseActions]);
185176

186177
return useMemo<AlertResponseActionsSupport>(() => {
187178
return {

x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/isolate_host/content.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const PanelContent: FC = () => {
6060
export const IsolateHostPanelContent: FC<{
6161
isIsolateActionSuccessBannerVisible: boolean;
6262
hostName: string;
63-
alertId: string;
63+
alertId?: string;
6464
isolateAction: 'isolateHost' | 'unisolateHost';
6565
dataFormattedForFieldBrowser: TimelineEventsDetailsItem[];
6666
showAlertDetails: () => void;

0 commit comments

Comments
 (0)