diff --git a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index 1afa24ebbd529..11d0aa22a17a5 100644 --- a/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -182,7 +182,6 @@ export class EndpointAppContextService { this.setupDependencies.securitySolutionRequestContextFactory, alerting, licenseService, - exceptionListsClient, this.setupDependencies.cloud, productFeaturesService ) diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 09a82212d9284..0300bd72246b7 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -187,7 +187,6 @@ describe('Fleet integrations', () => { requestContextFactoryMock.create(), endpointAppContextStartContract.alerting, licenseService, - exceptionListClient, cloudService, productFeaturesService ); diff --git a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts index 54f1ce8cc7e01..1b44a1252010e 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.ts @@ -46,7 +46,6 @@ import type { NewPolicyData, PolicyConfig } from '../../common/endpoint/types'; import type { LicenseService } from '../../common/license'; import type { ManifestManager } from '../endpoint/services'; import type { IRequestContextFactory } from '../request_context_factory'; -import { installPrepackagedRules } from './handlers/install_prepackaged_rules'; import { createPolicyArtifactManifest } from './handlers/create_policy_artifact_manifest'; import { createDefaultPolicy } from './handlers/create_default_policy'; import { validatePolicyAgainstLicense } from './handlers/validate_policy_against_license'; @@ -60,6 +59,7 @@ import { ENDPOINT_INTEGRATION_CONFIG_KEY } from './constants'; import { createEventFilters } from './handlers/create_event_filters'; import type { ProductFeaturesService } from '../lib/product_features_service/product_features_service'; import { removeProtectionUpdatesNote } from './handlers/remove_protection_updates_note'; +import { installEndpointSecurityPrebuiltRule } from '../lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule'; const isEndpointPackagePolicy = ( packagePolicy: T @@ -121,7 +121,6 @@ export const getPackagePolicyCreateCallback = ( securitySolutionRequestContextFactory: IRequestContextFactory, alerts: AlertsStartContract, licenseService: LicenseService, - exceptionsClient: ExceptionListClient | undefined, cloud: CloudSetup, productFeatures: ProductFeaturesService ): PostPackagePolicyCreateCallback => { @@ -174,15 +173,13 @@ export const getPackagePolicyCreateCallback = ( // perform these operations in parallel in order to help in not delaying the API response too much const [, manifestValue] = await Promise.all([ - // Install Detection Engine prepackaged rules - exceptionsClient && - installPrepackagedRules({ - logger, - context: securitySolutionContext, - request, - alerts, - exceptionsClient, - }), + installEndpointSecurityPrebuiltRule({ + logger, + context: securitySolutionContext, + request, + alerts, + soClient, + }), // create the Artifact Manifest for this policy createPolicyArtifactManifest(logger, manifestManager), diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts deleted file mode 100644 index d4a60be85d3ea..0000000000000 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts +++ /dev/null @@ -1,58 +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 { KibanaRequest, Logger } from '@kbn/core/server'; -import type { ExceptionListClient } from '@kbn/lists-plugin/server'; -import type { PluginStartContract as AlertsStartContract } from '@kbn/alerting-plugin/server'; -import { createDetectionIndex } from '../../lib/detection_engine/routes/index/create_index_route'; -import { createPrepackagedRules } from '../../lib/detection_engine/prebuilt_rules'; -import type { SecuritySolutionApiRequestHandlerContext } from '../../types'; - -export interface InstallPrepackagedRulesProps { - logger: Logger; - context: SecuritySolutionApiRequestHandlerContext; - request: KibanaRequest; - alerts: AlertsStartContract; - exceptionsClient: ExceptionListClient; -} - -/** - * As part of a user taking advantage of Endpoint Security from within fleet, we attempt to install - * the pre-packaged rules from the detection engine, which includes an Endpoint Rule enabled by default - */ -export const installPrepackagedRules = async ({ - logger, - context, - request, - alerts, - exceptionsClient, -}: InstallPrepackagedRulesProps): Promise => { - // Create detection index & rules (if necessary). move past any failure, this is just a convenience - try { - await createDetectionIndex(context); - } catch (err) { - if (err.statusCode !== 409) { - // 409 -> detection index already exists, which is fine - logger.warn( - `Possible problem creating detection signals index (${err.statusCode}): ${err.message}` - ); - } - } - try { - // this checks to make sure index exists first, safe to try in case of failure above - // may be able to recover from minor errors - await createPrepackagedRules( - context, - alerts.getRulesClientWithRequest(request), - exceptionsClient - ); - } catch (err) { - logger.error( - `Unable to create detection rules automatically (${err.statusCode}): ${err.message}` - ); - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule.ts new file mode 100644 index 0000000000000..576247f1fd372 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule.ts @@ -0,0 +1,84 @@ +/* + * 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 { KibanaRequest, Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import type { PluginStartContract as AlertsStartContract } from '@kbn/alerting-plugin/server'; +import { createDetectionIndex } from '../../../routes/index/create_index_route'; +import type { SecuritySolutionApiRequestHandlerContext } from '../../../../../types'; +import { ELASTIC_SECURITY_RULE_ID } from '../../../../../../common'; +import { createPrebuiltRuleObjectsClient } from '../rule_objects/prebuilt_rule_objects_client'; +import { createPrebuiltRuleAssetsClient } from '../rule_assets/prebuilt_rule_assets_client'; +import { createPrebuiltRules } from '../rule_objects/create_prebuilt_rules'; + +export interface InstallEndpointSecurityPrebuiltRuleProps { + logger: Logger; + context: SecuritySolutionApiRequestHandlerContext; + request: KibanaRequest; + alerts: AlertsStartContract; + soClient: SavedObjectsClientContract; +} + +/** + * As part of a user taking advantage of the Elastic Defend (formerly Endpoint + * Security) integration from within fleet, we attempt to install the `Endpoint + * Security (Elastic Defend)` prebuilt rule which will be enabled by default. + */ +export const installEndpointSecurityPrebuiltRule = async ({ + logger, + context, + request, + alerts, + soClient, +}: InstallEndpointSecurityPrebuiltRuleProps): Promise => { + // Create detection index & rules (if necessary). move past any failure, this is just a convenience + try { + await createDetectionIndex(context); + } catch (err) { + if (err.statusCode !== 409) { + // 409 -> detection index already exists, which is fine + logger.warn( + `Possible problem creating detection signals index (${err.statusCode}): ${err.message}` + ); + } + } + try { + const rulesClient = await alerts.getRulesClientWithRequest(request); + const detectionRulesClient = context.getDetectionRulesClient(); + const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient); + const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient); + const exceptionsListClient = context.getExceptionListClient(); + + const elasticDefendRule = await ruleObjectsClient.fetchInstalledRulesByIds([ + ELASTIC_SECURITY_RULE_ID, + ]); + if (elasticDefendRule.length > 0) { + // Elastic Defend rule already installed + return; + } + // Elastic Defend rule not installed, find the latest version in the + // prebuilt rule assets and install it + + // This will create the endpoint list if it does not exist yet + await exceptionsListClient?.createEndpointList(); + + const latestRuleVersion = await ruleAssetsClient.fetchLatestVersions([ + ELASTIC_SECURITY_RULE_ID, + ]); + if (latestRuleVersion.length === 0) { + logger.error( + `Unable to find Elastic Defend rule in the prebuilt rule assets (rule_id: ${ELASTIC_SECURITY_RULE_ID})` + ); + return; + } + const ruleAssetsToInstall = await ruleAssetsClient.fetchAssetsByVersion(latestRuleVersion); + await createPrebuiltRules(detectionRulesClient, ruleAssetsToInstall); + } catch (err) { + logger.error( + `Unable to create Endpoint Security rule automatically (${err.statusCode}): ${err.message}` + ); + } +};