Skip to content

Commit

Permalink
Feature/remove asset criticality flag (elastic#196270)
Browse files Browse the repository at this point in the history
## Summary

It removes the asset criticality advanced setting, which enables the
feature by default for all users.

Deleted settings:
![Screenshot 2024-10-15 at 14 54
48](https://github.com/user-attachments/assets/103c3f04-fd7e-45cf-ac74-93e1eef341fa)

### How to test it?
* Start Kibana with security data
* Inside security solution / manage, you should be able to find the
Asset Criticality page
![Screenshot 2024-10-15 at 14 57
14](https://github.com/user-attachments/assets/7ddcee91-ad76-4d8f-b14a-bacc4ba31172)
* You should see the asset critically section when opening an entity
flyout (explore or host page) <img width="400"
src="https://github.com/user-attachments/assets/3a9ee545-566c-4687-af16-f31bd93bdc20"
/>
* The risk score should be updated if you update an entity's asset
criticality.



### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: machadoum <[email protected]>
Co-authored-by: jaredburgettelastic <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
4 people authored Oct 16, 2024
1 parent 267efdf commit 5ae7a61
Show file tree
Hide file tree
Showing 53 changed files with 106 additions and 528 deletions.
1 change: 0 additions & 1 deletion packages/serverless/settings/security_project/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ export const SECURITY_PROJECT_SETTINGS = [
settings.SECURITY_SOLUTION_NEWS_FEED_URL_ID,
settings.SECURITY_SOLUTION_ENABLE_NEWS_FEED_ID,
settings.SECURITY_SOLUTION_DEFAULT_ALERT_TAGS_KEY,
settings.SECURITY_SOLUTION_ENABLE_ASSET_CRITICALITY_SETTING,
];
3 changes: 0 additions & 3 deletions x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,6 @@ export const EXTENDED_RULE_EXECUTION_LOGGING_ENABLED_SETTING =
export const EXTENDED_RULE_EXECUTION_LOGGING_MIN_LEVEL_SETTING =
'securitySolution:extendedRuleExecutionLoggingMinLevel' as const;

/** This Kibana Advanced Setting allows users to enable/disable the Asset Criticality feature */
export const ENABLE_ASSET_CRITICALITY_SETTING = 'securitySolution:enableAssetCriticality' as const;

/** This Kibana Advanced Setting allows users to exclude selected data tiers from search during rule execution */
export const EXCLUDED_DATA_TIERS_FOR_RULE_EXECUTION =
'securitySolution:excludedDataTiersForRuleExecution' as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,6 @@ describe('useAssetCriticality', () => {

expect(mockFetchAssetCriticalityPrivileges).toHaveBeenCalled();
});

it('does not call privileges API when UI Settings is disabled', async () => {
mockUseHasSecurityCapability.mockReturnValue(true);
mockUseUiSettings.mockReturnValue([false]);

await renderQuery(() => useAssetCriticalityPrivileges('test_entity_name'), 'isSuccess');

expect(mockFetchAssetCriticalityPrivileges).not.toHaveBeenCalled();
});
});

describe('useAssetCriticalityData', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@

import type { UseMutationResult, UseQueryResult } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useUiSetting$ } from '@kbn/kibana-react-plugin/public';
import type { SecurityAppError } from '@kbn/securitysolution-t-grid';
import type { EntityAnalyticsPrivileges } from '../../../../common/api/entity_analytics';
import type { CriticalityLevelWithUnassigned } from '../../../../common/entity_analytics/asset_criticality/types';
import { ENABLE_ASSET_CRITICALITY_SETTING } from '../../../../common/constants';
import { useHasSecurityCapability } from '../../../helper_hooks';
import type { AssetCriticalityRecord } from '../../../../common/api/entity_analytics/asset_criticality';
import type { AssetCriticality, DeleteAssetCriticalityResponse } from '../../api/api';
Expand All @@ -34,12 +32,12 @@ export const useAssetCriticalityPrivileges = (
): UseQueryResult<EntityAnalyticsPrivileges, SecurityAppError> => {
const { fetchAssetCriticalityPrivileges } = useEntityAnalyticsRoutes();
const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics');
const [isAssetCriticalityEnabled] = useUiSetting$<boolean>(ENABLE_ASSET_CRITICALITY_SETTING);
const isEnabled = isAssetCriticalityEnabled && hasEntityAnalyticsCapability;

return useQuery({
queryKey: [ASSET_CRITICALITY_KEY, PRIVILEGES_KEY, queryKey, isEnabled],
queryFn: isEnabled ? fetchAssetCriticalityPrivileges : () => nonAuthorizedResponse,
queryKey: [ASSET_CRITICALITY_KEY, PRIVILEGES_KEY, queryKey, hasEntityAnalyticsCapability],
queryFn: hasEntityAnalyticsCapability
? fetchAssetCriticalityPrivileges
: () => nonAuthorizedResponse,
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { EuiSpacer, EuiInMemoryTable, EuiTitle, EuiCallOut } from '@elastic/eui'
import type { ReactNode } from 'react';
import React, { useMemo, useState } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { useUiSetting$ } from '@kbn/kibana-react-plugin/public';
import { ALERT_RULE_NAME } from '@kbn/rule-data-utils';

import { get } from 'lodash/fp';
Expand All @@ -24,7 +23,6 @@ import type {
UseRiskContributingAlertsResult,
} from '../../../../hooks/use_risk_contributing_alerts';
import { useRiskContributingAlerts } from '../../../../hooks/use_risk_contributing_alerts';
import { ENABLE_ASSET_CRITICALITY_SETTING } from '../../../../../../common/constants';
import { PreferenceFormattedDate } from '../../../../../common/components/formatted_date';

import { useRiskScore } from '../../../../api/hooks/use_risk_score';
Expand Down Expand Up @@ -177,8 +175,6 @@ export const RiskInputsTab = ({ entityType, entityName, scopeId }: RiskInputsTab
[isPreviewEnabled, scopeId]
);

const [isAssetCriticalityEnabled] = useUiSetting$<boolean>(ENABLE_ASSET_CRITICALITY_SETTING);

if (riskScoreError) {
return (
<EuiCallOut
Expand Down Expand Up @@ -229,9 +225,7 @@ export const RiskInputsTab = ({ entityType, entityName, scopeId }: RiskInputsTab

return (
<>
{isAssetCriticalityEnabled && (
<ContextsSection loading={loadingRiskScore} riskScore={riskScore} />
)}
<ContextsSection loading={loadingRiskScore} riskScore={riskScore} />
<EuiSpacer size="m" />
{riskInputsAlertSection}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ interface EntityData {
risk: RiskStats;
}

export const buildColumns: (showFooter: boolean) => Array<EuiBasicTableColumn<TableItem>> = (
showFooter
) => [
export const buildColumns: () => Array<EuiBasicTableColumn<TableItem>> = () => [
{
field: 'category',
name: (
Expand All @@ -38,12 +36,12 @@ export const buildColumns: (showFooter: boolean) => Array<EuiBasicTableColumn<Ta
truncateText: false,
mobileOptions: { show: true },
sortable: true,
footer: showFooter ? (
footer: (
<FormattedMessage
id="xpack.securitySolution.flyout.entityDetails.categoryColumnFooterLabel"
defaultMessage="Result"
/>
) : undefined,
),
},
{
field: 'score',
Expand All @@ -59,12 +57,11 @@ export const buildColumns: (showFooter: boolean) => Array<EuiBasicTableColumn<Ta
dataType: 'number',
align: 'right',
render: formatRiskScore,
footer: (props) =>
showFooter ? (
<span data-test-subj="risk-summary-result-score">
{formatRiskScore(sumBy((i) => i.score, props.items))}
</span>
) : undefined,
footer: (props) => (
<span data-test-subj="risk-summary-result-score">
{formatRiskScore(sumBy((i) => i.score, props.items))}
</span>
),
},
{
field: 'count',
Expand All @@ -79,19 +76,15 @@ export const buildColumns: (showFooter: boolean) => Array<EuiBasicTableColumn<Ta
sortable: true,
dataType: 'number',
align: 'right',
footer: (props) =>
showFooter ? (
<span data-test-subj="risk-summary-result-count">
{sumBy((i) => i.count ?? 0, props.items)}
</span>
) : undefined,
footer: (props) => (
<span data-test-subj="risk-summary-result-count">
{sumBy((i) => i.count ?? 0, props.items)}
</span>
),
},
];

export const getItems: (
entityData: EntityData | undefined,
isAssetCriticalityEnabled: boolean
) => TableItem[] = (entityData, isAssetCriticalityEnabled) => {
export const getItems: (entityData: EntityData | undefined) => TableItem[] = (entityData) => {
return [
{
category: i18n.translate('xpack.securitySolution.flyout.entityDetails.alertsGroupLabel', {
Expand All @@ -100,20 +93,17 @@ export const getItems: (
score: entityData?.risk.category_1_score ?? 0,
count: entityData?.risk.category_1_count ?? 0,
},
...(isAssetCriticalityEnabled
? [
{
category: i18n.translate(
'xpack.securitySolution.flyout.entityDetails.assetCriticalityGroupLabel',
{
defaultMessage: 'Asset Criticality',
}
),
score: entityData?.risk.category_2_score ?? 0,
count: undefined,
},
]
: []),

{
category: i18n.translate(
'xpack.securitySolution.flyout.entityDetails.assetCriticalityGroupLabel',
{
defaultMessage: 'Asset Criticality',
}
),
score: entityData?.risk.category_2_score ?? 0,
count: undefined,
},
];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,53 +27,12 @@ jest.mock('../../../common/components/visualization_actions/visualization_embedd
mockVisualizationEmbeddable(props),
}));

const mockUseUiSetting = jest.fn().mockReturnValue([false]);

jest.mock('@kbn/kibana-react-plugin/public', () => {
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
return {
...original,
useUiSetting$: () => mockUseUiSetting(),
};
});

describe('FlyoutRiskSummary', () => {
beforeEach(() => {
mockVisualizationEmbeddable.mockClear();
});

it('renders risk summary table with alerts only', () => {
const { getByTestId, queryByTestId } = render(
<TestProviders>
<FlyoutRiskSummary
riskScoreData={mockHostRiskScoreState}
queryId={'testQuery'}
openDetailsPanel={() => {}}
recalculatingScore={false}
/>
</TestProviders>
);

expect(getByTestId('risk-summary-table')).toBeInTheDocument();

// Alerts
expect(getByTestId('risk-summary-table')).toHaveTextContent(
`${mockHostRiskScoreState.data?.[0].host.risk.category_1_count}`
);

// Context
expect(getByTestId('risk-summary-table')).not.toHaveTextContent(
`${mockHostRiskScoreState.data?.[0].host.risk.category_2_count}`
);

// Result row doesn't exist if alerts are the only category
expect(queryByTestId('risk-summary-result-count')).not.toBeInTheDocument();
expect(queryByTestId('risk-summary-result-score')).not.toBeInTheDocument();
});

it('renders risk summary table with context and totals', () => {
mockUseUiSetting.mockReturnValue([true]);

const { getByTestId } = render(
<TestProviders>
<FlyoutRiskSummary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ import { euiThemeVars } from '@kbn/ui-theme';
import dateMath from '@kbn/datemath';
import { i18n } from '@kbn/i18n';
import { ExpandablePanel } from '@kbn/security-solution-common';
import { ENABLE_ASSET_CRITICALITY_SETTING } from '../../../../common/constants';
import { useKibana, useUiSetting$ } from '../../../common/lib/kibana/kibana_react';
import { useKibana } from '../../../common/lib/kibana/kibana_react';

import { EntityDetailsLeftPanelTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header';

Expand Down Expand Up @@ -82,17 +81,9 @@ const FlyoutRiskSummaryComponent = <T extends RiskScoreEntity>({

const xsFontSize = useEuiFontSize('xxs').fontSize;

const [isAssetCriticalityEnabled] = useUiSetting$<boolean>(ENABLE_ASSET_CRITICALITY_SETTING);
const columns = useMemo(() => buildColumns(), []);

const columns = useMemo(
() => buildColumns(isAssetCriticalityEnabled),
[isAssetCriticalityEnabled]
);

const rows = useMemo(
() => getItems(entityData, isAssetCriticalityEnabled),
[entityData, isAssetCriticalityEnabled]
);
const rows = useMemo(() => getItems(entityData), [entityData]);

const onToggle = useCallback(
(isOpen: boolean) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { useEntityEngineStatus } from '../components/entity_store/hooks/use_entity_engine_status';
import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features';
import { ASSET_CRITICALITY_INDEX_PATTERN } from '../../../common/entity_analytics/asset_criticality';
import { useUiSetting$, useKibana } from '../../common/lib/kibana';
import { ENABLE_ASSET_CRITICALITY_SETTING } from '../../../common/constants';
import { useKibana } from '../../common/lib/kibana';
import { AssetCriticalityFileUploader } from '../components/asset_criticality_file_uploader/asset_criticality_file_uploader';
import { useAssetCriticalityPrivileges } from '../components/asset_criticality/use_asset_criticality';
import { useHasSecurityCapability } from '../../helper_hooks';
Expand All @@ -50,7 +49,6 @@ const entityStoreInstallingStatuses = ['installing', 'loading'];
export const EntityStoreManagementPage = () => {
const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics');
const isEntityStoreFeatureFlagDisabled = useIsExperimentalFeatureEnabled('entityStoreDisabled');
const [isAssetCriticalityEnabled] = useUiSetting$<boolean>(ENABLE_ASSET_CRITICALITY_SETTING);
const {
data: assetCriticalityPrivileges,
error: assetCriticalityPrivilegesError,
Expand Down Expand Up @@ -110,10 +108,7 @@ export const EntityStoreManagementPage = () => {
const errorMessage = assetCriticalityPrivilegesError?.body.message ?? (
<FormattedMessage
id="xpack.securitySolution.entityAnalytics.assetCriticalityUploadPage.advancedSettingDisabledMessage"
defaultMessage='Please enable "{ENABLE_ASSET_CRITICALITY_SETTING}" in advanced settings to access this functionality.'
values={{
ENABLE_ASSET_CRITICALITY_SETTING,
}}
defaultMessage="The don't have privileges to access Asset Criticality feature. Contact your administrator for further assistance."
/>
);

Expand Down Expand Up @@ -218,7 +213,6 @@ export const EntityStoreManagementPage = () => {
const FileUploadSection: React.FC = () => {
if (
!hasEntityAnalyticsCapability ||
!isAssetCriticalityEnabled ||
assetCriticalityPrivilegesError?.body.status_code === 403
) {
return <AssetCriticalityIssueCallout />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ import { ENTITY_RISK_LEVEL } from '../../../../entity_analytics/components/risk_

export const getHostsColumns = (
showRiskColumn: boolean,
dispatchSeverityUpdate: (s: RiskSeverity) => void,
isAssetCriticalityEnabled: boolean
dispatchSeverityUpdate: (s: RiskSeverity) => void
): HostsTableColumns => {
const columns: HostsTableColumns = [
{
Expand Down Expand Up @@ -166,24 +165,22 @@ export const getHostsColumns = (
});
}

if (isAssetCriticalityEnabled) {
columns.push({
field: 'node.criticality',
name: i18n.ASSET_CRITICALITY,
truncateText: false,
mobileOptions: { show: true },
sortable: false,
render: (assetCriticality: CriticalityLevelWithUnassigned) => {
if (!assetCriticality) return getEmptyTagValue();
return (
<AssetCriticalityBadge
criticalityLevel={assetCriticality}
css={{ verticalAlign: 'middle' }}
/>
);
},
});
}
columns.push({
field: 'node.criticality',
name: i18n.ASSET_CRITICALITY,
truncateText: false,
mobileOptions: { show: true },
sortable: false,
render: (assetCriticality: CriticalityLevelWithUnassigned) => {
if (!assetCriticality) return getEmptyTagValue();
return (
<AssetCriticalityBadge
criticalityLevel={assetCriticality}
css={{ verticalAlign: 'middle' }}
/>
);
},
});

return columns;
};
Loading

0 comments on commit 5ae7a61

Please sign in to comment.