Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions x-pack/solutions/security/packages/features/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/
export * from './src/actions';
1 change: 1 addition & 0 deletions x-pack/solutions/security/packages/features/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ export { assistantDefaultProductFeaturesConfig } from './src/assistant/product_f
export { attackDiscoveryDefaultProductFeaturesConfig } from './src/attack_discovery/product_feature_config';
export { timelineDefaultProductFeaturesConfig } from './src/timeline/product_feature_config';
export { notesDefaultProductFeaturesConfig } from './src/notes/product_feature_config';
export { siemMigrationsDefaultProductFeaturesConfig } from './src/siem_migrations/product_feature_config';

export { createEnabledProductFeaturesConfigMap } from './src/helpers';
7 changes: 7 additions & 0 deletions x-pack/solutions/security/packages/features/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/
export * from './src/constants';
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { getAssistantFeature } from './src/assistant';
export { getAttackDiscoveryFeature } from './src/attack_discovery';
export { getTimelineFeature } from './src/timeline';
export { getNotesFeature } from './src/notes';
export { getSiemMigrationsFeature } from './src/siem_migrations';
14 changes: 14 additions & 0 deletions x-pack/solutions/security/packages/features/src/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 { APP_ID } from './constants';

// The prefix ("securitySolution-") must be used by all the Security Solution API action privileges.
// This ensures product features are honored by the Kibana routes security authz.
export const API_ACTION_PREFIX = `${APP_ID}-`;

export const SIEM_MIGRATIONS_API_ACTION_ALL = `${API_ACTION_PREFIX}siemMigrationsAll`;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getAssistantBaseKibanaFeature = (): BaseKibanaFeatureConfig => ({
defaultMessage: 'Elastic AI Assistant',
}
),
order: 1100,
order: 1300,
category: DEFAULT_APP_CATEGORIES.security,
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
app: [ASSISTANT_FEATURE_ID, 'kibana'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getAttackDiscoveryBaseKibanaFeature = (): BaseKibanaFeatureConfig =
defaultMessage: 'Attack discovery',
}
),
order: 1100,
order: 1400,
category: DEFAULT_APP_CATEGORIES.security,
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
app: [ATTACK_DISCOVERY_FEATURE_ID, 'kibana'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const getCasesBaseKibanaFeature = ({
defaultMessage: 'Cases (Deprecated)',
}
),
order: 1100,
order: 1200,
category: DEFAULT_APP_CATEGORIES.security,
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
app: [CASES_FEATURE_ID, 'kibana'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const getCasesBaseKibanaFeatureV2 = ({
defaultMessage: 'Cases',
}
),
order: 1100,
order: 1200,
category: DEFAULT_APP_CATEGORIES.security,
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
app: [CASES_FEATURE_ID, 'kibana'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const ASSISTANT_FEATURE_ID = 'securitySolutionAssistant' as const;
export const ATTACK_DISCOVERY_FEATURE_ID = 'securitySolutionAttackDiscovery' as const;
export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const;
export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const;
export const SIEM_MIGRATIONS_FEATURE_ID = 'securitySolutionSiemMigrations' as const;

// Same as the plugin id defined by Cloud Security Posture
export const CLOUD_POSTURE_APP_ID = 'csp' as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,20 @@ export enum ProductFeatureNotesFeatureKey {
*/
notes = 'notes',
}
export enum ProductFeatureSiemMigrationsKey {
/**
* Enables the SIEM Migrations main feature
*/
siemMigrations = 'siem_migrations',
}

// Merges the two enums.
export const ProductFeatureKey = {
...ProductFeatureSecurityKey,
...ProductFeatureCasesKey,
...ProductFeatureAssistantKey,
...ProductFeatureAttackDiscoveryKey,
...ProductFeatureSiemMigrationsKey,
...ProductFeatureTimelineFeatureKey,
...ProductFeatureNotesFeatureKey,
};
Expand All @@ -148,6 +155,7 @@ export type ProductFeatureKeyType =
| ProductFeatureCasesKey
| ProductFeatureAssistantKey
| ProductFeatureAttackDiscoveryKey
| ProductFeatureSiemMigrationsKey
| ProductFeatureTimelineFeatureKey
| ProductFeatureNotesFeatureKey;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 { getSiemMigrationsBaseKibanaFeature } from './kibana_features';
import type { ProductFeatureParams } from '../types';

export const getSiemMigrationsFeature = (): ProductFeatureParams => ({
baseKibanaFeature: getSiemMigrationsBaseKibanaFeature(),
baseKibanaSubFeatureIds: [],
subFeaturesMap: new Map(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common';
import { i18n } from '@kbn/i18n';
import { KibanaFeatureScope } from '@kbn/features-plugin/common';

import { APP_ID, SIEM_MIGRATIONS_FEATURE_ID } from '../constants';
import { type BaseKibanaFeatureConfig } from '../types';

export const getSiemMigrationsBaseKibanaFeature = (): BaseKibanaFeatureConfig => ({
id: SIEM_MIGRATIONS_FEATURE_ID,
name: i18n.translate(
'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionSiemMigrationsTitle',
{
defaultMessage: 'SIEM migrations',
}
),
order: 1500,
category: DEFAULT_APP_CATEGORIES.security,
scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security],
app: [SIEM_MIGRATIONS_FEATURE_ID, 'kibana'],
catalogue: [APP_ID],
minimumLicense: 'enterprise',
privileges: {
all: {
api: [],
app: [SIEM_MIGRATIONS_FEATURE_ID, 'kibana'],
catalogue: [APP_ID],
savedObject: {
all: [],
read: [],
},
ui: [],
},
read: {
// No read-only mode currently supported
disabled: true,
savedObject: {
all: [],
read: [],
},
ui: [],
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 { SIEM_MIGRATIONS_API_ACTION_ALL } from '../actions';
import { ProductFeatureSiemMigrationsKey } from '../product_features_keys';
import type { ProductFeatureKibanaConfig } from '../types';

/**
* App features privileges configuration for the Attack discovery feature.
* These are the configs that are shared between both offering types (ess and serverless).
* They can be extended on each offering plugin to register privileges using different way on each offering type.
*
* Privileges can be added in different ways:
* - `privileges`: the privileges that will be added directly into the main Security feature.
* - `subFeatureIds`: the ids of the sub-features that will be added into the Security subFeatures entry.
* - `subFeaturesPrivileges`: the privileges that will be added into the existing Security subFeature with the privilege `id` specified.
*/
export const siemMigrationsDefaultProductFeaturesConfig: Record<
ProductFeatureSiemMigrationsKey,
ProductFeatureKibanaConfig
> = {
[ProductFeatureSiemMigrationsKey.siemMigrations]: {
privileges: {
all: {
api: [SIEM_MIGRATIONS_API_ACTION_ALL],
ui: ['all'],
},
},
},
};
16 changes: 16 additions & 0 deletions x-pack/solutions/security/packages/features/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
AssistantSubFeatureId,
CasesSubFeatureId,
SecuritySubFeatureId,
ProductFeatureSiemMigrationsKey,
ProductFeatureTimelineFeatureKey,
ProductFeatureNotesFeatureKey,
} from './product_features_keys';
Expand Down Expand Up @@ -69,10 +70,25 @@ export type ProductFeaturesNotesConfig = Map<
ProductFeatureKibanaConfig
>;

export type ProductFeaturesSiemMigrationsConfig = Map<
ProductFeatureSiemMigrationsKey,
ProductFeatureKibanaConfig
>;

export type AppSubFeaturesMap<T extends string = string> = Map<T, SubFeatureConfig>;

export interface ProductFeatureParams<T extends string = string> {
baseKibanaFeature: BaseKibanaFeatureConfig;
baseKibanaSubFeatureIds: T[];
subFeaturesMap: AppSubFeaturesMap<T>;
}

export interface ProductFeaturesConfigurator {
security: () => ProductFeaturesConfig<SecuritySubFeatureId>;
cases: () => ProductFeaturesConfig<CasesSubFeatureId>;
securityAssistant: () => ProductFeaturesConfig<AssistantSubFeatureId>;
attackDiscovery: () => ProductFeaturesConfig;
timeline: () => ProductFeaturesConfig;
notes: () => ProductFeaturesConfig;
siemMigrations: () => ProductFeaturesConfig;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { SolutionSideNavPanel, type SolutionSideNavPanelProps } from './solution_side_nav_panel';
import { BETA_LABEL } from './beta_badge';
import { TELEMETRY_EVENT } from './telemetry/const';
import { METRIC_TYPE } from '@kbn/analytics';
import { TelemetryContextProvider } from './telemetry/telemetry_context';
Expand Down Expand Up @@ -48,8 +47,6 @@ const mockItems: SolutionSideNavItem[] = [
},
];

const betaMockItemsCount = mockItems.filter((item) => item.isBeta).length;

const mockCategories: LinkCategories = [
{
label: 'HOSTS CATEGORY',
Expand Down Expand Up @@ -98,7 +95,6 @@ describe('SolutionSideNavPanel', () => {
mockItems.forEach((item) => {
expect(result.getByText(item.label)).toBeInTheDocument();
});
expect(result.queryAllByText(BETA_LABEL).length).toBe(betaMockItemsCount);
});

it('should only render categories with items', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import {
type SeparatorLinkCategory,
} from '@kbn/security-solution-navigation';
import type { SolutionSideNavItem } from './types';
import { BetaBadge } from './beta_badge';
import { TELEMETRY_EVENT } from './telemetry/const';
import { useTelemetryContext } from './telemetry/telemetry_context';
import {
Expand Down Expand Up @@ -388,12 +387,11 @@ const SolutionSideNavPanelItem: React.FC<SolutionSideNavPanelItemProps> = React.
* Renders the navigation item label
**/
const ItemLabel: React.FC<{ item: SolutionSideNavItem }> = React.memo(function ItemLabel({
item: { label, openInNewTab, isBeta, betaOptions },
item: { label, openInNewTab },
}) {
return (
<>
{label} {openInNewTab && <EuiIcon type="popout" size="s" />}
{isBeta && <BetaBadge text={betaOptions?.text} />}
</>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ import type {
GetRuleMigrationIntegrationsResponse,
GetRuleMigrationPrebuiltRulesRequestParamsInput,
GetRuleMigrationPrebuiltRulesResponse,
GetRuleMigrationPrivilegesResponse,
GetRuleMigrationResourcesRequestQueryInput,
GetRuleMigrationResourcesRequestParamsInput,
GetRuleMigrationResourcesResponse,
Expand All @@ -391,6 +392,7 @@ import type {
StartRuleMigrationResponse,
StopRuleMigrationRequestParamsInput,
StopRuleMigrationResponse,
UpdateRuleMigrationRequestParamsInput,
UpdateRuleMigrationRequestBodyInput,
UpdateRuleMigrationResponse,
UpsertRuleMigrationResourcesRequestParamsInput,
Expand Down Expand Up @@ -1491,6 +1493,21 @@ finalize it.
})
.catch(catchAxiosErrorFormatAndThrow);
}
/**
* Identifies the privileges required for a SIEM rules migration and returns the missing privileges
*/
async getRuleMigrationPrivileges() {
this.log.info(`${new Date().toISOString()} Calling API GetRuleMigrationPrivileges`);
return this.kbnClient
.request<GetRuleMigrationPrivilegesResponse>({
path: '/internal/siem_migrations/rules/missing_privileges',
headers: {
[ELASTIC_HTTP_VERSION_HEADER]: '1',
},
method: 'GET',
})
.catch(catchAxiosErrorFormatAndThrow);
}
/**
* Retrieves resources for an existing SIEM rules migration
*/
Expand Down Expand Up @@ -2251,7 +2268,7 @@ detection engine rules.
this.log.info(`${new Date().toISOString()} Calling API UpdateRuleMigration`);
return this.kbnClient
.request<UpdateRuleMigrationResponse>({
path: '/internal/siem_migrations/rules',
path: replaceParams('/internal/siem_migrations/rules/{migration_id}', props.params),
headers: {
[ELASTIC_HTTP_VERSION_HEADER]: '1',
},
Expand Down Expand Up @@ -2600,6 +2617,7 @@ export interface UpdateRuleProps {
body: UpdateRuleRequestBodyInput;
}
export interface UpdateRuleMigrationProps {
params: UpdateRuleMigrationRequestParamsInput;
body: UpdateRuleMigrationRequestBodyInput;
}
export interface UpdateWorkflowInsightProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export const SIEM_RULE_MIGRATION_RESOURCES_PATH = `${SIEM_RULE_MIGRATION_PATH}/r
export const SIEM_RULE_MIGRATION_RESOURCES_MISSING_PATH =
`${SIEM_RULE_MIGRATION_RESOURCES_PATH}/missing` as const;

export const SIEM_RULE_MIGRATION_MISSING_PRIVILEGES_PATH =
`${SIEM_RULE_MIGRATIONS_PATH}/missing_privileges` as const;

export const LOOKUPS_INDEX_PREFIX = 'lookup_';

export enum SiemMigrationTaskStatus {
READY = 'ready',
RUNNING = 'running',
Expand Down
Loading