[SecuritySolution] Fix search indices that was returning unmapped fields (#225245)

## Summary

The bug: A field with the expected name `user.name.keyword` but with the
wrong mapping was returned.

How to fix it? `fieldCaps` was returning unmapped mixed with mapped
fields. This change forces the API to return the `fields` property with
a list of all indices matching `user.name.keyword`.

More information on [this
slack](https://elastic.slack.com/archives/C0D8ST60Y/p1750661564933609) 🧵
 

### How to test it?
* Create an index with the correct mapping
```
PUT /test-index1
{
  "mappings": {
    "properties": {
      "user.name.keyword": {
        "type": "text"
      }
    }
  }
}
```
* Create an index with the wrong mapping

```
PUT /test-index2
{
  "mappings": {
    "properties": {
      "user.name.keyword": {
        "type": "text"
      }
    }
  }
}
```
* Go to the manage data sources page
* Only `test-index1` should be returned
This commit is contained in:
Pablo Machado 2025-06-26 13:16:02 +02:00 committed by GitHub
parent 6a791fa179
commit cc6a2a978e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -236,34 +236,25 @@ export class PrivilegeMonitoringDataClient {
}
public async searchPrivilegesIndices(query: string | undefined) {
const { indices } = await this.esClient.fieldCaps({
const { indices, fields } = await this.esClient.fieldCaps({
index: [query ? `*${query}*` : '*', ...PRE_EXCLUDE_INDICES],
types: ['keyword'],
fields: ['user.name.keyword'], // search for indices with field 'user.name.keyword' of type 'keyword'
include_unmapped: false,
include_unmapped: true,
ignore_unavailable: true,
allow_no_indices: true,
expand_wildcards: 'open',
include_empty_fields: false,
include_empty_fields: true,
filters: '-parent',
index_filter: {
bool: {
must: [
{
exists: {
field: 'user.name.keyword',
},
},
],
},
},
});
if (!Array.isArray(indices) || indices.length === 0) {
const indicesWithUserName = fields['user.name.keyword']?.keyword?.indices ?? indices;
if (!Array.isArray(indicesWithUserName) || indicesWithUserName.length === 0) {
return [];
}
return indices.filter(
return indicesWithUserName.filter(
(name) => !POST_EXCLUDE_INDICES.some((pattern) => name.startsWith(pattern))
);
}