From 6fa0aae932cc56a31e1572009f96578ebdbf159e Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Thu, 1 Jul 2021 17:08:13 -0400 Subject: [PATCH] [RAC] [RBAC] force rule data client to register features (#20) * force any plugin registering rules to register the feature id into the master list which maps feature id to index names * javascript is not python * favor keyof instead of typeof as const, removes ts-expect-error * updates typedocs * adds rbac utils to utils folder and updates typedocs * featureIds is already string[] and do not trust input for type guard --- .../authorization/alerting_authorization.ts | 2 +- x-pack/plugins/apm/server/plugin.ts | 3 +- .../alerts_client/classes/alertsclient.md | 58 +++++++++---------- .../interfaces/constructoroptions.md | 19 ++---- .../alerts_client/interfaces/updateoptions.md | 35 ++++++----- .../server/alert_data_client/alerts_client.ts | 15 ++--- .../server/routes/get_alert_index.ts | 9 +-- .../server/rule_data_client/types.ts | 9 +++ .../rule_registry/server/utils/rbac.ts | 22 +++++++ 9 files changed, 93 insertions(+), 79 deletions(-) create mode 100644 x-pack/plugins/rule_registry/server/utils/rbac.ts diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts index de49cdd370585..655e1f7ce095c 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts @@ -143,7 +143,7 @@ export class AlertingAuthorization { * used by the RAC/Alerts client */ public async getAugmentRuleTypesWithAuthorization( - featureIds: string[], + featureIds: readonly string[], operations: Array, authorizationEntity: AlertingAuthorizationEntity ): Promise<{ diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index e617ed0510a8d..24d6fd80c15fb 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -18,7 +18,8 @@ import { import { mapValues, once } from 'lodash'; import { TECHNICAL_COMPONENT_TEMPLATE_NAME } from '../../rule_registry/common/assets'; import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map'; -import { APMConfig, APMXPackConfig } from '.'; +import { RuleDataClient } from '../../rule_registry/server'; +import { APMConfig, APMXPackConfig, APM_SERVER_FEATURE_ID } from '.'; import { mergeConfigs } from './index'; import { UI_SETTINGS } from '../../../../src/plugins/data/common'; import { APM_FEATURE, registerFeaturesUsage } from './feature'; diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md b/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md index 1ff8499213add..9b639829a9f5f 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/classes/alertsclient.md @@ -18,14 +18,13 @@ on alerts as data. - [authorization](alertsclient.md#authorization) - [esClient](alertsclient.md#esclient) - [logger](alertsclient.md#logger) -- [ruleDataService](alertsclient.md#ruledataservice) ### Methods - [fetchAlert](alertsclient.md#fetchalert) - [get](alertsclient.md#get) - [getAlertsIndex](alertsclient.md#getalertsindex) -- [getFullAssetName](alertsclient.md#getfullassetname) +- [getAuthorizedAlertsIndices](alertsclient.md#getauthorizedalertsindices) - [update](alertsclient.md#update) ## Constructors @@ -42,7 +41,7 @@ on alerts as data. #### Defined in -[alerts_client.ts:56](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L56) +[rule_registry/server/alert_data_client/alerts_client.ts:59](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L59) ## Properties @@ -52,7 +51,7 @@ on alerts as data. #### Defined in -[alerts_client.ts:53](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L53) +[rule_registry/server/alert_data_client/alerts_client.ts:57](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L57) ___ @@ -62,7 +61,7 @@ ___ #### Defined in -[alerts_client.ts:54](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L54) +[rule_registry/server/alert_data_client/alerts_client.ts:58](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L58) ___ @@ -72,7 +71,7 @@ ___ #### Defined in -[alerts_client.ts:55](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L55) +[rule_registry/server/alert_data_client/alerts_client.ts:59](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L59) ___ @@ -82,23 +81,13 @@ ___ #### Defined in -[alerts_client.ts:52](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L52) - -___ - -### ruleDataService - -• `Private` `Readonly` **ruleDataService**: `PublicMethodsOf` - -#### Defined in - -[alerts_client.ts:56](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L56) +[rule_registry/server/alert_data_client/alerts_client.ts:56](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L56) ## Methods ### fetchAlert -▸ `Private` **fetchAlert**(`__namedParameters`): `Promise`\>\> +▸ `Private` **fetchAlert**(`__namedParameters`): `Promise` #### Parameters @@ -108,11 +97,11 @@ ___ #### Returns -`Promise`\>\> +`Promise` #### Defined in -[alerts_client.ts:83](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L83) +[rule_registry/server/alert_data_client/alerts_client.ts:79](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L79) ___ @@ -132,47 +121,54 @@ ___ #### Defined in -[alerts_client.ts:108](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L108) +[rule_registry/server/alert_data_client/alerts_client.ts:108](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L108) ___ ### getAlertsIndex -▸ **getAlertsIndex**(`featureIds`): `Promise` +▸ **getAlertsIndex**(`featureIds`, `operations`): `Promise`<`Object`\> #### Parameters | Name | Type | | :------ | :------ | | `featureIds` | `string`[] | +| `operations` | (`ReadOperations` \| `WriteOperations`)[] | #### Returns -`Promise` +`Promise`<`Object`\> #### Defined in -[alerts_client.ts:76](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L76) +[rule_registry/server/alert_data_client/alerts_client.ts:68](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L68) ___ -### getFullAssetName +### getAuthorizedAlertsIndices + +▸ **getAuthorizedAlertsIndices**(`featureIds`): `Promise` + +#### Parameters -▸ **getFullAssetName**(): `string` +| Name | Type | +| :------ | :------ | +| `featureIds` | `string`[] | #### Returns -`string` +`Promise` #### Defined in -[alerts_client.ts:72](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L72) +[rule_registry/server/alert_data_client/alerts_client.ts:200](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L200) ___ ### update -▸ **update**(`__namedParameters`): `Promise`\>\> +▸ **update**(`__namedParameters`): `Promise`<`Object`\> #### Type parameters @@ -188,8 +184,8 @@ ___ #### Returns -`Promise`\>\> +`Promise`<`Object`\> #### Defined in -[alerts_client.ts:146](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L146) +[rule_registry/server/alert_data_client/alerts_client.ts:146](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L146) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md index 5cf1539c52878..e3dbc6b2c2354 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/constructoroptions.md @@ -10,7 +10,6 @@ - [authorization](constructoroptions.md#authorization) - [esClient](constructoroptions.md#esclient) - [logger](constructoroptions.md#logger) -- [ruleDataService](constructoroptions.md#ruledataservice) ## Properties @@ -20,7 +19,7 @@ #### Defined in -[alerts_client.ts:26](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L26) +[rule_registry/server/alert_data_client/alerts_client.ts:34](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L34) ___ @@ -30,7 +29,7 @@ ___ #### Defined in -[alerts_client.ts:25](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L25) +[rule_registry/server/alert_data_client/alerts_client.ts:33](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L33) ___ @@ -40,7 +39,7 @@ ___ #### Defined in -[alerts_client.ts:27](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L27) +[rule_registry/server/alert_data_client/alerts_client.ts:35](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L35) ___ @@ -50,14 +49,4 @@ ___ #### Defined in -[alerts_client.ts:24](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L24) - -___ - -### ruleDataService - -• **ruleDataService**: `PublicMethodsOf` - -#### Defined in - -[alerts_client.ts:28](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L28) +[rule_registry/server/alert_data_client/alerts_client.ts:32](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L32) diff --git a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md index 3ec99762c78cc..fbc0991635000 100644 --- a/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md +++ b/x-pack/plugins/rule_registry/docs/alerts_client/interfaces/updateoptions.md @@ -12,25 +12,20 @@ ### Properties -- [data](updateoptions.md#data) +- [\_version](updateoptions.md#_version) - [id](updateoptions.md#id) -- [indexName](updateoptions.md#indexname) +- [index](updateoptions.md#index) +- [status](updateoptions.md#status) ## Properties -### data +### \_version -• **data**: `Object` - -#### Type declaration - -| Name | Type | -| :------ | :------ | -| `status` | `string` | +• **\_version**: `undefined` \| `string` #### Defined in -[alerts_client.ts:33](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L33) +[rule_registry/server/alert_data_client/alerts_client.ts:41](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L41) ___ @@ -40,14 +35,24 @@ ___ #### Defined in -[alerts_client.ts:32](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L32) +[rule_registry/server/alert_data_client/alerts_client.ts:39](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L39) + +___ + +### index + +• **index**: `string` + +#### Defined in + +[rule_registry/server/alert_data_client/alerts_client.ts:42](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L42) ___ -### indexName +### status -• **indexName**: `string` +• **status**: `string` #### Defined in -[alerts_client.ts:37](https://github.com/dhurley14/kibana/blob/25bf227f8c6/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L37) +[rule_registry/server/alert_data_client/alerts_client.ts:40](https://github.com/dhurley14/kibana/blob/d2173f5090e/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts#L40) diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index e36e97b7a252a..d32e09d32de13 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -18,6 +18,7 @@ import { alertAuditEvent, AlertAuditAction } from './audit_events'; import { AuditLogger } from '../../../security/server'; import { ALERT_STATUS, OWNER, RULE_ID } from '../../common/technical_rule_data_field_names'; import { ParsedTechnicalFields } from '../../common/parse_technical_fields'; +import { mapConsumerToIndexName, validFeatureIds, isValidFeatureId } from '../utils/rbac'; // TODO: Fix typings https://github.com/elastic/kibana/issues/101776 type NonNullableProps = Omit & @@ -69,7 +70,7 @@ export class AlertsClient { operations: Array ) { return this.authorization.getAugmentRuleTypesWithAuthorization( - featureIds.length !== 0 ? featureIds : ['apm', 'siem'], + featureIds.length !== 0 ? featureIds : validFeatureIds, operations, AlertingAuthorizationEntity.Alert ); @@ -206,20 +207,16 @@ export class AlertsClient { // As long as the user can read a minimum of one type of rule type produced by the provided feature, // the user should be provided that features' alerts index. // Limiting which alerts that user can read on that index will be done via the findAuthorizationFilter - const authorizedFeatures = new Set(); + const authorizedFeatures = new Set(); for (const ruleType of augmentedRuleTypes.authorizedRuleTypes) { authorizedFeatures.add(ruleType.producer); } const toReturn = Array.from(authorizedFeatures).flatMap((feature) => { - switch (feature) { - case 'apm': - return '.alerts-observability-apm'; - case 'siem': - return ['.alerts-security-solution', '.siem-signals']; - default: - return []; + if (isValidFeatureId(feature)) { + return mapConsumerToIndexName[feature]; } + return []; }); return toReturn; diff --git a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts index bfafec919ebb2..b8b181a493cec 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_alert_index.ts @@ -11,6 +11,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { RacRequestHandlerContext } from '../types'; import { BASE_RAC_ALERTS_API_PATH } from '../../common/constants'; +import { validFeatureIds } from '../utils/rbac'; export const getAlertsIndexRoute = (router: IRouter) => { router.get( @@ -22,14 +23,9 @@ export const getAlertsIndexRoute = (router: IRouter) = }, }, async (context, request, response) => { - const APM_SERVER_FEATURE_ID = 'apm'; - const SERVER_APP_ID = 'siem'; try { const alertsClient = await context.rac.getAlertsClient(); - const indexName = await alertsClient.getAuthorizedAlertsIndices([ - APM_SERVER_FEATURE_ID, - SERVER_APP_ID, - ]); + const indexName = await alertsClient.getAuthorizedAlertsIndices(validFeatureIds); return response.ok({ body: { index_name: indexName }, }); @@ -52,7 +48,6 @@ export const getAlertsIndexRoute = (router: IRouter) = }) ), }); - // return response.custom; } } ); diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts index 46a37abcd1ffc..17d71e7354af4 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts @@ -11,6 +11,7 @@ import { ElasticsearchClient } from 'kibana/server'; import { FieldDescriptor } from 'src/plugins/data/server'; import { ESSearchRequest, ESSearchResponse } from 'src/core/types/elasticsearch'; import { TechnicalRuleDataFieldName } from '../../common/technical_rule_data_field_names'; +import { ValidFeatureId } from '../utils/rbac'; export interface RuleDataReader { search( @@ -37,9 +38,17 @@ export interface IRuleDataClient { createOrUpdateWriteTarget(options: { namespace?: string }): Promise; } +/** + * The purpose of the `feature` param is to force the user to update + * the data structure which contains the mapping of consumers to alerts + * as data indices. The idea is it is typed such that it forces the + * user to go to the code and modify it. At least until a better system + * is put in place or we move the alerts as data client out of rule registry. + */ export interface RuleDataClientConstructorOptions { getClusterClient: () => Promise; isWriteEnabled: boolean; ready: () => Promise; alias: string; + feature: ValidFeatureId; } diff --git a/x-pack/plugins/rule_registry/server/utils/rbac.ts b/x-pack/plugins/rule_registry/server/utils/rbac.ts new file mode 100644 index 0000000000000..a7e3d264f4bca --- /dev/null +++ b/x-pack/plugins/rule_registry/server/utils/rbac.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * registering a new instance of the rule data client + * in a new plugin will require updating the below data structure + * to include the index name where the alerts as data will be written to. + */ +export const mapConsumerToIndexName = { + apm: '.alerts-observability-apm', + observability: '.alerts-observability', + siem: ['.alerts-security-solution', '.siem-signals'], +}; +export type ValidFeatureId = keyof typeof mapConsumerToIndexName; + +export const validFeatureIds = Object.keys(mapConsumerToIndexName); +export const isValidFeatureId = (a: unknown): a is ValidFeatureId => + typeof a === 'string' && validFeatureIds.includes(a);