Skip to content

Commit

Permalink
[8.14] [Security solution] Add additional properties to attack discov…
Browse files Browse the repository at this point in the history
…ery telemetry (#182249) (#182997)

# Backport

This will backport the following commits from `main` to `8.14`:
- [[Security solution] Add additional properties to attack discovery
telemetry (#182249)](#182249)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Steph
Milovic","email":"stephanie.milovic@elastic.co"},"sourceCommit":{"committedDate":"2024-05-02T04:48:36Z","message":"[Security
solution] Add additional properties to attack discovery telemetry
(#182249)","sha":"e306074aa9e8943ab342270a6f795e17ee37c1da","branchLabelMapping":{"^v8.15.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:
SecuritySolution","Team:Security Generative
AI","v8.14.0","v8.15.0","Feature:Attack
Discovery"],"number":182249,"url":"#182249
solution] Add additional properties to attack discovery telemetry
(#182249)","sha":"e306074aa9e8943ab342270a6f795e17ee37c1da"}},"sourceBranch":"main","suggestedTargetBranches":["8.14"],"targetPullRequestStates":[{"branch":"8.14","label":"v8.14.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.15.0","labelRegex":"^v8.15.0$","isSourceBranch":true,"state":"MERGED","url":"#182249
solution] Add additional properties to attack discovery telemetry
(#182249)","sha":"e306074aa9e8943ab342270a6f795e17ee37c1da"}}]}]
BACKPORT-->
  • Loading branch information
stephmilovic committed May 8, 2024
1 parent 6e804fd commit a71c51c
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ interface GenAiConfig {
export const getGenAiConfig = (connector: ActionConnector | undefined): GenAiConfig | undefined => {
if (!connector?.isPreconfigured) {
const config = (connector as ActionConnectorProps<GenAiConfig, unknown>)?.config;
if (config?.apiProvider === OpenAiProviderType.AzureAi) {
return {
...config,
defaultModel: getAzureApiVersionParameter(config.apiUrl ?? ''),
};
}

return (connector as ActionConnectorProps<GenAiConfig, unknown>)?.config;
const { apiProvider, apiUrl, defaultModel } = config ?? {};

return {
apiProvider,
apiUrl,
defaultModel:
apiProvider === OpenAiProviderType.AzureAi
? getAzureApiVersionParameter(apiUrl ?? '')
: defaultModel,
};
}
return undefined;

return undefined; // the connector is neither available nor editable
};

export const getActionTypeTitle = (actionType: ActionTypeModel): string => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ describe('useAttackDiscoveryTelemetry', () => {
await result.current.reportAttackDiscoveriesGenerated({
actionTypeId: '.gen-ai',
model: 'gpt-4',
durationMs: 8000,
alertsCount: 20,
configuredAlertsCount: 30,
});
expect(reportAttackDiscoveriesGenerated).toHaveBeenCalledWith({
actionTypeId: '.gen-ai',
model: 'gpt-4',
durationMs: 8000,
alertsCount: 20,
configuredAlertsCount: 30,
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 type { ActionConnector } from '@kbn/triggers-actions-ui-plugin/public';
import type { ActionConnectorProps } from '@kbn/triggers-actions-ui-plugin/public/types';

// aligns with OpenAiProviderType from '@kbn/stack-connectors-plugin/common/openai/types'
enum OpenAiProviderType {
OpenAi = 'OpenAI',
AzureAi = 'Azure OpenAI',
}

interface GenAiConfig {
apiProvider?: OpenAiProviderType;
apiUrl?: string;
defaultModel?: string;
}

/**
* Returns the GenAiConfig for a given ActionConnector. Note that if the connector is preconfigured,
* the config will be undefined as the connector is neither available nor editable.
*
* @param connector
*/
export const getGenAiConfig = (connector: ActionConnector | undefined): GenAiConfig | undefined => {
if (!connector?.isPreconfigured) {
const config = (connector as ActionConnectorProps<GenAiConfig, unknown>)?.config;
const { apiProvider, apiUrl, defaultModel } = config ?? {};

return {
apiProvider,
apiUrl,
defaultModel:
apiProvider === OpenAiProviderType.AzureAi
? getAzureApiVersionParameter(apiUrl ?? '')
: defaultModel,
};
}

return undefined; // the connector is neither available nor editable
};

const getAzureApiVersionParameter = (url: string): string | undefined => {
const urlSearchParams = new URLSearchParams(new URL(url).search);
return urlSearchParams.get('api-version') ?? undefined;
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
AttackDiscoveryPostResponse,
ELASTIC_AI_ASSISTANT_INTERNAL_API_VERSION,
} from '@kbn/elastic-assistant-common';
import { isEmpty } from 'lodash/fp';
import { isEmpty, uniq } from 'lodash/fp';
import moment from 'moment';
import React, { useCallback, useMemo, useState } from 'react';
import { useLocalStorage, useSessionStorage } from 'react-use';
Expand All @@ -41,6 +41,7 @@ import {
} from '../pages/session_storage';
import { ERROR_GENERATING_ATTACK_DISCOVERIES } from '../pages/translations';
import type { AttackDiscovery, GenerationInterval } from '../types';
import { getGenAiConfig } from './helpers';

const MAX_GENERATION_INTERVALS = 5;

Expand Down Expand Up @@ -230,7 +231,17 @@ export const useAttackDiscovery = ({
setAttackDiscoveries(newAttackDiscoveries);
setLastUpdated(newLastUpdated);
setConnectorId?.(connectorId);
reportAttackDiscoveriesGenerated({ actionTypeId });
const connectorConfig = getGenAiConfig(selectedConnector);
reportAttackDiscoveriesGenerated({
actionTypeId,
durationMs,
alertsCount: uniq(
newAttackDiscoveries.flatMap((attackDiscovery) => attackDiscovery.alertIds)
).length,
configuredAlertsCount: knowledgeBase.latestAlerts,
provider: connectorConfig?.apiProvider,
model: connectorConfig?.defaultModel,
});
} catch (error) {
toasts?.addDanger(error, {
title: ERROR_GENERATING_ATTACK_DISCOVERIES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ export const insightsGeneratedEvent: TelemetryEvent = {
optional: false,
},
},
durationMs: {
type: 'integer',
_meta: {
description: 'Duration of request in ms',
optional: false,
},
},
alertsCount: {
type: 'integer',
_meta: {
description: 'Number of unique alerts referenced in the attack discoveries',
optional: false,
},
},
configuredAlertsCount: {
type: 'integer',
_meta: {
description: 'Number of alerts configured by the user',
optional: false,
},
},
model: {
type: 'keyword',
_meta: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export interface ReportAttackDiscoveriesGeneratedParams {
actionTypeId: string;
provider?: string;
model?: string;
durationMs: number;
alertsCount: number;
configuredAlertsCount: number;
}

export type ReportAttackDiscoveryTelemetryEventParams = ReportAttackDiscoveriesGeneratedParams;
Expand Down

0 comments on commit a71c51c

Please sign in to comment.