From a237f591dca6eea2e212418ec844729e38bb67e3 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Tue, 6 Aug 2024 11:38:46 +0200 Subject: [PATCH] remove automated actions feature flags --- .../common/experimental_features.ts | 10 -- .../components/event_details/osquery_tab.tsx | 104 ------------------ .../event_details/response_actions_view.tsx | 5 +- .../components/step_rule_actions/index.tsx | 6 +- .../get_supported_response_actions.ts | 2 - .../use_supported_response_action_types.tsx | 11 +- .../left/components/response_details.test.tsx | 25 ----- .../left/components/response_details.tsx | 13 +-- .../components/actions_log_filters.tsx | 42 +++---- .../api/rules/create_rule/route.test.ts | 4 - .../api/rules/update_rule/route.test.ts | 4 - .../rule_management/utils/validate.ts | 4 +- .../test/defend_workflows_cypress/config.ts | 3 - 13 files changed, 23 insertions(+), 210 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/common/components/event_details/osquery_tab.tsx diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index cc38eefffe5f2..92f4b61bf0f25 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -42,16 +42,6 @@ export const allowedExperimentalValues = Object.freeze({ */ socTrendsEnabled: false, - /** - * Enables the automated response actions in rule + alerts - */ - responseActionsEnabled: true, - - /** - * Enables the automated endpoint response action in rule + alerts - */ - endpointResponseActionsEnabled: true, - /** * Enables the `upload` endpoint response action (v8.9) */ diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/osquery_tab.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/osquery_tab.tsx deleted file mode 100644 index be2bcddfca3e6..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/event_details/osquery_tab.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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. - */ - -import type { EuiTabbedContentTab } from '@elastic/eui'; -import { EuiNotificationBadge, EuiSpacer } from '@elastic/eui'; -import React from 'react'; -import styled from 'styled-components'; -import type { Ecs } from '@kbn/cases-plugin/common'; -import type { SearchHit } from '../../../../common/search_strategy'; -import type { - ExpandedEventFieldsObject, - RawEventData, -} from '../../../../common/types/response_actions'; -import { expandDottedObject } from '../../../../common/utils/expand_dotted'; -import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; -import { useKibana } from '../../lib/kibana'; -import { EventsViewType } from './event_details'; -import * as i18n from './translations'; -import { ResponseActionTypesEnum } from '../../../../common/api/detection_engine/model/rule_response_actions'; - -const TabContentWrapper = styled.div` - height: 100%; - position: relative; -`; - -// TODO: MOVE TO FLYOUT FOLDER - https://github.com/elastic/security-team/issues/7462 -export const useOsqueryTab = ({ - rawEventData, - ecsData, -}: { - rawEventData?: SearchHit | undefined; - ecsData?: Ecs | null; -}): EuiTabbedContentTab | undefined => { - const { - services: { osquery }, - } = useKibana(); - const responseActionsEnabled = useIsExperimentalFeatureEnabled('responseActionsEnabled'); - const endpointResponseActionsEnabled = useIsExperimentalFeatureEnabled( - 'endpointResponseActionsEnabled' - ); - - const expandedEventFieldsObject = rawEventData - ? (expandDottedObject((rawEventData as RawEventData).fields) as ExpandedEventFieldsObject) - : undefined; - - const responseActions = - expandedEventFieldsObject?.kibana?.alert?.rule?.parameters?.[0].response_actions; - - const shouldEarlyReturn = - !rawEventData || - !responseActionsEnabled || - endpointResponseActionsEnabled || - !ecsData || - !responseActions?.length; - - const alertId = rawEventData?._id ?? ''; - - const { OsqueryResults, fetchAllLiveQueries } = osquery; - - const { data: actionsData } = fetchAllLiveQueries({ - kuery: `alert_ids: ( ${alertId} )`, - alertId, - skip: shouldEarlyReturn, - }); - - if (shouldEarlyReturn) { - return; - } - - const osqueryResponseActions = responseActions.filter( - (responseAction) => responseAction.action_type_id === ResponseActionTypesEnum['.osquery'] - ); - - if (!osqueryResponseActions?.length) { - return; - } - - const actionItems = actionsData?.data.items || []; - - const ruleName = expandedEventFieldsObject?.kibana?.alert?.rule?.name?.[0]; - - const content = ( - - - - - ); - - return { - id: EventsViewType.osqueryView, - 'data-test-subj': 'osqueryViewTab', - name: i18n.OSQUERY_VIEW, - append: ( - - {actionItems.length} - - ), - content, - }; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/response_actions_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/response_actions_view.tsx index 4f6bbac5df419..33760b7ab4242 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/response_actions_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/response_actions_view.tsx @@ -23,8 +23,6 @@ import { useGetAutomatedActionList } from '../../../management/hooks/response_ac import { EventsViewType } from './event_details'; import * as i18n from './translations'; -import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; - const TabContentWrapper = styled.div` height: 100%; position: relative; @@ -75,14 +73,13 @@ export const useResponseActionsView = ({ }), [] ); - const responseActionsEnabled = useIsExperimentalFeatureEnabled('endpointResponseActionsEnabled'); const expandedEventFieldsObject = rawEventData ? (expandDottedObject((rawEventData as RawEventData).fields) as ExpandedEventFieldsObject) : undefined; const responseActions = expandedEventFieldsObject?.kibana?.alert?.rule?.parameters?.[0].response_actions; - const shouldEarlyReturn = !rawEventData || !responseActionsEnabled; + const shouldEarlyReturn = !rawEventData; const alertId = rawEventData?._id ?? ''; const [isLive, setIsLive] = useState(false); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.tsx index ebf6b1bf0930c..b555054a75e0c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/step_rule_actions/index.tsx @@ -18,7 +18,6 @@ import { UseArray } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import type { RuleObjectId } from '../../../../../common/api/detection_engine/model/rule_schema'; import { isQueryRule } from '../../../../../common/detection_engine/utils'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { ResponseActionsForm } from '../../../rule_response_actions/response_actions_form'; import type { RuleStepProps, @@ -85,8 +84,6 @@ const StepRuleActionsComponent: FC = ({ const { services: { application }, } = useKibana(); - const responseActionsEnabled = useIsExperimentalFeatureEnabled('responseActionsEnabled'); - const displayActionsOptions = useMemo( () => ( <> @@ -120,7 +117,7 @@ const StepRuleActionsComponent: FC = ({ {ruleId && } {displayActionsOptions} - {responseActionsEnabled && displayResponseActionsOptions} + {displayResponseActionsOptions} @@ -134,7 +131,6 @@ const StepRuleActionsComponent: FC = ({ application.capabilities.actions.show, displayActionsOptions, displayResponseActionsOptions, - responseActionsEnabled, ]); return ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/get_supported_response_actions.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/get_supported_response_actions.ts index 51b599028156d..95fc300a3fe57 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/get_supported_response_actions.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/get_supported_response_actions.ts @@ -24,12 +24,10 @@ interface EnabledFeatures { export const getSupportedResponseActions = ( actionTypes: ResponseActionType[], - enabledFeatures: EnabledFeatures, userPermissions: EnabledFeatures ): ResponseActionType[] => actionTypes.reduce((acc: ResponseActionType[], actionType) => { const isEndpointAction = actionType.id === ResponseActionTypesEnum['.endpoint']; - if (!enabledFeatures.endpoint && isEndpointAction) return acc; if (ResponseActionTypes.options.includes(actionType.id)) return [ ...acc, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/use_supported_response_action_types.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/use_supported_response_action_types.tsx index aed3d0302f05c..5d6f7a01bf076 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/use_supported_response_action_types.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/use_supported_response_action_types.tsx @@ -7,7 +7,6 @@ import { useEffect, useMemo, useState } from 'react'; import { useUserPrivileges } from '../../common/components/user_privileges'; -import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; import type { ResponseActionType } from './get_supported_response_actions'; import { getSupportedResponseActions, responseActionTypes } from './get_supported_response_actions'; @@ -16,15 +15,8 @@ export const useSupportedResponseActionTypes = () => { ResponseActionType[] | undefined >(); - const isEndpointEnabled = useIsExperimentalFeatureEnabled('endpointResponseActionsEnabled'); const { canIsolateHost, canKillProcess, canSuspendProcess } = useUserPrivileges().endpointPrivileges; - const enabledFeatures = useMemo( - () => ({ - endpoint: isEndpointEnabled, - }), - [isEndpointEnabled] - ); const userHasPermissionsToExecute = useMemo( () => ({ @@ -36,11 +28,10 @@ export const useSupportedResponseActionTypes = () => { useEffect(() => { const supportedTypes = getSupportedResponseActions( responseActionTypes, - enabledFeatures, userHasPermissionsToExecute ); setSupportedResponseActionTypes(supportedTypes); - }, [isEndpointEnabled, enabledFeatures, userHasPermissionsToExecute]); + }, [userHasPermissionsToExecute]); return supportedResponseActionTypes; }; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.test.tsx index e8be41c601844..9b11ccbb516ba 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.test.tsx @@ -12,7 +12,6 @@ import { DocumentDetailsContext } from '../../shared/context'; import { rawEventData, TestProviders } from '../../../../common/mock'; import { RESPONSE_DETAILS_TEST_ID } from './test_ids'; import { ResponseDetails } from './response_details'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; jest.mock('../../../../common/hooks/use_experimental_features'); jest.mock('../../../../common/lib/kibana', () => { @@ -98,19 +97,6 @@ const renderResponseDetails = (contextValue: DocumentDetailsContext) => ); describe('', () => { - let featureFlags: { endpointResponseActionsEnabled: boolean; responseActionsEnabled: boolean }; - - beforeEach(() => { - featureFlags = { endpointResponseActionsEnabled: true, responseActionsEnabled: true }; - - const useIsExperimentalFeatureEnabledMock = (feature: keyof typeof featureFlags) => - featureFlags[feature]; - - (useIsExperimentalFeatureEnabled as jest.Mock).mockImplementation( - useIsExperimentalFeatureEnabledMock - ); - }); - it('should render the view with response actions', () => { const wrapper = renderResponseDetails(contextWithResponseActions); @@ -120,17 +106,6 @@ describe('', () => { // TODO mock osquery results }); - it('should render the view with osquery only', () => { - featureFlags.responseActionsEnabled = true; - featureFlags.endpointResponseActionsEnabled = false; - - const wrapper = renderResponseDetails(contextWithResponseActions); - - expect(wrapper.getByTestId(RESPONSE_DETAILS_TEST_ID)).toBeInTheDocument(); - expect(wrapper.queryByTestId('responseActionsViewWrapper')).not.toBeInTheDocument(); - expect(wrapper.getByTestId('osqueryViewWrapper')).toBeInTheDocument(); - }); - it('should render the empty information', () => { const wrapper = renderResponseDetails(defaultContextValue); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.tsx index c240799639166..5081bdad9c17f 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/response_details.tsx @@ -11,8 +11,6 @@ import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n-react'; import { RESPONSE_DETAILS_TEST_ID } from './test_ids'; import { useDocumentDetailsContext } from '../../shared/context'; -import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; -import { useOsqueryTab } from '../../../../common/components/event_details/osquery_tab'; import { useResponseActionsView } from '../../../../common/components/event_details/response_actions_view'; const ExtendedFlyoutWrapper = styled.div` @@ -25,18 +23,11 @@ const ExtendedFlyoutWrapper = styled.div` */ export const ResponseDetails: React.FC = () => { const { searchHit, dataAsNestedObject, isPreview } = useDocumentDetailsContext(); - const endpointResponseActionsEnabled = useIsExperimentalFeatureEnabled( - 'endpointResponseActionsEnabled' - ); const responseActionsView = useResponseActionsView({ rawEventData: searchHit, ecsData: dataAsNestedObject, }); - const osqueryView = useOsqueryTab({ - rawEventData: searchHit, - ecsData: dataAsNestedObject, - }); return (
@@ -57,9 +48,7 @@ export const ResponseDetails: React.FC = () => { - - {endpointResponseActionsEnabled ? responseActionsView?.content : osqueryView?.content} - + {responseActionsView?.content} )}
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx index f403ba6f6aacd..b950c3f343e18 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/actions_log_filters.tsx @@ -55,9 +55,6 @@ export const ActionsLogFilters = memo( 'data-test-subj'?: string; }) => { const getTestId = useTestIdGenerator(dataTestSubj); - const responseActionsEnabled = useIsExperimentalFeatureEnabled( - 'endpointResponseActionsEnabled' - ); const isSentinelOneV1Enabled = useIsExperimentalFeatureEnabled( 'responseActionsSentinelOneV1Enabled' @@ -86,26 +83,24 @@ export const ActionsLogFilters = memo( onChangeFilterOptions={onChangeStatusesFilter} data-test-subj={dataTestSubj} /> - {isSentinelOneV1Enabled - ? responseActionsEnabled && ( - - ) - : responseActionsEnabled && ( - - )} + {isSentinelOneV1Enabled ? ( + + ) : ( + + )} ); }, [ @@ -116,7 +111,6 @@ export const ActionsLogFilters = memo( dataTestSubj, onChangeCommandsFilter, onChangeStatusesFilter, - responseActionsEnabled, onChangeAgentTypesFilter, onChangeTypeFilter, ]); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts index 1402518103e64..7441aec8c8fa5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts @@ -172,10 +172,6 @@ describe('Create rule route', () => { }); }); describe('rule containing response actions', () => { - beforeEach(() => { - // @ts-expect-error We're writting to a read only property just for the purpose of the test - clients.config.experimentalFeatures.endpointResponseActionsEnabled = true; - }); const getResponseAction = (command: string = 'isolate', config?: object) => ({ action_type_id: '.endpoint', params: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts index 80db9f68a853b..87f42a014c1d2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts @@ -179,10 +179,6 @@ describe('Update rule route', () => { }); }); describe('rule containing response actions', () => { - beforeEach(() => { - // @ts-expect-error We're writting to a read only property just for the purpose of the test - clients.config.experimentalFeatures.endpointResponseActionsEnabled = true; - }); const getResponseAction = (command: string = 'isolate', config?: object) => ({ action_type_id: '.endpoint', params: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts index dd77122ac4560..500db54acd867 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts @@ -64,9 +64,7 @@ export const validateResponseActionsPermissions = async ( ruleUpdate: RuleCreateProps | RuleUpdateProps, existingRule?: RuleAlertType | null ): Promise => { - const { experimentalFeatures } = await securitySolution.getConfig(); - - if (!experimentalFeatures.endpointResponseActionsEnabled || !isQueryRule(ruleUpdate.type)) { + if (!isQueryRule(ruleUpdate.type)) { return; } diff --git a/x-pack/test/defend_workflows_cypress/config.ts b/x-pack/test/defend_workflows_cypress/config.ts index 09c08fca6996c..a8502edcabe24 100644 --- a/x-pack/test/defend_workflows_cypress/config.ts +++ b/x-pack/test/defend_workflows_cypress/config.ts @@ -48,9 +48,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--xpack.fleet.agents.elasticsearch.host=http://${hostIp}:${kibanaCommonTestsConfig.get( 'servers.elasticsearch.port' )}`, - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'endpointResponseActionsEnabled', - ])}`, ], }, };