Skip to content

Commit

Permalink
[SecuritySolutions][Endpoint] Microsoft defender for Endpoint respons…
Browse files Browse the repository at this point in the history
…e actions API (elastic#205097)

## Summary

- Adds response actions client/APIs for isolate and release actions for
Microsoft Defender for Endpoint
- The feature is behind a feature flag
`responseActionsMSDefenderEndpointEnabled`
  • Loading branch information
ashokaditya authored Jan 9, 2025
1 parent 737cf96 commit b25c998
Show file tree
Hide file tree
Showing 30 changed files with 1,291 additions and 58 deletions.
2 changes: 2 additions & 0 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46558,10 +46558,12 @@ components:
- minLength: 1
type: string
Security_Endpoint_Management_API_AgentTypes:
description: The host agent type (optional). Defaults to endpoint.
enum:
- endpoint
- sentinel_one
- crowdstrike
- microsoft_defender_endpoint
type: string
Security_Endpoint_Management_API_AlertIds:
description: A list of alerts ids.
Expand Down
2 changes: 2 additions & 0 deletions oas_docs/output/kibana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53434,10 +53434,12 @@ components:
- minLength: 1
type: string
Security_Endpoint_Management_API_AgentTypes:
description: The host agent type (optional). Defaults to endpoint.
enum:
- endpoint
- sentinel_one
- crowdstrike
- microsoft_defender_endpoint
type: string
Security_Endpoint_Management_API_AlertIds:
description: A list of alerts ids.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,16 @@ export const Comment = z.string();
export type Parameters = z.infer<typeof Parameters>;
export const Parameters = z.object({});

/**
* The host agent type (optional). Defaults to endpoint.
*/
export type AgentTypes = z.infer<typeof AgentTypes>;
export const AgentTypes = z.enum(['endpoint', 'sentinel_one', 'crowdstrike']);
export const AgentTypes = z.enum([
'endpoint',
'sentinel_one',
'crowdstrike',
'microsoft_defender_endpoint',
]);
export type AgentTypesEnum = typeof AgentTypes.enum;
export const AgentTypesEnum = AgentTypes.enum;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@ components:
description: Optional parameters object
AgentTypes:
type: string
description: The host agent type (optional). Defaults to endpoint.
enum:
- endpoint
- sentinel_one
- crowdstrike
- microsoft_defender_endpoint

BaseActionSchema:
x-inline: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ export type ResponseActionStatus = (typeof RESPONSE_ACTION_STATUS)[number];
export const RESPONSE_ACTION_TYPE = ['automated', 'manual'] as const;
export type ResponseActionType = (typeof RESPONSE_ACTION_TYPE)[number];

export const RESPONSE_ACTION_AGENT_TYPE = ['endpoint', 'sentinel_one', 'crowdstrike'] as const;
export const RESPONSE_ACTION_AGENT_TYPE = [
'endpoint',
'sentinel_one',
'crowdstrike',
'microsoft_defender_endpoint',
] as const;
export type ResponseActionAgentType = (typeof RESPONSE_ACTION_AGENT_TYPE)[number];

/**
Expand Down Expand Up @@ -181,6 +186,7 @@ export const RESPONSE_ACTIONS_ZIP_PASSCODE: Readonly<Record<ResponseActionAgentT
endpoint: 'elastic',
sentinel_one: 'Elastic@123',
crowdstrike: 'tbd..',
microsoft_defender_endpoint: 'tbd..',
});

/**
Expand All @@ -206,6 +212,8 @@ export const RESPONSE_ACTIONS_ALERT_AGENT_ID_FIELDS: Readonly<
'sentinel_one.agent.agent.id',
],
crowdstrike: ['device.id'],
// FIXME:PT temporary change. Tests for MS defender will be in PR https://github.com/elastic/kibana/pull/205012
microsoft_defender_endpoint: ['some.id'],
});

export const SUPPORTED_AGENT_ID_ALERT_FIELDS: Readonly<string[]> = Object.values(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,119 +23,139 @@ const RESPONSE_ACTIONS_SUPPORT_MAP: SupportMap = {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: true,
crowdstrike: true,
microsoft_defender_endpoint: true,
},
},
unisolate: {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: true,
crowdstrike: true,
microsoft_defender_endpoint: true,
},
},
upload: {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
'get-file': {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: true,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
'kill-process': {
automated: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: true,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
execute: {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
'suspend-process': {
automated: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
'running-processes': {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: true,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
scan: {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: true,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
},
runscript: {
automated: {
endpoint: false,
sentinel_one: false,
crowdstrike: false,
microsoft_defender_endpoint: false,
},
manual: {
endpoint: false,
sentinel_one: false,
crowdstrike: true,
microsoft_defender_endpoint: false,
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './trusted_apps';
export * from './utility_types';
export * from './agents';
export * from './sentinel_one';
export * from './microsoft_defender_endpoint';
export type { ConditionEntriesMap, ConditionEntry } from './exception_list_items';

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export interface MicrosoftDefenderEndpointActionRequestCommonMeta {
/** The ID of the action in Microsoft Defender's system */
machineActionId: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ export const allowedExperimentalValues = Object.freeze({
* Enables the Asset Inventory feature
*/
assetInventoryUXEnabled: false,

/**
* Enabled Microsoft Defender for Endpoint actions client
*/
responseActionsMSDefenderEndpointEnabled: false,
});

type ExperimentalConfigKeys = Array<keyof ExperimentalFeatures>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,12 @@ components:
- minLength: 1
type: string
AgentTypes:
description: The host agent type (optional). Defaults to endpoint.
enum:
- endpoint
- sentinel_one
- crowdstrike
- microsoft_defender_endpoint
type: string
AlertIds:
description: A list of alerts ids.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,12 @@ components:
- minLength: 1
type: string
AgentTypes:
description: The host agent type (optional). Defaults to endpoint.
enum:
- endpoint
- sentinel_one
- crowdstrike
- microsoft_defender_endpoint
type: string
AlertIds:
description: A list of alerts ids.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ describe('AgentTypeVendorLogo component', () => {
};
});

it.each(RESPONSE_ACTION_AGENT_TYPE)('should display logo for: %s', async (agentType) => {
// FIXME:PT temporary change. Tests for MS defender will be in PR https://github.com/elastic/kibana/pull/205012
it.each(
RESPONSE_ACTION_AGENT_TYPE.filter((agentType) => agentType !== 'microsoft_defender_endpoint')
)('should display logo for: %s', async (agentType) => {
props.agentType = agentType;
const { getByTitle } = render();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ describe('use responder action data hooks', () => {
expect(onClickMock).not.toHaveBeenCalled();
});

it.each([...RESPONSE_ACTION_AGENT_TYPE])(
it.each([
// FIXME:PT temporary change. Tests for MS defender will be in PR https://github.com/elastic/kibana/pull/205012
...RESPONSE_ACTION_AGENT_TYPE.filter(
(agentType) => agentType !== 'microsoft_defender_endpoint'
),
])(
'should show action disabled with tooltip for %s if agent id field is missing',
(agentType) => {
const agentTypeField = RESPONSE_ACTIONS_ALERT_AGENT_ID_FIELDS[agentType][0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,15 @@ describe('When using `useAlertResponseActionsSupport()` hook', () => {
appContextMock.renderHook(() => useAlertResponseActionsSupport(alertDetailItemData));
});

it.each(RESPONSE_ACTION_AGENT_TYPE)(
'should return expected response for agentType: `%s`',
(agentType) => {
alertDetailItemData =
endpointAlertDataMock.generateAlertDetailsItemDataForAgentType(agentType);
const { result } = renderHook();

expect(result.current).toEqual(getExpectedResult({ details: { agentType } }));
}
);
it.each(
// FIXME:PT temporary change. Tests for MS defender will be in PR https://github.com/elastic/kibana/pull/205012
RESPONSE_ACTION_AGENT_TYPE.filter((agentType) => agentType !== 'microsoft_defender_endpoint')
)('should return expected response for agentType: `%s`', (agentType) => {
alertDetailItemData = endpointAlertDataMock.generateAlertDetailsItemDataForAgentType(agentType);
const { result } = renderHook();

expect(result.current).toEqual(getExpectedResult({ details: { agentType } }));
});

it('should set `isSupported` to `false` if no alert details item data is provided', () => {
alertDetailItemData = [];
Expand Down Expand Up @@ -178,7 +177,9 @@ describe('When using `useAlertResponseActionsSupport()` hook', () => {
});

it.each(
RESPONSE_ACTION_AGENT_TYPE.filter((agentType) => agentType !== 'endpoint') as Array<
RESPONSE_ACTION_AGENT_TYPE.filter((agentType) => agentType !== 'endpoint')
// FIXME:PT temporary change. Tests for MS defender will be in PR https://github.com/elastic/kibana/pull/205012
.filter((agentType) => agentType !== 'microsoft_defender_endpoint') as Array<
Exclude<ResponseActionAgentType, 'endpoint'>
>
)('should set `isSupported` to `false` for [%s] if feature flag is disabled', (agentType) => {
Expand Down
Loading

0 comments on commit b25c998

Please sign in to comment.