Skip to content

Commit 2f50c8b

Browse files
spongkibanamachine
authored andcommitted
[Security Assistant] Fixes issue preventing the creation of Knowledge Base Index Entries in deployments with a large number of indices/mappings (elastic#231376)
## Summary This PR fixes an issue with the Security Assistant KB Index Entries interface introduced in `9.1` where a large number of indices/mappings could result in Kibana crashing and preventing the creation of the Index Entry. This is technically a 'fix-hancement' as we are bypassing the underlying issue altogether by switching to use common core API's for index/field suggestions (just as is done in the Discover 'Create a data view' interface), and in turn supporting all fields of type `text`, not just `semantic_text` (elastic#230863). ### Original Issue The underlying issue here was introduced by a change to the `field_caps` API in `9.1` (elastic/elasticsearch#127664) that resulted in the `/internal/elastic_assistant/knowledge_base/_indices` route not finding any indices with a `semantic_text` field, and thus inadvertently falling back to doing a full scan of all mappings ([source](https://github.com/elastic/kibana/blob/b128cee4ee7ccc367e8acf159dbf58a75f081867/x-pack/solutions/security/plugins/elastic_assistant/server/routes/knowledge_base/get_knowledge_base_indices.ts#L69)). A fix to this API was initially investigated, but there was no reasonable API available for fetching all occurrences of `semantic_text` fields, so with `match` queries adding support for `semantic_text` in `8.18`, it was decided to go ahead and enable support for all `text` fields. ### Fix Details The `Index` input field now uses the `dataViews.getIndices()` API for suggestions (instead of the `useKnowledgeBaseIndices` hook/route), which is backed by the [resolve indices ES API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-resolve-index). System indices are filtered out with the `*,-.*` filter. The initial call will return all indices just as the Discover 'Create a data view' interface, which is further filtered upon as the user continues to type. Note: Discover makes subsequent calls upon further user input, though I'm not entirely sure this is necessary here as all indices are initially returned and available for client-side filtering within the input. I will perform further stress testing with many indices/mappings to confirm. The `Field` input now uses the fields already queried for the `Output fields` input suggestions (via `dataViews.getFieldsForWildcard()`), just filtered to those whose `field.esTypes?.includes('text')`. This is potentially still a hot path for client-side code with many mappings, so I will also confirm this with further stress testing. ### Docs @elastic/security-docs / @benironside, we will need to update the Security Assistant KB docs [here](https://www.elastic.co/docs/solutions/security/ai/ai-assistant-knowledge-base#knowledge-base-add-knowledge-index) to indicate that any `text` field is now supported for retrieval. ### Testing #### Functional Testing To confirm proper retrieval of both `text` and `semantic_text` fields we'll need to create an index, add a document, then create the KB Index Entry. Then update the KB Index Entry to reference the other field type, and test again. <details><summary>Create Index</summary> <p> ``` JSON PUT project-details { "mappings": { "properties": { "project_issue": { "type": "text" }, "project_name": { "type": "text" }, "summary": { "type": "semantic_text", "inference_id": ".elser-2-elasticsearch", "model_settings": { "service": "elasticsearch", "task_type": "sparse_embedding" } } } } } ``` </p> </details> <details><summary>Create Sample Doc</summary> <p> ``` JSON PUT project-details/_doc/doc1 { "project_issue": "The main issue at hand is the breaking of the space plane", "project_name": "Issue 5", "summary": "This is a summary that contains the word yellow" } ``` </p> </details> <details><summary>Create KB Index Entry (Text)</summary> <p> ``` JSON POST kbn:api/security_ai_assistant/knowledge_base/entries { "type": "index", "name": "Project Details Tool", "index": "project-details", "field": "project_issue", "outputFields": [], "description": "Use this index to answer questions about any project details.", "queryDescription": "Key terms to search for from the user's prompt." } ``` </p> </details> Now you can open the Assistant and perform a query like: ``` Do I have any project details about the issue at hand? ``` Which should result in a [trace like this](https://smith.langchain.com/public/208338a6-42f3-4a9d-bc4c-0ff38d06d34c/r) which calls the generated tool that will then perform a _lexical search_ against the configured index. Ensure citations work as expected for the returned document. Now open the Index Entry in the KB Settings UI and change the `field` to from `project_issue` to `summary` for testing `semantic_text`. Open the Assistant and perform a query like: ``` Do I have any project details for Project Yellow? ``` Which should result in a [trace like this](https://smith.langchain.com/public/3041a48b-5dfd-4c89-9f51-0bcdffd38f63/r) which calls the generated tool that will then perform a _semantic search_ against the configured index. Ensure citations work as expected for the returned document. #### Performance Testing ⚠️ In progress -- I will include a script for generating many indices/mappings for testing, and also prepare the `ci-cloud-deploy` instance with the same setup for confirmation. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [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/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials * Will coordinate with @elastic/security-docs on the docs update here. - [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: kibanamachine <[email protected]>
1 parent f5fe7ce commit 2f50c8b

File tree

30 files changed

+109
-958
lines changed

30 files changed

+109
-958
lines changed

src/platform/packages/shared/kbn-doc-links/src/get_doc_links.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,9 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
483483
mlAnomalyDetection: `${ELASTIC_DOCS}explore-analyze/machine-learning/anomaly-detection`,
484484
},
485485
detectionEngineOverview: `${ELASTIC_DOCS}solutions/security/detect-and-alert`,
486+
// TODO: Follow-up PR for creating an aiAssistant category adding all relevant doc links
486487
aiAssistant: `${ELASTIC_DOCS}solutions/security/ai/ai-assistant`,
488+
aiAssistantKnowledgeBaseIndexEntries: `${ELASTIC_DOCS}solutions/security/ai/ai-assistant-knowledge-base#knowledge-base-add-knowledge-index`,
487489
signalsMigrationApi: isServerless
488490
? `${KIBANA_APIS}group/endpoint-security-detections-api`
489491
: `${KIBANA_SERVERLESS_APIS}group/endpoint-security-detections-api`,

src/platform/packages/shared/kbn-doc-links/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ export interface DocLinks {
301301
};
302302
readonly securitySolution: {
303303
readonly aiAssistant: string;
304+
readonly aiAssistantKnowledgeBaseIndexEntries: string;
304305
readonly cloudSecurityPosture: string;
305306
readonly installElasticDefend: string;
306307
readonly artifactControl: string;

x-pack/platform/packages/shared/kbn-elastic-assistant-common/constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ export const ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_ENTRIES_URL_FIND =
5454
export const ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_ENTRIES_URL_BULK_ACTION =
5555
`${ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_ENTRIES_URL}/_bulk_action` as const;
5656

57-
export const ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_INDICES_URL =
58-
`${ELASTIC_AI_ASSISTANT_INTERNAL_URL}/knowledge_base/_indices` as const;
5957
export const ELASTIC_AI_ASSISTANT_EVALUATE_URL =
6058
`${ELASTIC_AI_ASSISTANT_INTERNAL_URL}/evaluate` as const;
6159

x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ export * from './actions_connector/post_actions_connector_execute_route.gen';
6060

6161
// Knowledge Base Schemas
6262
export * from './knowledge_base/crud_kb_route.gen';
63-
export * from './knowledge_base/get_knowledge_base_indices_route.gen';
6463
export * from './knowledge_base/entries/bulk_crud_knowledge_base_entries_route.gen';
6564
export * from './knowledge_base/entries/common_attributes.gen';
6665
export * from './knowledge_base/entries/crud_knowledge_base_entries_route.gen';

x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/get_knowledge_base_indices_route.gen.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

x-pack/platform/packages/shared/kbn-elastic-assistant-common/impl/schemas/knowledge_base/get_knowledge_base_indices_route.schema.yaml

Lines changed: 0 additions & 40 deletions
This file was deleted.

x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/api/knowledge_base/api.test.tsx

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import { HttpSetup } from '@kbn/core-http-browser';
99

10-
import { getKnowledgeBaseIndices, getKnowledgeBaseStatus, postKnowledgeBase } from './api';
10+
import { getKnowledgeBaseStatus, postKnowledgeBase } from './api';
1111
import { API_VERSIONS } from '@kbn/spaces-plugin/common';
1212

1313
jest.mock('@kbn/core-http-browser');
@@ -73,29 +73,4 @@ describe('API tests', () => {
7373
await expect(postKnowledgeBase(knowledgeBaseArgs)).rejects.toThrowError('simulated error');
7474
});
7575
});
76-
77-
describe('getKnowledgeBaseIndices', () => {
78-
it('calls the knowledge base API when correct resource path', async () => {
79-
await getKnowledgeBaseIndices({ http: mockHttp });
80-
81-
expect(mockHttp.fetch).toHaveBeenCalledWith(
82-
'/internal/elastic_assistant/knowledge_base/_indices',
83-
{
84-
method: 'GET',
85-
signal: undefined,
86-
version: '1',
87-
}
88-
);
89-
});
90-
it('returns error when error is an error', async () => {
91-
const error = 'simulated error';
92-
(mockHttp.fetch as jest.Mock).mockImplementation(() => {
93-
throw new Error(error);
94-
});
95-
96-
await expect(getKnowledgeBaseIndices({ http: mockHttp })).resolves.toThrowError(
97-
'simulated error'
98-
);
99-
});
100-
});
10176
});

x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/api/knowledge_base/api.tsx

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import {
99
API_VERSIONS,
1010
CreateKnowledgeBaseRequestParams,
1111
CreateKnowledgeBaseResponse,
12-
ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_INDICES_URL,
1312
ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_URL,
14-
GetKnowledgeBaseIndicesResponse,
1513
ReadKnowledgeBaseRequestParams,
1614
ReadKnowledgeBaseResponse,
1715
} from '@kbn/elastic-assistant-common';
@@ -76,32 +74,3 @@ export const postKnowledgeBase = async ({
7674

7775
return response as CreateKnowledgeBaseResponse;
7876
};
79-
80-
/**
81-
* API call for getting indices that have fields of `semantic_text` type.
82-
*
83-
* @param {Object} options - The options object.
84-
* @param {HttpSetup} options.http - HttpSetup
85-
* @param {AbortSignal} [options.signal] - AbortSignal
86-
*
87-
* @returns {Promise<GetKnowledgeBaseIndicesResponse | IHttpFetchError>}
88-
*/
89-
export const getKnowledgeBaseIndices = async ({
90-
http,
91-
signal,
92-
}: {
93-
http: HttpSetup;
94-
signal?: AbortSignal | undefined;
95-
}): Promise<GetKnowledgeBaseIndicesResponse | IHttpFetchError> => {
96-
try {
97-
const response = await http.fetch(ELASTIC_AI_ASSISTANT_KNOWLEDGE_BASE_INDICES_URL, {
98-
method: 'GET',
99-
signal,
100-
version: API_VERSIONS.internal.v1,
101-
});
102-
103-
return response as GetKnowledgeBaseIndicesResponse;
104-
} catch (error) {
105-
return error as IHttpFetchError;
106-
}
107-
};

x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/api/knowledge_base/use_knowledge_base_indices.test.tsx

Lines changed: 0 additions & 80 deletions
This file was deleted.

x-pack/platform/packages/shared/kbn-elastic-assistant/impl/assistant/api/knowledge_base/use_knowledge_base_indices.tsx

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)