Skip to content

Commit

Permalink
Update the Risk Input table in the expanded Entity Flyout to incorpor…
Browse files Browse the repository at this point in the history
…ate all alerts contributing to the risk score (elastic#174025)

## Update the Risk Input table in the expanded Entity Flyout to
incorporate all alerts contributing to the risk score



<img width="1260" alt="Screenshot 2024-01-03 at 12 06 13"
src="https://github.com/elastic/kibana/assets/7609147/81bbdcd6-d15c-4d70-9552-b270f75346d4">

We have changed the way how we request alerts for the risk inputs table.
It will create a new query:

```
 query: {
      bool: {
        filter: [
          { term: { "user.name": "${user.name}" } },
          {
            range: {
              '@timestamp': {
                gte: from,
                lte: to,
              },
            },
          },
        ],
      },
    }
```

It still uses in-memory pagination.

It also updates the number of alerts in the Risk input summary but
doesn't change the inspect query, as it can be used in the future for
asset criticality and other input sources.

## Add new API to return risk engine settings

Currently, return only the risk engine **range**, any other options can
be added later if needed.

Also added an open API generated types for this route

---------

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
nkhristinin and kibanamachine authored Jan 9, 2024
1 parent 46707e4 commit 3fea5d4
Show file tree
Hide file tree
Showing 32 changed files with 1,019 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,139 @@ export const EntityAnalyticsPrivileges = z.object({
}),
}),
});

export type AfterKeys = z.infer<typeof AfterKeys>;
export const AfterKeys = z.object({
host: z.object({}).catchall(z.string()).optional(),
user: z.object({}).catchall(z.string()).optional(),
});

/**
* The identifier of the Kibana data view to be used when generating risk scores.
*/
export type DataViewId = z.infer<typeof DataViewId>;
export const DataViewId = z.string();

/**
* An elasticsearch DSL filter object. Used to filter the risk inputs involved, which implicitly filters the risk scores themselves.
*/
export type Filter = z.infer<typeof Filter>;
export const Filter = z.object({});

/**
* Specifies how many scores will be involved in a given calculation. Note that this value is per `identifier_type`, i.e. a value of 10 will calculate 10 host scores and 10 user scores, if available. To avoid missed data, keep this value consistent while paginating through scores.
*/
export type PageSize = z.infer<typeof PageSize>;
export const PageSize = z.number().default(1000);

export type KibanaDate = z.infer<typeof KibanaDate>;
export const KibanaDate = z.string();

/**
* Defines the time period on which risk inputs will be filtered.
*/
export type DateRange = z.infer<typeof DateRange>;
export const DateRange = z.object({
start: KibanaDate,
end: KibanaDate,
});

export type IdentifierType = z.infer<typeof IdentifierType>;
export const IdentifierType = z.enum(['host', 'user']);
export type IdentifierTypeEnum = typeof IdentifierType.enum;
export const IdentifierTypeEnum = IdentifierType.enum;

/**
* A generic representation of a document contributing to a Risk Score.
*/
export type RiskScoreInput = z.infer<typeof RiskScoreInput>;
export const RiskScoreInput = z.object({
/**
* The unique identifier (`_id`) of the original source document
*/
id: z.string().optional(),
/**
* The unique index (`_index`) of the original source document
*/
index: z.string().optional(),
/**
* The risk category of the risk input document.
*/
category: z.string().optional(),
/**
* A human-readable description of the risk input document.
*/
description: z.string().optional(),
/**
* The weighted risk score of the risk input document.
*/
risk_score: z.number().min(0).max(100).optional(),
/**
* The @timestamp of the risk input document.
*/
timestamp: z.string().optional(),
});

export type RiskScore = z.infer<typeof RiskScore>;
export const RiskScore = z.object({
/**
* The time at which the risk score was calculated.
*/
'@timestamp': z.string().datetime(),
/**
* The identifier field defining this risk score. Coupled with `id_value`, uniquely identifies the entity being scored.
*/
id_field: z.string(),
/**
* The identifier value defining this risk score. Coupled with `id_field`, uniquely identifies the entity being scored.
*/
id_value: z.string(),
/**
* Lexical description of the entity's risk.
*/
calculated_level: z.string(),
/**
* The raw numeric value of the given entity's risk score.
*/
calculated_score: z.number(),
/**
* The normalized numeric value of the given entity's risk score. Useful for comparing with other entities.
*/
calculated_score_norm: z.number().min(0).max(100),
/**
* The contribution of Category 1 to the overall risk score (`calculated_score`). Category 1 contains Detection Engine Alerts.
*/
category_1_score: z.number(),
/**
* The number of risk input documents that contributed to the Category 1 score (`category_1_score`).
*/
category_1_count: z.number(),
/**
* A list of the highest-risk documents contributing to this risk score. Useful for investigative purposes.
*/
inputs: z.array(RiskScoreInput),
});

/**
* Configuration used to tune risk scoring. Weights can be used to change the score contribution of risk inputs for hosts and users at both a global level and also for Risk Input categories (e.g. 'category_1').
*/
export type RiskScoreWeight = z.infer<typeof RiskScoreWeight>;
export const RiskScoreWeight = z.object({
type: z.string(),
value: z.string().optional(),
host: z.number().min(0).max(1).optional(),
user: z.number().min(0).max(1).optional(),
});

/**
* A list of weights to be applied to the scoring calculation.
*/
export type RiskScoreWeights = z.infer<typeof RiskScoreWeights>;
export const RiskScoreWeights = z.array(RiskScoreWeight);

export type RiskEngineInitStep = z.infer<typeof RiskEngineInitStep>;
export const RiskEngineInitStep = z.object({
type: z.string(),
success: z.boolean(),
error: z.string().optional(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,195 @@ components:
required:
- has_all_required
- privileges
AfterKeys:
type: object
properties:
host:
type: object
additionalProperties:
type: string
user:
type: object
additionalProperties:
type: string
example:
host:
'host.name': 'example.host'
user:
'user.name': 'example_user_name'

DataViewId:
description: The identifier of the Kibana data view to be used when generating risk scores.
example: security-solution-default
type: string

Filter:
description: An elasticsearch DSL filter object. Used to filter the risk inputs involved, which implicitly filters the risk scores themselves.
type: object

PageSize:
description: Specifies how many scores will be involved in a given calculation. Note that this value is per `identifier_type`, i.e. a value of 10 will calculate 10 host scores and 10 user scores, if available. To avoid missed data, keep this value consistent while paginating through scores.
default: 1000
type: number

KibanaDate:
type: string
example: '2017-07-21T17:32:28Z'

DateRange:
description: Defines the time period on which risk inputs will be filtered.
type: object
required:
- start
- end
properties:
start:
$ref: '#/components/schemas/KibanaDate'
end:
$ref: '#/components/schemas/KibanaDate'

IdentifierType:
type: string
enum:
- host
- user

RiskScoreInput:
description: A generic representation of a document contributing to a Risk Score.
type: object
properties:
id:
type: string
example: 91a93376a507e86cfbf282166275b89f9dbdb1f0be6c8103c6ff2909ca8e1a1c
description: The unique identifier (`_id`) of the original source document
index:
type: string
example: .internal.alerts-security.alerts-default-000001
description: The unique index (`_index`) of the original source document
category:
type: string
example: category_1
description: The risk category of the risk input document.
description:
type: string
example: 'Generated from Detection Engine Rule: Malware Prevention Alert'
description: A human-readable description of the risk input document.
risk_score:
type: number
format: double
minimum: 0
maximum: 100
description: The weighted risk score of the risk input document.
timestamp:
type: string
example: '2017-07-21T17:32:28Z'
description: The @timestamp of the risk input document.

RiskScore:
type: object
required:
- '@timestamp'
- id_field
- id_value
- calculated_level
- calculated_score
- calculated_score_norm
- category_1_score
- category_1_count
- inputs
properties:
'@timestamp':
type: string
format: 'date-time'
example: '2017-07-21T17:32:28Z'
description: The time at which the risk score was calculated.
id_field:
type: string
example: 'host.name'
description: The identifier field defining this risk score. Coupled with `id_value`, uniquely identifies the entity being scored.
id_value:
type: string
example: 'example.host'
description: The identifier value defining this risk score. Coupled with `id_field`, uniquely identifies the entity being scored.
calculated_level:
type: string
example: 'Critical'
description: Lexical description of the entity's risk.
calculated_score:
type: number
format: double
description: The raw numeric value of the given entity's risk score.
calculated_score_norm:
type: number
format: double
minimum: 0
maximum: 100
description: The normalized numeric value of the given entity's risk score. Useful for comparing with other entities.
category_1_score:
type: number
format: double
description: The contribution of Category 1 to the overall risk score (`calculated_score`). Category 1 contains Detection Engine Alerts.
category_1_count:
type: number
format: integer
description: The number of risk input documents that contributed to the Category 1 score (`category_1_score`).
inputs:
type: array
description: A list of the highest-risk documents contributing to this risk score. Useful for investigative purposes.
items:
$ref: '#/components/schemas/RiskScoreInput'



RiskScoreWeight:
description: "Configuration used to tune risk scoring. Weights can be used to change the score contribution of risk inputs for hosts and users at both a global level and also for Risk Input categories (e.g. 'category_1')."
type: object
required:
- type
properties:
type:
type: string
value:
type: string
host:
type: number
format: double
minimum: 0
maximum: 1
user:
type: number
format: double
minimum: 0
maximum: 1
example:
type: 'risk_category'
value: 'category_1'
host: 0.8
user: 0.4

RiskScoreWeights:
description: 'A list of weights to be applied to the scoring calculation.'
type: array
items:
$ref: '#/components/schemas/RiskScoreWeight'
example:
- type: 'risk_category'
value: 'category_1'
host: 0.8
user: 0.4
- type: 'global_identifier'
host: 0.5
user: 0.1

RiskEngineInitStep:
type: object
required:
- type
- success
properties:
type:
type: string
success:
type: boolean
error:
type: string
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { z } from 'zod';

/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*/

import { DateRange } from '../common/common.gen';

export type RiskEngineSettingsResponse = z.infer<typeof RiskEngineSettingsResponse>;
export const RiskEngineSettingsResponse = z.object({
range: DateRange.optional(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
openapi: 3.0.0
info:
version: 1.0.0
title: Risk Scoring API
description: These APIs allow the consumer to manage Entity Risk Scores within Entity Analytics.
servers:
- url: 'http://{kibana_host}:{port}'
variables:
kibana_host:
default: localhost
port:
default: '5601'

paths:
/engine/settings:
get:
operationId: RiskEngineSettingsGet
summary: Get the settings of the Risk Engine
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/RiskEngineSettingsResponse'

components:
schemas:
RiskEngineSettingsResponse:
type: object
properties:
range:
$ref: '../common/common.schema.yaml#/components/schemas/DateRange'
Loading

0 comments on commit 3fea5d4

Please sign in to comment.