-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[EDR Workflows] Add Cancel response action to MDE #230399
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
Conversation
|
/ci |
# Conflicts: # x-pack/solutions/security/plugins/security_solution/public/management/components/console_argument_selectors/custom_scripts_selector/custom_script_selector.tsx # x-pack/solutions/security/plugins/security_solution/public/management/components/endpoint_responder/lib/console_commands_definition.ts # x-pack/solutions/security/plugins/security_solution/server/endpoint/services/actions/clients/lib/types.ts
|
/ci |
|
/ci |
|
/ci |
|
/ci |
|
@paul-tavares Thanks for the feedback! I applied some changes to the picker's option, and fixed the tooltip. a69afe1 However, regarding
I am not sure what else we should do here — to me handling this scenario differently would be an overkill. Users still can |
…el-action # Conflicts: # x-pack/solutions/security/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/integration_tests/cancel_action.test.tsx
ashokaditya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes in here and patience with continuing with more change requests. I tested it locally and found some issues that I'll list here. I could review backend code so far and would do another round of review for the frontend code shortly.
- Cancel action is available even if there was no action taken or pending. I think it should be disabled when there is no action to cancel. See error shown at the start state when no action has ever been taken.
- I see considerable lag between action taken and it showing up on the cancel action dropdown list, and sometimes the action completes before the cancel action can be taken. See screenshot.
-
Is another user supposed to be able to cancel a cancel action taken by another user? I think not. This should be restricted to the user who took the original action. I see potential issues with allowing cross-user cancel action for a
cancelaction. -
Cancelled cancel actions show up as "successful" actions in the action history, instead of failed like we show for cancelled response actions. This should be consistent. So if we are allowing cancelling cancel action then all cancelled actions should show as failed.
Note: My test clips are bigger than 10 mb for attaching here so I'll send them to you offline
| ) { | ||
| const responseActionAuthzNames = uniq( | ||
| Object.values(RESPONSE_CONSOLE_ACTION_COMMANDS_TO_REQUIRED_AUTHZ) | ||
| Object.values(RESPONSE_CONSOLE_ACTION_COMMANDS_TO_REQUIRED_AUTHZ) as Array<keyof EndpointAuthz> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a redundant cast. TS correctly infers the type of responseActionAuthzNames.
| const legacyResponseData = responseActionsWithLegacyActionProperty.includes(command) | ||
| ? { | ||
| action: actionId ?? data.id ?? '', | ||
| } | ||
| : {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to continue using the deprecated action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now I'd say let's keep it, and if we decide to remove this code - let's do it in a separate PR. Is that ok?
| error?: EcsError; | ||
| /** Host info that might have been stored along with the Action Request (ex. 3rd party EDR actions) */ | ||
| hosts: ActionDetails['hosts']; | ||
| /** Additional metadata that might be stored with the action (ex. 3rd party EDR action IDs) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this meta being used anywhere. Do we need this?
| if (additionalChecks) { | ||
| try { | ||
| await additionalChecks(context, request); | ||
| await additionalChecks(context, request, logger); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes agree. I think best to not make a change to this file at all, when endpointContext can be used for logger. I think this is an unnecessary change here.
| ): Promise<void> => { | ||
| const { parameters } = request.body as CancelActionRequestBody; | ||
| const actionId = parameters.id; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can create the logger here like so, const logger = endpointContext.logFactory.get('cancelActionAdditionalChecks'); here instead of passing a logger in the param of this anonymous async function.
| } | ||
|
|
||
| // Check if Microsoft Defender Endpoint cancel feature is enabled | ||
| if (!featureFlags.microsoftDefenderEndpointCancelEnabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree➕ . The condition should be combined for feature flag and MDE agent type
| 'suspend-process': 'canSuspendProcess', | ||
| scan: 'canWriteScanOperations', | ||
| runscript: 'canWriteExecuteOperations', | ||
| cancel: 'canAccessResponseConsole', // Cancel uses base console permission |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So does this mean if you can't access response console you can't access the API? For example if a user created a release action but wants to cancel it (on a platinum license). You won't be able to do this via API with the current privilege tied to Enterprise license. Cancel action should work via API for all allowable response actions in a downgrade scenario. For instance for release action that is available to non-enterprise users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing to a new privilege that does not expect enterprise license 👍 that's a very good catch @ashokaditya , thanks!
|
|
||
| export interface ResponseActionCancelOutputContent { | ||
| code: string; | ||
| actionId: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the cancelled action's id or the id for the cancel action? Maybe name it so it's clear. Also where is this used? I don't see it being populated in the response of history API or /api/endpoint/action or /api/endpoint/action/cancel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed 👍
| size: 1, | ||
| _source: ['agent', 'device.id', 'event.created'], | ||
| sort: [{ 'event.created': 'desc' }], | ||
| _source: ['agent', 'device.id', '@timestamp'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this bug fix should go in this PR!
| _source: ['agent', 'device.id', '@timestamp'], | ||
| sort: [{ '@timestamp': 'desc' }], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not merge this CS bug fix in this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was merged in another PR, so the change is not included here - but thanks for double checking 👍
|
@ashokaditya Thanks! Good comments, I applied most of them in 3a2d495, fixed the bug where the pending list wasn't refetched too 👍 For the UI discussion we had, I'll create follow up issues so we can make a decision and apply after FF 👍 Big thanks! |
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsESLint disabled line counts
References to deprecated APIs
Total ESLint disabled count
History
cc @tomsonpl |
ashokaditya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the hard work on this, subsequent changes and patience with this @tomsonpl. 🙇🏻 I have not been able to test it again after privilege changes that I thought should be considered and that you promptly added. I'll test it after you merge this and make improvements as we begin to test cancel action.

Summary
This PR introduces cancel action capabilities for Microsoft Defender Endpoint response actions in Kibana's Security Solution. Previously, there was no mechanism to cancel long-running or stuck response actions, creating operational challenges for security analysts managing Microsoft Defender Endpoint hosts.
Problem Statement
Security analysts working with Microsoft Defender Endpoint needed the ability to cancel pending or long-running response actions that may be stuck or no longer needed. Without this capability, they had to wait for actions to timeout or complete naturally, potentially impacting incident response times.
Solution
Core Authorization System
Implemented a dynamic, context-aware authorization system for cancel operations that evaluates permissions based on:
Key Files:
common/endpoint/service/authz/cancel_authz_utils.ts- Authorization utility functionsisCancelFeatureAvailable()- Checks if cancel is available for agent typecanUserCancelCommand()- Validates command-specific permissionscheckCancelPermission()- Complete permission check combining all factorsAPI Layer
Request Schema & Validation:
common/api/endpoint/actions/response_actions/cancel/cancel.ts- Request schema with action_id validationcommon/api/endpoint/actions/response_actions/cancel/cancel.schema.yaml- OpenAPI specificationRoute Implementation:
server/endpoint/routes/actions/response_actions.ts- Cancel route handler that:withEndpointAuthzmiddleware for base permissionsUI Components
Console Integration:
public/management/components/endpoint_responder/command_render_components/cancel_action.tsxPending Actions Selector:
public/management/components/console_argument_selectors/pending_actions_selector/API Communication:
public/management/hooks/response_actions/use_send_cancel_request.tsFeature Flag
Added
microsoftDefenderEndpointCancelEnabledexperimental feature flag to:common/experimental_features.tsTechnical Approach
Permission Model
The implementation uses a dynamic, context-aware authorization model rather than static permissions:
Integration Pattern
The solution integrates seamlessly with existing patterns:
BaseActionRequestSchemafor consistencywithEndpointAuthzmiddlewareTesting
Comprehensive test coverage added:
common/endpoint/service/authz/cancel_authz_utils.test.ts- Authorization logic testsserver/endpoint/routes/actions/response_actions.test.ts- Route handler testspublic/management/components/endpoint_responder/command_render_components/integration_tests/cancel_action.test.tsx- UI integration testspublic/management/components/console_argument_selectors/pending_actions_selector/pending_actions_selector.test.tsx- Selector component testsKey Changes
Modified Files:
canCancelResponseActions: falsetoEndpointAuthzinterface for framework consistencyCANCEL_ROUTEconstant to endpoint route definitionsNew Files:
Impact & Limitations
Benefits:
✅ Security analysts can now cancel stuck or unnecessary Microsoft Defender Endpoint actions
✅ Dynamic permission system ensures proper authorization
✅ Intuitive UI for selecting and cancelling pending actions
✅ Proper API documentation and validation
✅ Follows established architectural patterns
Current Limitations:
Closes: https://github.com/elastic/security-team/issues/13443
Closes: https://github.com/elastic/security-team/issues/13444
Closes: https://github.com/elastic/security-team/issues/13445
Closes: https://github.com/elastic/security-team/issues/13464
Closes: https://github.com/elastic/security-team/issues/13766