mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.18] [Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations (#214506) (#214616)
# Backport This will backport the following commits from `main` to `8.18`: - [[Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations (#214506)](https://github.com/elastic/kibana/pull/214506) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Andrew Macri","email":"andrew.macri@elastic.co"},"sourceCommit":{"committedDate":"2025-03-14T16:41:40Z","message":"[Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations (#214506)\n\n## [Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations\n\nThis PR detects invalid Anonymization configurations when generating Attack discoveries.\n\nIt displays an error message when:\n\n- The Security AI Anonymization settings are configured to not allow _any_ fields, as reported in <https://github.com/elastic/kibana/issues/214310>\n- The Security AI Anonymization settings are configured to not allow the `_id` field, as reported by @aarju\n\n### Out of scope: detecting configurations that don't include enough useful fields\n\nThe default fields in the Security AI Anonymization settings were chosen because they are most likely to provide relevant context for the AI Assistant and Attack discovery.\n\nHowever, there isn't a well defined threshold for the minimum set of useful fields.\n\nFor example, Attack discovery may still produce useful results (depending on the data), if the `user.name`, `host.name`, and `source.ip` fields are not allowed, but in most cases omitting these important fields will reduce the quality of results.\n\nAnother example: A configuration that **only** allows just **two** fields, for example the `_id` field AND `user.name` fields is valid, but NOT _useful_.\n\n- Detecting configurations that don't include enough _useful_ fields is beyond the scope of this PR\n- Configurations that **only** allow the `_id` field are _valid_, but not _useful_\n\n#### Desk testing\n\n1. Navigate to Stack Management > AI Assistants > Security\n\n2. Configure the Security AI Anonymization settings to deny all fields.\n\nNote: At the time of this writing, using the bulk actions to update all `102` default fields may result in an `Unable to load page` error that appears below the table when it is saved. Refreshing the page reveals the settings are not updated after clicking save. As a workaround for this separate, unrelated issue, apply bulk actions to only one page at a time, and be sure to refresh the page after saving changes to verify the update(s) before continuing to the next step.\n\n3. Navigate to Security > Attack discovery\n\n4. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow any fields. Fields must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n\n\n5. Once again, navigate to Stack Management > AI Assistants > Security\n\n6. Allow all the (`102`) default fields\n\n7. Once again, navigate to Security > Attack discovery\n\n8. Click `Generate`\n\n**Expected result**\n\n- Attack discoveries are generated\n\n9. Navigate back to Stack Management > AI Assistants > Security\n\n10. Configure the `_id` field, and another (arbitrary) field to NOT be allowed\n\n11. Navigate back to Security > Attack discovery\n\n12. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow the _id field. The _id field must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n","sha":"c631bdd574d4c8cf3157ea64b67c0db91fc96f19","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team: SecuritySolution","Team:Security Generative AI","backport:version","v8.18.0","v9.1.0","v8.19.0","v8.18.1"],"title":"[Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations","number":214506,"url":"https://github.com/elastic/kibana/pull/214506","mergeCommit":{"message":"[Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations (#214506)\n\n## [Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations\n\nThis PR detects invalid Anonymization configurations when generating Attack discoveries.\n\nIt displays an error message when:\n\n- The Security AI Anonymization settings are configured to not allow _any_ fields, as reported in <https://github.com/elastic/kibana/issues/214310>\n- The Security AI Anonymization settings are configured to not allow the `_id` field, as reported by @aarju\n\n### Out of scope: detecting configurations that don't include enough useful fields\n\nThe default fields in the Security AI Anonymization settings were chosen because they are most likely to provide relevant context for the AI Assistant and Attack discovery.\n\nHowever, there isn't a well defined threshold for the minimum set of useful fields.\n\nFor example, Attack discovery may still produce useful results (depending on the data), if the `user.name`, `host.name`, and `source.ip` fields are not allowed, but in most cases omitting these important fields will reduce the quality of results.\n\nAnother example: A configuration that **only** allows just **two** fields, for example the `_id` field AND `user.name` fields is valid, but NOT _useful_.\n\n- Detecting configurations that don't include enough _useful_ fields is beyond the scope of this PR\n- Configurations that **only** allow the `_id` field are _valid_, but not _useful_\n\n#### Desk testing\n\n1. Navigate to Stack Management > AI Assistants > Security\n\n2. Configure the Security AI Anonymization settings to deny all fields.\n\nNote: At the time of this writing, using the bulk actions to update all `102` default fields may result in an `Unable to load page` error that appears below the table when it is saved. Refreshing the page reveals the settings are not updated after clicking save. As a workaround for this separate, unrelated issue, apply bulk actions to only one page at a time, and be sure to refresh the page after saving changes to verify the update(s) before continuing to the next step.\n\n3. Navigate to Security > Attack discovery\n\n4. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow any fields. Fields must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n\n\n5. Once again, navigate to Stack Management > AI Assistants > Security\n\n6. Allow all the (`102`) default fields\n\n7. Once again, navigate to Security > Attack discovery\n\n8. Click `Generate`\n\n**Expected result**\n\n- Attack discoveries are generated\n\n9. Navigate back to Stack Management > AI Assistants > Security\n\n10. Configure the `_id` field, and another (arbitrary) field to NOT be allowed\n\n11. Navigate back to Security > Attack discovery\n\n12. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow the _id field. The _id field must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n","sha":"c631bdd574d4c8cf3157ea64b67c0db91fc96f19"}},"sourceBranch":"main","suggestedTargetBranches":["9.0","8.18","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214506","number":214506,"mergeCommit":{"message":"[Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations (#214506)\n\n## [Security Solution] [Attack discovery] Display error messages for invalid Anonymization configurations\n\nThis PR detects invalid Anonymization configurations when generating Attack discoveries.\n\nIt displays an error message when:\n\n- The Security AI Anonymization settings are configured to not allow _any_ fields, as reported in <https://github.com/elastic/kibana/issues/214310>\n- The Security AI Anonymization settings are configured to not allow the `_id` field, as reported by @aarju\n\n### Out of scope: detecting configurations that don't include enough useful fields\n\nThe default fields in the Security AI Anonymization settings were chosen because they are most likely to provide relevant context for the AI Assistant and Attack discovery.\n\nHowever, there isn't a well defined threshold for the minimum set of useful fields.\n\nFor example, Attack discovery may still produce useful results (depending on the data), if the `user.name`, `host.name`, and `source.ip` fields are not allowed, but in most cases omitting these important fields will reduce the quality of results.\n\nAnother example: A configuration that **only** allows just **two** fields, for example the `_id` field AND `user.name` fields is valid, but NOT _useful_.\n\n- Detecting configurations that don't include enough _useful_ fields is beyond the scope of this PR\n- Configurations that **only** allow the `_id` field are _valid_, but not _useful_\n\n#### Desk testing\n\n1. Navigate to Stack Management > AI Assistants > Security\n\n2. Configure the Security AI Anonymization settings to deny all fields.\n\nNote: At the time of this writing, using the bulk actions to update all `102` default fields may result in an `Unable to load page` error that appears below the table when it is saved. Refreshing the page reveals the settings are not updated after clicking save. As a workaround for this separate, unrelated issue, apply bulk actions to only one page at a time, and be sure to refresh the page after saving changes to verify the update(s) before continuing to the next step.\n\n3. Navigate to Security > Attack discovery\n\n4. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow any fields. Fields must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n\n\n5. Once again, navigate to Stack Management > AI Assistants > Security\n\n6. Allow all the (`102`) default fields\n\n7. Once again, navigate to Security > Attack discovery\n\n8. Click `Generate`\n\n**Expected result**\n\n- Attack discoveries are generated\n\n9. Navigate back to Stack Management > AI Assistants > Security\n\n10. Configure the `_id` field, and another (arbitrary) field to NOT be allowed\n\n11. Navigate back to Security > Attack discovery\n\n12. Click `Generate`\n\n**Expected result**\n\n- The following error message is displayed:\n\n```\nYour Security AI Anonymization settings are configured to not allow the _id field. The _id field must be allowed to generate Attack discoveries.\n```\n\nas illustrated by the screenshot below:\n\n","sha":"c631bdd574d4c8cf3157ea64b67c0db91fc96f19"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Andrew Macri <andrew.macri@elastic.co>
This commit is contained in:
parent
0cfc64b271
commit
a2fea44c48
4 changed files with 152 additions and 0 deletions
|
@ -22,6 +22,7 @@ import {
|
|||
} from '../../../../../lib/attack_discovery/graphs/default_attack_discovery_graph/constants';
|
||||
import { GraphState } from '../../../../../lib/attack_discovery/graphs/default_attack_discovery_graph/types';
|
||||
import { throwIfErrorCountsExceeded } from '../throw_if_error_counts_exceeded';
|
||||
import { throwIfInvalidAnonymization } from '../throw_if_invalid_anonymization';
|
||||
import { getLlmType } from '../../../../utils';
|
||||
import { getAttackDiscoveryPrompts } from '../../../../../lib/attack_discovery/graphs/default_attack_discovery_graph/nodes/helpers/prompts';
|
||||
|
||||
|
@ -63,6 +64,8 @@ export const invokeAttackDiscoveryGraph = async ({
|
|||
anonymizedAlerts: Document[];
|
||||
attackDiscoveries: AttackDiscovery[] | null;
|
||||
}> => {
|
||||
throwIfInvalidAnonymization(anonymizationFields);
|
||||
|
||||
const llmType = getLlmType(apiConfig.actionTypeId);
|
||||
const model = apiConfig.model;
|
||||
const tags = [ATTACK_DISCOVERY_TAG, llmType, model].flatMap((tag) => tag ?? []);
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 { AnonymizationFieldResponse } from '@kbn/elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen';
|
||||
|
||||
import { throwIfInvalidAnonymization } from '.';
|
||||
import * as i18n from './translations';
|
||||
|
||||
const userNameFieldNotAllowed: AnonymizationFieldResponse = {
|
||||
allowed: false, // <-- This field is NOT allowed
|
||||
anonymized: true,
|
||||
createdAt: '2025-03-13T06:07:34.493Z',
|
||||
field: 'user.name',
|
||||
id: 'kB8djpUBwtgi0OSKhvlf',
|
||||
namespace: 'default',
|
||||
timestamp: '2025-03-13T06:07:34.493Z',
|
||||
updatedAt: '2025-03-13T20:33:58.283Z',
|
||||
};
|
||||
|
||||
const userNameFieldAllowed: AnonymizationFieldResponse = {
|
||||
...userNameFieldNotAllowed,
|
||||
allowed: true, // <-- the user.name field IS allowed
|
||||
};
|
||||
|
||||
const idFieldNotAllowed: AnonymizationFieldResponse = {
|
||||
allowed: false, // <-- This field is NOT allowed
|
||||
anonymized: false,
|
||||
createdAt: '2025-03-13T20:45:41.877Z',
|
||||
field: '_id',
|
||||
id: 'TShBkZUBT8Bn3CFdeOR3',
|
||||
namespace: 'default',
|
||||
timestamp: '2025-03-13T20:45:41.877Z',
|
||||
updatedAt: '2025-03-13T20:33:58.283Z',
|
||||
};
|
||||
|
||||
describe('throwIfInvalidAnonymization', () => {
|
||||
it('throws when the anonymizationFields are empty', () => {
|
||||
const emptyAnonymizationFields: AnonymizationFieldResponse[] = [];
|
||||
|
||||
expect(() => {
|
||||
throwIfInvalidAnonymization(emptyAnonymizationFields);
|
||||
}).toThrowError(i18n.NO_FIELDS_ALLOWED);
|
||||
});
|
||||
|
||||
it('throws when all fields are NOT allowed', () => {
|
||||
const anonymizationFields: AnonymizationFieldResponse[] = [
|
||||
userNameFieldNotAllowed,
|
||||
idFieldNotAllowed,
|
||||
];
|
||||
|
||||
expect(() => {
|
||||
throwIfInvalidAnonymization(anonymizationFields);
|
||||
}).toThrowError(i18n.NO_FIELDS_ALLOWED);
|
||||
});
|
||||
|
||||
it('throws when the _id field is NOT included', () => {
|
||||
const idFieldNotIncluded: AnonymizationFieldResponse[] = [
|
||||
userNameFieldAllowed, // <-- at least one field is allowed
|
||||
];
|
||||
|
||||
expect(() => {
|
||||
throwIfInvalidAnonymization(idFieldNotIncluded);
|
||||
}).toThrowError(i18n.ID_FIELD_REQUIRED);
|
||||
});
|
||||
|
||||
it('throws when the _id field is NOT allowed', () => {
|
||||
const anonymizationFields: AnonymizationFieldResponse[] = [
|
||||
userNameFieldAllowed, // <-- at least one field is allowed
|
||||
idFieldNotAllowed,
|
||||
];
|
||||
|
||||
expect(() => {
|
||||
throwIfInvalidAnonymization(anonymizationFields);
|
||||
}).toThrowError(i18n.ID_FIELD_REQUIRED);
|
||||
});
|
||||
|
||||
it('does NOT throw when the _id field is allowed', () => {
|
||||
const idFieldAllowed: AnonymizationFieldResponse = {
|
||||
...idFieldNotAllowed,
|
||||
allowed: true, // <-- the _id field is allowed
|
||||
};
|
||||
|
||||
const anonymizationFields: AnonymizationFieldResponse[] = [
|
||||
idFieldAllowed,
|
||||
userNameFieldNotAllowed,
|
||||
];
|
||||
|
||||
expect(() => {
|
||||
throwIfInvalidAnonymization(anonymizationFields);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 { AnonymizationFieldResponse } from '@kbn/elastic-assistant-common/impl/schemas/anonymization_fields/bulk_crud_anonymization_fields_route.gen';
|
||||
|
||||
import * as i18n from './translations';
|
||||
|
||||
export const throwIfInvalidAnonymization = (
|
||||
anonymizationFields: AnonymizationFieldResponse[]
|
||||
): void => {
|
||||
const idField = anonymizationFields.find((field) => field.field === '_id');
|
||||
|
||||
// no fields allowed:
|
||||
if (
|
||||
anonymizationFields.length === 0 ||
|
||||
anonymizationFields.every((field) => field.allowed === false)
|
||||
) {
|
||||
throw new Error(i18n.NO_FIELDS_ALLOWED);
|
||||
}
|
||||
|
||||
// _id field NOT included, or NOT allowed:
|
||||
if (idField == null || idField.allowed === false) {
|
||||
throw new Error(i18n.ID_FIELD_REQUIRED);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
|
||||
export const NO_FIELDS_ALLOWED = i18n.translate(
|
||||
'xpack.elasticAssistantPlugin.attackDiscovery.defaultAttackDiscoveryGraph.nodes.retriever.helpers.throwIfInvalidAnonymization.noFieldsAllowedErrorMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your Security AI Anonymization settings are configured to not allow any fields. Fields must be allowed to generate Attack discoveries.',
|
||||
}
|
||||
);
|
||||
|
||||
export const ID_FIELD_REQUIRED = i18n.translate(
|
||||
'xpack.elasticAssistantPlugin.attackDiscovery.defaultAttackDiscoveryGraph.nodes.retriever.helpers.throwIfInvalidAnonymization.idFieldRequiredErrorMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your Security AI Anonymization settings are configured to not allow the _id field. The _id field must be allowed to generate Attack discoveries.',
|
||||
}
|
||||
);
|
Loading…
Add table
Add a link
Reference in a new issue