Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] [Security Solution] [Attack discovery] Alerts filtering (#205070) #205137

Merged
merged 2 commits into from
Dec 24, 2024

Conversation

kibanamachine
Copy link
Contributor

Backport

This will backport the following commits from main to 8.x:

Questions ?

Please refer to the Backport tool documentation

## [Security Solution] [Attack discovery] Alerts filtering

![00_alerts_filtering](https://github.com/user-attachments/assets/1a81413b-b8f4-4965-a006-25fb529668a6)

This PR enhances _Attack discovery_ by providing users additional control over which alerts are included as context to the large language model (LLM).

Using the new resizeable _Attack discovery settings flyout_, users may:

- Filter alerts via a search bar and filters
- Control the time window (previously fixed to `Last 24 hrs`)

### Before (feature flag disabled)

Previously, users could only set the number of alerts sent as context to the LLM via a modal:

![01_before_full_page](https://github.com/user-attachments/assets/65eaf604-3bdf-41bd-a726-f03ba5d630d5)

### After (feature flag enabled)

The new Attack discovery settings flyout replaces the modal:

![02_alert_summary_full_page](https://github.com/user-attachments/assets/613c292b-c6ec-4dc6-aea3-b2eddbacd614)

It has two tabs, _Alert summary_ and _Alerts preview_.

### Alert summary

The _Alert summary_ Lens embeddable counts the selected field name via an ES|QL query:

![03_alert_summary_cropped](https://github.com/user-attachments/assets/6f5de0e4-3da6-4937-a3cd-9a0f80df16b6)

The Alert summary query is an aggregation. It does NOT display the details of individual alerts.

### Alerts preview

The _Alerts preview_ Lens embeddable shows a preview of the actual alerts that will be sent as context via an ES|QL query:

![05_alerts_preview_cropped](https://github.com/user-attachments/assets/6db23931-3fe6-46d2-8b9a-6cc7a9d8720c)

Users may resize the settings flyout to view all the fields in the Alerts preview.

### Feature flag

Enable the `attackDiscoveryAlertFiltering` feature flag via the following setting in `kibana.dev.yml`:

```yaml
xpack.securitySolution.enableExperimental:
  - 'attackDiscoveryAlertFiltering'
```

Enabling the feature flag:

- Replaces the `Settings` modal with the `Attack discovery settings` flyout
- Includes additional `start`, `end`, and `filters` parameters in requests to generate Attack discoveries
- Enables new loading messages

### Details

#### Loading messages

The loading messages displayed when generating Attack discoveries were updated to render three types of date ranges:

1) The default date range (`Last 24 hours`), which displays the same message seen in previous versions:

![06_loading_default_date_range](https://github.com/user-attachments/assets/b376a87c-b4b8-42d8-bcbf-ddf79cc82800)

2) Relative date ranges:

![07_loading_relative_date_range](https://github.com/user-attachments/assets/d0b6bddd-7722-4181-a99c-7450d07a6624)

3) Absolute date ranges:

![08_loading_absolute_date_range](https://github.com/user-attachments/assets/a542a921-eeaa-4ced-9568-25e63a47d42d)

#### Filtering preferences

Alert filtering preferences are stored in local storage.

This PR adds the following new local storage keys:

```
elasticAssistantDefault.attackDiscovery.default.end
elasticAssistantDefault.attackDiscovery.default.filters
elasticAssistantDefault.attackDiscovery.default.query
elasticAssistantDefault.attackDiscovery.default.start
```

Users may use the `Reset` button in the Attack discovery settings flyout to restore the above to their defaults.

#### Known limitations

The following known limitations in this PR may be mitigated in follow-up PRs:

#### Table cell hover actions are disabled

Table cell actions, i.e. `Filter for` and `Filter out` are disabled in the `Alert summary` and `Alerts preview` tables.

The actions are disabled because custom cell hover actions registered in `x-pack/solutions/security/plugins/security_solution/public/app/actions/register.ts` do NOT appear to receive field metadata (i.e. the name of the field being hovered over) when the action is triggered. This limitation also appears to apply to ad hoc ES|QL visualizations created via Lens in Kibana's _Dashboard_ app.

##### Default table sort indicators are hidden

The `Alert summary` and `Alerts preview` tables are sorted descending by Count, and Risk score, respectively, via their ES|QL queries.

The tables _should_ display default sort indicators, as illustrated by the screenshots below:

![09_alert_summary_with_sort_indicator](https://github.com/user-attachments/assets/c4e78144-f516-40f8-b6da-7c8c808841c4)

![10_alerts_preview_with_sort_indicator](https://github.com/user-attachments/assets/c0061134-4734-462f-8eb0-978b2b02fb1e)

The default indicators are hidden in this PR as a workaround for an  error that occurs in `EuiDataGrid` when switching tabs when the column sort indicators are enabled:

```
TypeError: Cannot read properties of undefined (reading 'split')
```

To re-enable the sort indicators, `DEFAULT_ALERT_SUMMARY_SORT` and `DEFAULT_ALERTS_PREVIEW_SORT` must respectively be passed as the `sorting` prop to the `PreviewTab` in `x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/alert_selection/helpers/get_tabs/index.tsx`, as illustrated by the following code:

```typescript
  <PreviewTab
    dataTestSubj={ALERT_SUMMARY_TEST_SUBJ}
    embeddableId={SUMMARY_TAB_EMBEDDABLE_ID}
    end={end}
    filters={filters}
    getLensAttributes={getAlertSummaryLensAttributes}
    getPreviewEsqlQuery={getAlertSummaryEsqlQuery}
    maxAlerts={maxAlerts}
    query={query}
    setTableStackBy0={setAlertSummaryStackBy0}
    start={start}
    sorting={DEFAULT_ALERT_SUMMARY_SORT} // <-- enables the sort indicator
    tableStackBy0={alertSummaryStackBy0}
  />
```

##### Selected date range not persisted

The `start` and `end` date range selected when a user starts generation are not (yet) persisted in Elasticsearch. As a result, the loading message always displays the currently configured range, rather than the range selected at the start of generation.

(cherry picked from commit 681d40e)
…olution/public/attack_discovery/pages/index.tsx`

In `main`, the `convertToBuildEsQuery` function called in the page above accepts a parameter named `dataViewSpec`, which is typed as:

```typescript
dataViewSpec: DataViewSpec | undefined;
```

In `8.x`, the `convertToBuildEsQuery` function takes a different parameter named `indexPattern` instead of `dataViewSpec`, and it's typed differently:

```typescript
indexPattern: DataViewBase | undefined;
```

The page was updated to call the `convertToBuildEsQuery` function using the `8.x` version of the parameter.

- fixed a type error by updating `x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/alert_selection/use_data_view/index.ts`

In `8.x`, when the `AlertSelectionQuery` component in `x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/alert_selection/alert_selection_query/index.tsx` obtains a `sourcererDataView` via `useSourcererDataView` in the following code:

```typescript
  const { sourcererDataView, loading: isLoadingIndexPattern } = useSourcererDataView(
    SourcererScopeName.detections
  );
```

the `sourcererDataView` is typed as:

```typescript
const sourcererDataView: DataViewSpec | undefined
```

The `dataViewSpec` parameter of the `useDataView` hook was updated (in this 8.x branch) to reflect the fact that `sourcererDataView` may be undefined:

```typescript
dataViewSpec: DataViewSpec | undefined;
```

and an additional check for `undefined` was added in `useDataView`.
Comment on lines +187 to +198
const { indexPattern } = useSourcererDataView();

// filterQuery is the combined search bar query and filters in ES format:
const [filterQuery, kqlError] = useMemo(
() =>
convertToBuildEsQuery({
config: getEsQueryConfig(uiSettings),
indexPattern,
queries: [query ?? getDefaultQuery()], // <-- search bar query
filters: filters ?? [], // <-- search bar filters
}),
[filters, indexPattern, query, uiSettings]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In main, the convertToBuildEsQuery function called here accepts a parameter named dataViewSpec, which is typed as:

dataViewSpec: DataViewSpec | undefined;

In 8.x, the convertToBuildEsQuery function takes a different parameter named indexPattern instead of dataViewSpec, and it's typed differently:

indexPattern: DataViewBase | undefined;

The page was updated to call the convertToBuildEsQuery function using the 8.x version of the parameter.

dataViewSpec,
loading,
}: {
dataViewSpec: DataViewSpec | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 8.x, when the AlertSelectionQuery component in x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/settings_flyout/alert_selection/alert_selection_query/index.tsx obtains a sourcererDataView via useSourcererDataView in the following code:

  const { sourcererDataView, loading: isLoadingIndexPattern } = useSourcererDataView(
    SourcererScopeName.detections
  );

the sourcererDataView is typed as:

const sourcererDataView: DataViewSpec | undefined

The dataViewSpec parameter of the useDataView hook was updated (in this 8.x branch) to reflect the fact that sourcererDataView may be undefined:

dataViewSpec: DataViewSpec | undefined;

let active = true;

async function createDataView() {
if (dataViewSpec != null && !loading) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional check was added because in the 8.x branch, the dataViewSpec argument may be undefined:

dataViewSpec: DataViewSpec | undefined;

as noted in this comment above.

@kibanamachine kibanamachine merged commit a8cf4eb into elastic:8.x Dec 24, 2024
8 checks passed
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 6445 6469 +24

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/elastic-assistant 141 145 +4
@kbn/elastic-assistant-common 405 410 +5
total +9

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
securitySolution 18.5MB 18.5MB +19.5KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
securitySolution 86.6KB 86.6KB +33.0B
Unknown metric groups

API count

id before after diff
@kbn/elastic-assistant 170 174 +4
@kbn/elastic-assistant-common 442 447 +5
total +9

History

cc @andrew-goldstein

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants