diff --git a/x-pack/solutions/security/plugins/security_solution/public/mocks.ts b/x-pack/solutions/security/plugins/security_solution/public/mocks.ts index 8e16b883f474b..b45d0eb1316b8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/mocks.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/mocks.ts @@ -24,7 +24,8 @@ export const contractStartServicesMock: ContractStartServices = { const setupMock = (): PluginSetup => ({ resolver: jest.fn(), - experimentalFeatures: allowedExperimentalValues, // default values + experimentalFeatures: allowedExperimentalValues, // default values, + setProductFeatureKeys: jest.fn(), }); const startMock = (): PluginStart => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/plugin.tsx b/x-pack/solutions/security/plugins/security_solution/public/plugin.tsx index 2dfef2a01e978..2da2fa8a8c347 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/plugin.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/plugin.tsx @@ -24,6 +24,7 @@ import type { SecuritySolutionAppWrapperFeature, SecuritySolutionCellRendererFeature, } from '@kbn/discover-shared-plugin/public/services/discover_features'; +import { ProductFeatureAssistantKey } from '@kbn/security-solution-features/src/product_features_keys'; import { getLazyCloudSecurityPosturePliAuthBlockExtension } from './cloud_security_posture/lazy_cloud_security_posture_pli_auth_block_extension'; import { getLazyEndpointAgentTamperProtectionExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_agent_tamper_protection_extension'; import type { @@ -99,6 +100,7 @@ export class Plugin implements IPlugin { @@ -202,6 +204,25 @@ export class Plugin implements IPlugin { + if (!productFeatureKeys || !license) { + return; + } + + const isAssistantAvailable = + productFeatureKeys?.has(ProductFeatureAssistantKey.assistant) && + license?.hasAtLeast('enterprise'); + const assistantManagementApp = management?.sections.section.kibana.getApp( + 'securityAiAssistantManagement' + ); + + if (!isAssistantAvailable) { + assistantManagementApp?.disable(); + } + }); + cases?.attachmentFramework.registerExternalReference( getExternalReferenceAttachmentEndpointRegular() ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/plugin_contract.ts b/x-pack/solutions/security/plugins/security_solution/public/plugin_contract.ts index d9b79a06c1e8a..0f526070f26f7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/plugin_contract.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/plugin_contract.ts @@ -4,10 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { BehaviorSubject } from 'rxjs'; import { UpsellingService } from '@kbn/security-solution-upselling/service'; import type { CoreStart } from '@kbn/core/public'; +import type { + ProductFeatureKeyType, + ProductFeatureKeys, +} from '@kbn/security-solution-features/src/types'; import type { ContractStartServices, PluginSetup, PluginStart } from './types'; import type { ExperimentalFeatures } from '../common/experimental_features'; import { navLinks$, updateNavLinks } from './common/links/nav_links'; @@ -20,18 +23,23 @@ export class PluginContract { public upsellingService: UpsellingService; public onboardingService: OnboardingService; public isSolutionNavigationEnabled$: BehaviorSubject; + public productFeatureKeys$: BehaviorSubject | null>; constructor(private readonly experimentalFeatures: ExperimentalFeatures) { this.onboardingService = new OnboardingService(); this.componentsService = new ContractComponentsService(); this.upsellingService = new UpsellingService(); this.isSolutionNavigationEnabled$ = new BehaviorSubject(false); // defaults to classic navigation + this.productFeatureKeys$ = new BehaviorSubject | null>(null); } public getSetupContract(): PluginSetup { return { resolver: lazyResolver, experimentalFeatures: { ...this.experimentalFeatures }, + setProductFeatureKeys: (productFeatureKeys: ProductFeatureKeys) => { + this.productFeatureKeys$.next(new Set(productFeatureKeys)); + }, }; } diff --git a/x-pack/solutions/security/plugins/security_solution/public/types.ts b/x-pack/solutions/security/plugins/security_solution/public/types.ts index 57dd3b34edcbf..47fb76cec1796 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/types.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/types.ts @@ -62,6 +62,7 @@ import type { MapsStartApi } from '@kbn/maps-plugin/public'; import type { ServerlessPluginStart } from '@kbn/serverless/public'; import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import type { AutomaticImportPluginStart } from '@kbn/automatic-import-plugin/public'; +import type { ProductFeatureKeys } from '@kbn/security-solution-features'; import type { ResolverPluginSetup } from './resolver/types'; import type { Inspect } from '../common/search_strategy'; import type { Detections } from './detections'; @@ -213,6 +214,7 @@ export type StartRenderServices = Pick< export interface PluginSetup { resolver: () => Promise; experimentalFeatures: ExperimentalFeatures; + setProductFeatureKeys: (productFeatureKeys: ProductFeatureKeys) => void; } export interface PluginStart { diff --git a/x-pack/solutions/security/plugins/security_solution_ess/server/constants.ts b/x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts similarity index 100% rename from x-pack/solutions/security/plugins/security_solution_ess/server/constants.ts rename to x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts diff --git a/x-pack/solutions/security/plugins/security_solution_ess/public/plugin.ts b/x-pack/solutions/security/plugins/security_solution_ess/public/plugin.ts index 9cd5e77e5a4e4..faa6d40121605 100644 --- a/x-pack/solutions/security/plugins/security_solution_ess/public/plugin.ts +++ b/x-pack/solutions/security/plugins/security_solution_ess/public/plugin.ts @@ -16,6 +16,7 @@ import type { SecuritySolutionEssPluginStartDeps, } from './types'; import { setOnboardingSettings } from './onboarding'; +import { DEFAULT_PRODUCT_FEATURES } from '../common/constants'; export class SecuritySolutionEssPlugin implements @@ -28,8 +29,12 @@ export class SecuritySolutionEssPlugin { public setup( _core: CoreSetup, - _setupDeps: SecuritySolutionEssPluginSetupDeps + setupDeps: SecuritySolutionEssPluginSetupDeps ): SecuritySolutionEssPluginSetup { + const { securitySolution } = setupDeps; + + securitySolution.setProductFeatureKeys(DEFAULT_PRODUCT_FEATURES); + return {}; } diff --git a/x-pack/solutions/security/plugins/security_solution_ess/server/plugin.ts b/x-pack/solutions/security/plugins/security_solution_ess/server/plugin.ts index de4081f60ac49..6c0edcf40dbaf 100644 --- a/x-pack/solutions/security/plugins/security_solution_ess/server/plugin.ts +++ b/x-pack/solutions/security/plugins/security_solution_ess/server/plugin.ts @@ -7,7 +7,7 @@ import type { Plugin, CoreSetup } from '@kbn/core/server'; import { getProductProductFeaturesConfigurator } from './product_features'; -import { DEFAULT_PRODUCT_FEATURES } from './constants'; +import { DEFAULT_PRODUCT_FEATURES } from '../common/constants'; import type { SecuritySolutionEssPluginSetup, diff --git a/x-pack/solutions/security/plugins/security_solution_serverless/public/plugin.ts b/x-pack/solutions/security/plugins/security_solution_serverless/public/plugin.ts index a9743ef4fa51f..c65949a19efe2 100644 --- a/x-pack/solutions/security/plugins/security_solution_serverless/public/plugin.ts +++ b/x-pack/solutions/security/plugins/security_solution_serverless/public/plugin.ts @@ -24,6 +24,7 @@ import { } from '../common/experimental_features'; import { setOnboardingSettings } from './onboarding'; import { getAdditionalChargesMessage } from './components/additional_charges_message'; +import { getProductProductFeatures } from '../common/pli/pli_features'; export class SecuritySolutionServerlessPlugin implements @@ -47,12 +48,14 @@ export class SecuritySolutionServerlessPlugin setupDeps: SecuritySolutionServerlessPluginSetupDeps ): SecuritySolutionServerlessPluginSetup { const { securitySolution } = setupDeps; + const { productTypes } = this.config; this.experimentalFeatures = parseExperimentalConfigValue( this.config.enableExperimental, securitySolution.experimentalFeatures ).features; + securitySolution.setProductFeatureKeys(getProductProductFeatures(productTypes)); return {}; }