Skip to content

Commit

Permalink
[Security Solution] Add coverage overview dashboard API contract (#15…
Browse files Browse the repository at this point in the history
…9993)

**Addresses:** #158202

## Summary

This PR defines Coverage Overview Dashboard API's request and response type definitions and adds UI domain models.
  • Loading branch information
maximpn authored Jun 22, 2023
1 parent c5d330b commit 7186684
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 * as t from 'io-ts';
import { enumeration, NonEmptyArray, NonEmptyString } from '@kbn/securitysolution-io-ts-types';

/**
* Rule activity (status) filter applicable to two groups of rules
* - installed from a Fleet package, custom and customized which are installed but customized later on which
* can be either enabled or disabled
* - available to be installed from a Fleet package rules
*/
export enum CoverageOverviewRuleActivity {
/**
* Enabled rules (installed from a Fleet package, custom or customized)
*/
Enabled = 'enabled',
/**
* Disabled rules (installed from a Fleet package, custom or customized)
*/
Disabled = 'disabled',
/**
* Available to be installed from a Fleet package rules (Elastic prebuilt rules)
*/
Available = 'available',
}
export const CoverageOverviewRuleActivitySchema = enumeration(
'CoverageOverviewRuleActivity',
CoverageOverviewRuleActivity
);

/**
* Rule source (origin) filter representing from where the rules came from
*/
export enum CoverageOverviewRuleSource {
/**
* Rules installed from a Fleet package of Elastic prebuilt rules
*/
Prebuilt = 'prebuilt',
/**
* Rules created manually
*/
Custom = 'custom',
/**
* Rules installed from a Fleet package but modified later on
*/
Customized = 'customized',
}
export const CoverageOverviewRuleSourceSchema = enumeration(
'CoverageOverviewRuleSource',
CoverageOverviewRuleSource
);

export type CoverageOverviewFilter = t.TypeOf<typeof CoverageOverviewFilter>;
export const CoverageOverviewFilter = t.partial({
/**
* A search term to filter the response by rule name, index pattern, MITRE ATT&CK™ tactic or technique
*
* @example "Defense Evasion" or "TA0005"
*/
search_term: NonEmptyString,
/**
* An activity filter representing an array combined of CoverageOverviewRuleActivity values to include only specified rules in the response
*/
activity: NonEmptyArray(CoverageOverviewRuleActivitySchema),
/**
* A source filter representing an array combined of CoverageOverviewRuleSource values to include only specified rules in the response
*/
source: NonEmptyArray(CoverageOverviewRuleSourceSchema),
});

export type CoverageOverviewRequestBody = t.TypeOf<typeof CoverageOverviewRequestBody>;
export const CoverageOverviewRequestBody = t.partial({
filter: CoverageOverviewFilter,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 * as t from 'io-ts';
import { NonEmptyArray } from '@kbn/securitysolution-io-ts-types';
import { CoverageOverviewRuleActivitySchema } from './request_schema';

export type CoverageOverviewRuleAttributes = t.TypeOf<typeof CoverageOverviewRuleAttributes>;
export const CoverageOverviewRuleAttributes = t.type({
name: t.string,
activity: CoverageOverviewRuleActivitySchema,
});

export type CoverageOverviewResponse = t.TypeOf<typeof CoverageOverviewResponse>;
export const CoverageOverviewResponse = t.exact(
t.type({
/**
* Map having (tacticId, techniqueId or subtechniqueId) as the key and an array of rule ids as the value
*/
coverage: t.record(t.string, NonEmptyArray(t.string)),
/**
* Array of unmapped rule ids
*/
unmapped_rule_ids: t.array(t.string),
/**
* Map having ruleId as the key and coverage overview rule data as the value
*/
rules_data: t.record(t.string, CoverageOverviewRuleAttributes),
})
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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 { CoverageOverviewMitreTactic } from './mitre_tactic';
import type { CoverageOverviewRule } from './rule';

/**
* Coverage overview dashboard domain model
*/
export interface CoverageOverviewDashboard {
/**
* MITRE ATT&CK coverage
*/
mitreTactics: CoverageOverviewMitreTactic[];
/**
* Unmapped rules
*/
unmappedRules: {
enabledRules: CoverageOverviewRule[];
disabledRules: CoverageOverviewRule[];
availableRules: CoverageOverviewRule[];
};
/**
* Total metrics
*/
metrics: {
totalRulesCount: number;
totalEnabledRulesCount: number;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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 { CoverageOverviewRule } from './rule';
import type { CoverageOverviewMitreTechnique } from './mitre_technique';

export interface CoverageOverviewMitreTactic {
name: string;
/**
* An url leading to the tactic's page
*/
reference: string;
/**
* A list if techniques associated with this tactic
*/
techniques: CoverageOverviewMitreTechnique[];
enabledRules: CoverageOverviewRule[];
disabledRules: CoverageOverviewRule[];
availableRules: CoverageOverviewRule[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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 { CoverageOverviewRule } from './rule';

export interface CoverageOverviewMitreTechnique {
name: string;
/**
* An url leading to the technique's page
*/
reference: string;
/**
* A number of covered subtechniques (having at least one enabled rule associated with it)
*/
numOfCoveredSubtechniques: number;
/**
* A total number of subtechniques associated with this technique
*/
numOfSubtechniques: number;
enabledRules: CoverageOverviewRule[];
disabledRules: CoverageOverviewRule[];
availableRules: CoverageOverviewRule[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 { RuleObjectId } from '../../../../../common/detection_engine/rule_schema';

export interface CoverageOverviewRule {
id: RuleObjectId; // rule SO's ids (not ruleId)
name: string;
}

0 comments on commit 7186684

Please sign in to comment.