diff --git a/x-pack/solutions/security/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts b/x-pack/solutions/security/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts index ddebefd0bddc0..cada2fb7d498a 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts @@ -188,7 +188,6 @@ export class EndpointAppContextService { this.setupDependencies.securitySolutionRequestContextFactory, alerting, licenseService, - exceptionListsClient, this.setupDependencies.cloud, productFeaturesService, telemetryConfigProvider diff --git a/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts b/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts index 496056f6878d6..904df8fad5786 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts @@ -191,7 +191,6 @@ describe('Fleet integrations', () => { requestContextFactoryMock.create(), endpointAppContextStartContract.alerting, licenseService, - exceptionListClient, cloudService, productFeaturesService, telemetryConfigProviderMock diff --git a/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.ts b/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.ts index 307b7147f2cb5..88fa30b959791 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/fleet_integration.ts @@ -47,7 +47,7 @@ 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 { installEndpointSecurityPrebuiltRule } from '../lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule'; import { createPolicyArtifactManifest } from './handlers/create_policy_artifact_manifest'; import { createDefaultPolicy } from './handlers/create_default_policy'; import { validatePolicyAgainstLicense } from './handlers/validate_policy_against_license'; @@ -122,7 +122,6 @@ export const getPackagePolicyCreateCallback = ( securitySolutionRequestContextFactory: IRequestContextFactory, alerts: AlertingServerStart, licenseService: LicenseService, - exceptionsClient: ExceptionListClient | undefined, cloud: CloudSetup, productFeatures: ProductFeaturesService, telemetryConfigProvider: TelemetryConfigProvider @@ -176,15 +175,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/solutions/security/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts b/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts deleted file mode 100644 index 891face9f2879..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts +++ /dev/null @@ -1,55 +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 { AlertingServerStart } 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: AlertingServerStart; - 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 - const rulesClient = await alerts.getRulesClientWithRequest(request); - await createPrepackagedRules(context, rulesClient, exceptionsClient); - } catch (err) { - logger.error( - `Unable to create detection rules automatically (${err.statusCode}): ${err.message}` - ); - } -}; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rules_package/install_endpoint_security_prebuilt_rule.ts new file mode 100644 index 0000000000000..ad34630fca19c --- /dev/null +++ b/x-pack/solutions/security/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 { AlertingServerStart } 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: AlertingServerStart; + 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({ + ruleIds: [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}` + ); + } +};