From c1fde765b98b980e5244f33e5b3651f70b3ce88b Mon Sep 17 00:00:00 2001 From: Andrew Macri Date: Tue, 22 Aug 2023 11:33:20 -0600 Subject: [PATCH] [Security Solution] expandable flyout - Opt in to data anonymization for the Elastic AI Assistant (#164384) ## [Security Solution] expandable flyout - Opt in to data anonymization for the Elastic AI Assistant This PR fixes an issue where the new expandable flyout wasn't opting in to data anonymization when passing alerts as context to the Elastic AI Assistant. As a result: - A stat that reads `0 Anonymized` indicates the alert data will NOT be anonymized - NO toggle buttons to allow specific fields and enable / disable anonymization are displayed ### Reproduction steps To reproduce: 1. Navigate to Security > Alerts 2. Click the `View details` action on any row in the Alerts table to view the new expandable flyout 3. Click the `Chat` button, which appears next to the `Expand details` button in the flyout 4. Expand the `Alert (from summary)` context **Expected results** - Stats for the number of fields that will be `Allowed`, `Anonymized`, and the total number of fields `Available` are displayed - Toggle buttons to allow specific fields and enable / disable anonymization on each field are displayed **Actual results** - A stat that reads `0 Anonymized` indicates the alert data will NOT be anonymized - NO toggle buttons to allow specific fields and enable / disable anonymization are displayed - The plain-text, non-anonymized context data is displayed in the preview, per the screenshot below: ![0_anonymized](https://github.com/elastic/kibana/assets/4459398/e881bb4a-caa4-43c4-8b31-cf3deb354cf7) ## Desk testing 1. Reproduce the issue per the steps above 2. Verify the expected results are displayed when testing the fix, per the screenshot below: ![anonymization-opt-in](https://github.com/elastic/kibana/assets/4459398/79a8228d-c5a6-4ea5-a6ab-4bd992e6b7ef) _Above: After the fix, the expected stats and field level anonymization toggles are displayed_ --- .../flyout/right/hooks/use_assistant.test.tsx | 24 +++++++++++++++++++ .../flyout/right/hooks/use_assistant.ts | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.test.tsx index 1a538a2ceaeae..b5542b5cac5cf 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.test.tsx @@ -54,4 +54,28 @@ describe('useAssistant', () => { expect(hookResult.result.current.showAssistant).toEqual(false); expect(hookResult.result.current.promptContextId).toEqual(''); }); + + it('returns anonymized prompt context data', async () => { + jest + .mocked(useAssistantAvailability) + .mockReturnValue({ hasAssistantPrivilege: true, isAssistantEnabled: true }); + jest + .mocked(useAssistantOverlay) + .mockReturnValue({ showAssistantOverlay: jest.fn, promptContextId: '123' }); + + hookResult = renderUseAssistant(); + + const getPromptContext = (useAssistantOverlay as jest.Mock).mock.calls[0][3]; + + expect(await getPromptContext()).toEqual({ + '@timestamp': ['2023-01-01T01:01:01.000Z'], + 'kibana.alert.ancestors.id': ['ancestors-id'], + 'kibana.alert.rule.description': ['rule-description'], + 'kibana.alert.rule.name': ['rule-name'], + 'kibana.alert.rule.parameters.index': ['rule-parameters-index'], + 'kibana.alert.rule.uuid': ['rule-uuid'], + 'kibana.alert.workflow_status': ['open'], + 'process.entity_id': ['process-entity_id'], + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.ts b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.ts index 13392692e6746..8d9360fdb0f5e 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.ts +++ b/x-pack/plugins/security_solution/public/flyout/right/hooks/use_assistant.ts @@ -9,7 +9,7 @@ import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; import { useAssistantOverlay } from '@kbn/elastic-assistant'; import { useCallback } from 'react'; import { useAssistantAvailability } from '../../../assistant/use_assistant_availability'; -import { getPromptContextFromEventDetailsItem } from '../../../assistant/helpers'; +import { getRawData } from '../../../assistant/helpers'; import { ALERT_SUMMARY_CONTEXT_DESCRIPTION, ALERT_SUMMARY_CONVERSATION_ID, @@ -59,7 +59,7 @@ export const useAssistant = ({ const { hasAssistantPrivilege } = useAssistantAvailability(); const useAssistantHook = hasAssistantPrivilege ? useAssistantOverlay : useAssistantNoop; const getPromptContext = useCallback( - async () => getPromptContextFromEventDetailsItem(dataFormattedForFieldBrowser ?? []), + async () => getRawData(dataFormattedForFieldBrowser ?? []), [dataFormattedForFieldBrowser] ); const { promptContextId } = useAssistantHook(