From 99463c7a0d5e74b08791dfc4a6f9fbdbea14caee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:03:24 +0000 Subject: [PATCH] Revert "[Infra][ECO] Fix RBAC issue in hosts view" (#202418) Reverts elastic/kibana#199841 --- .../apm/server/assistant_functions/index.ts | 5 +- .../apm/server/plugin.ts | 11 +++- .../apm_routes/register_apm_server_routes.ts | 5 +- .../index.ts | 3 +- .../fleet/register_fleet_policy_callbacks.ts | 8 +-- .../apm_data_access/kibana.jsonc | 4 +- .../apm_data_access/server/index.ts | 1 + .../server/lib/check_privileges.ts | 42 ++++++++++++++++ .../apm_data_access/server/plugin.ts | 50 ++++++++++++++----- .../apm_data_access/server/types.ts | 18 +++++-- .../apm_data_access/tsconfig.json | 3 ++ .../lib/helpers/get_apm_data_access_client.ts | 12 +++-- .../infra/server/routes/infra/index.ts | 6 ++- .../server/routes/infra/lib/helpers/query.ts | 14 ++---- .../server/routes/infra/lib/host/get_hosts.ts | 1 - .../routes/infra/lib/host/get_hosts_count.ts | 8 +-- .../infra/server/routes/infra/lib/types.ts | 2 +- .../infra/server/routes/services/index.ts | 10 ++++ .../profiling/server/routes/apm.ts | 4 +- 19 files changed, 158 insertions(+), 49 deletions(-) create mode 100644 x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts diff --git a/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts b/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts index 1dff57cef6602..6a65e6126ff22 100644 --- a/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/assistant_functions/index.ts @@ -72,7 +72,10 @@ export function registerAssistantFunctions({ ruleDataClient, plugins, getApmIndices: async () => { - const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await resources.context.core; + const apmIndices = await plugins.apmDataAccess.setup.getApmIndices( + coreContext.savedObjects.client + ); return apmIndices; }, }; diff --git a/x-pack/plugins/observability_solution/apm/server/plugin.ts b/x-pack/plugins/observability_solution/apm/server/plugin.ts index de49ebcebf8b0..1142a5c69a51f 100644 --- a/x-pack/plugins/observability_solution/apm/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm/server/plugin.ts @@ -16,6 +16,7 @@ import { registerAssistantFunctions } from './assistant_functions'; import { registerDeprecations } from './deprecations'; import { APM_FEATURE, registerFeaturesUsage } from './feature'; import { createApmTelemetry } from './lib/apm_telemetry'; +import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client'; import { APM_RULE_TYPE_ALERT_CONTEXT, apmRuleTypeAlertFieldMap, @@ -114,6 +115,13 @@ export class APMPlugin }; }) as APMRouteHandlerResources['plugins']; + const apmIndicesPromise = (async () => { + const coreStart = await getCoreStart(); + const soClient = await getInternalSavedObjectsClient(coreStart); + const { getApmIndices } = plugins.apmDataAccess; + return getApmIndices(soClient); + })(); + // This if else block will go away in favour of removing Home Tutorial Integration // Ideally we will directly register a custom integration and pass the configs // for cloud, onPrem and Serverless so that the actual component can take @@ -121,8 +129,7 @@ export class APMPlugin if (currentConfig.serverlessOnboarding && plugins.customIntegrations) { plugins.customIntegrations?.registerCustomIntegration(apmTutorialCustomIntegration); } else { - plugins.apmDataAccess - .getApmIndices() + apmIndicesPromise .then((apmIndices) => { plugins.home?.tutorials.registerTutorial( tutorialProvider({ diff --git a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts index 59c9cdac2df83..197b4259d3f09 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.ts @@ -115,7 +115,10 @@ export function registerRoutes({ ); const getApmIndices = async () => { - const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await context.core; + const apmIndices = await plugins.apmDataAccess.setup.getApmIndices( + coreContext.savedObjects.client + ); return apmIndices; }; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts index f28e3f9df8570..84e51675233c9 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts @@ -38,7 +38,8 @@ export const getAlertDetailsContextHandler = ( return async (requestContext, query) => { const resources = { getApmIndices: async () => { - return resourcePlugins.apmDataAccess.setup.getApmIndices(); + const coreContext = await requestContext.core; + return resourcePlugins.apmDataAccess.setup.getApmIndices(coreContext.savedObjects.client); }, request: requestContext.request, params: { query: { _inspect: false } }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts b/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts index 9d00c50b4ab48..2237548f2d325 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/fleet/register_fleet_policy_callbacks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { Logger, CoreStart } from '@kbn/core/server'; +import { Logger, CoreStart, SavedObjectsClientContract } from '@kbn/core/server'; import { FleetStartContract, PostPackagePolicyCreateCallback, @@ -22,6 +22,7 @@ import { SOURCE_MAP_API_KEY_PATH, } from './get_package_policy_decorators'; import { createInternalESClient } from '../../lib/helpers/create_es_client/create_internal_es_client'; +import { getInternalSavedObjectsClient } from '../../lib/helpers/get_internal_saved_objects_client'; import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes'; export async function registerFleetPolicyCallbacks({ @@ -148,7 +149,7 @@ function onPackagePolicyCreateOrUpdate({ coreStart, }: { fleetPluginStart: FleetStartContract; - getApmIndices: () => Promise; + getApmIndices: (soClient: SavedObjectsClientContract) => Promise; coreStart: CoreStart; }): PutPackagePolicyUpdateCallback & PostPackagePolicyCreateCallback { return async (packagePolicy) => { @@ -157,7 +158,8 @@ function onPackagePolicyCreateOrUpdate({ } const { asInternalUser } = coreStart.elasticsearch.client; - const apmIndices = await getApmIndices(); + const savedObjectsClient = await getInternalSavedObjectsClient(coreStart); + const apmIndices = await getApmIndices(savedObjectsClient); const internalESClient = await createInternalESClient({ debug: false, diff --git a/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc b/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc index 42ffe16acc265..4eb0859691ba1 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc +++ b/x-pack/plugins/observability_solution/apm_data_access/kibana.jsonc @@ -15,7 +15,9 @@ "requiredPlugins": [ "data" ], - "optionalPlugins": [], + "optionalPlugins": [ + "security" + ], "requiredBundles": [] } } \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/index.ts b/x-pack/plugins/observability_solution/apm_data_access/server/index.ts index 7afaa656591c4..6b6385ded4ce4 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/index.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/index.ts @@ -91,6 +91,7 @@ export type { APMEventESSearchRequest, APMLogEventESSearchRequest, DocumentSourcesRequest, + ApmDataAccessPrivilegesCheck, HostNamesRequest, GetDocumentTypeParams, } from './types'; diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts b/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts new file mode 100644 index 0000000000000..6b8e734a10b4e --- /dev/null +++ b/x-pack/plugins/observability_solution/apm_data_access/server/lib/check_privileges.ts @@ -0,0 +1,42 @@ +/* + * 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 { KibanaRequest } from '@kbn/core-http-server'; +import { SecurityPluginStart } from '@kbn/security-plugin-types-server'; +import { mapValues } from 'lodash'; +import { APMIndices } from '..'; + +export interface ApmDataAccessPrivilegesCheck { + request: KibanaRequest; + security?: SecurityPluginStart; + getApmIndices: () => Promise; +} + +export async function checkPrivileges({ + request, + getApmIndices, + security, +}: ApmDataAccessPrivilegesCheck) { + const authorization = security?.authz; + if (!authorization) { + return true; + } + + const [apmIndices, checkPrivilegesFn] = await Promise.all([ + getApmIndices(), + authorization.checkPrivilegesDynamicallyWithRequest(request), + ]); + + const { hasAllRequested } = await checkPrivilegesFn({ + elasticsearch: { + cluster: [], + index: mapValues(apmIndices, () => ['read']), + }, + }); + + return hasAllRequested; +} diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts b/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts index 6bf684985583a..680079d080c82 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/plugin.ts @@ -5,19 +5,32 @@ * 2.0. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server'; +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + SavedObjectsClientContract, + Logger, +} from '@kbn/core/server'; import { APMDataAccessConfig } from '.'; -import { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types'; +import { + ApmDataAccessPluginSetup, + ApmDataAccessPluginStart, + ApmDataAccessServerDependencies, +} from './types'; import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware'; import { apmIndicesSavedObjectDefinition, getApmIndicesSavedObject, } from './saved_objects/apm_indices'; import { getServices } from './services/get_services'; +import { ApmDataAccessPrivilegesCheck, checkPrivileges } from './lib/check_privileges'; export class ApmDataAccessPlugin implements Plugin { + public server?: ApmDataAccessServerDependencies; public config: APMDataAccessConfig; public logger: Logger; @@ -26,34 +39,45 @@ export class ApmDataAccessPlugin this.logger = initContext.logger.get(); } + getApmIndices = async (savedObjectsClient: SavedObjectsClientContract) => { + const apmIndicesFromSavedObject = await getApmIndicesSavedObject(savedObjectsClient); + return { ...this.config.indices, ...apmIndicesFromSavedObject }; + }; + public setup(core: CoreSetup): ApmDataAccessPluginSetup { // register saved object core.savedObjects.registerType(apmIndicesSavedObjectDefinition); - const getApmIndices = async () => { - const [coreStart] = await core.getStartServices(); - const soClient = await coreStart.savedObjects.createInternalRepository(); - - const apmIndicesFromSavedObject = await getApmIndicesSavedObject(soClient); - return { ...this.config.indices, ...apmIndicesFromSavedObject }; - }; - // expose return { apmIndicesFromConfigFile: this.config.indices, - getApmIndices, + getApmIndices: this.getApmIndices, getServices, }; } - public start(core: CoreStart) { + public start(core: CoreStart, plugins: ApmDataAccessServerDependencies) { // TODO: remove in 9.0 migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger: this.logger }).catch((e) => { this.logger.error('Failed to run migration making APM indices space aware'); this.logger.error(e); }); - return {}; + const getApmIndicesWithInternalUserFn = async () => { + const soClient = core.savedObjects.createInternalRepository(); + return this.getApmIndices(soClient); + }; + + const startServices = { + hasPrivileges: ({ request }: Pick) => + checkPrivileges({ + request, + getApmIndices: getApmIndicesWithInternalUserFn, + security: plugins.security, + }), + }; + + return { ...startServices }; } public stop() {} diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/types.ts b/x-pack/plugins/observability_solution/apm_data_access/server/types.ts index 968590e780ee8..f10c23c1fd994 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/types.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/types.ts @@ -5,17 +5,28 @@ * 2.0. */ +import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; +import type { SecurityPluginStart } from '@kbn/security-plugin-types-server'; import type { APMIndices } from '.'; import { getServices } from './services/get_services'; +import type { ApmDataAccessPrivilegesCheck } from './lib/check_privileges'; export interface ApmDataAccessPluginSetup { apmIndicesFromConfigFile: APMIndices; - getApmIndices: () => Promise; + getApmIndices: (soClient: SavedObjectsClientContract) => Promise; getServices: typeof getServices; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface ApmDataAccessPluginStart {} +export interface ApmDataAccessServerDependencies { + security?: SecurityPluginStart; +} + +export interface ApmDataAccessPluginStart { + hasPrivileges: (params: Pick) => Promise; +} +export interface ApmDataAccessServerDependencies { + security?: SecurityPluginStart; +} export type ApmDataAccessServices = ReturnType; export type { ApmDataAccessServicesParams } from './services/get_services'; @@ -27,3 +38,4 @@ export type { APMEventESSearchRequest, APMLogEventESSearchRequest, } from './lib/helpers'; +export type { ApmDataAccessPrivilegesCheck }; diff --git a/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json b/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json index f7ac83af0922e..d4c38fddf967e 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json +++ b/x-pack/plugins/observability_solution/apm_data_access/tsconfig.json @@ -9,6 +9,7 @@ "@kbn/config-schema", "@kbn/core", "@kbn/i18n", + "@kbn/core-saved-objects-api-server", "@kbn/data-plugin", "@kbn/inspector-plugin", "@kbn/observability-plugin", @@ -17,6 +18,8 @@ "@kbn/apm-types", "@kbn/core-http-server-mocks", "@kbn/apm-utils", + "@kbn/core-http-server", + "@kbn/security-plugin-types-server", "@kbn/utility-types", "@kbn/elastic-agent-utils", "@kbn/observability-utils-common" diff --git a/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_apm_data_access_client.ts b/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_apm_data_access_client.ts index dcf63e01b7e93..e99d57eb4d6c8 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_apm_data_access_client.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/helpers/get_apm_data_access_client.ts @@ -27,17 +27,23 @@ export const getApmDataAccessClient = ({ context: InfraPluginRequestHandlerContext; request: KibanaRequest; }) => { + const hasPrivileges = async () => { + const apmDataAccessStart = await libs.plugins.apmDataAccess.start(); + return apmDataAccessStart.hasPrivileges({ request }); + }; + const getServices = async () => { const apmDataAccess = libs.plugins.apmDataAccess.setup; const coreContext = await context.core; - const { uiSettings, elasticsearch } = coreContext; + const { savedObjects, uiSettings, elasticsearch } = coreContext; + const savedObjectsClient = savedObjects.client; const esClient = elasticsearch.client.asCurrentUser; const uiSettingsClient = uiSettings.client; const [apmIndices, includeFrozen] = await Promise.all([ - apmDataAccess.getApmIndices(), + apmDataAccess.getApmIndices(savedObjectsClient), uiSettingsClient.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), ]); @@ -80,5 +86,5 @@ export const getApmDataAccessClient = ({ }; }; - return { getServices }; + return { hasPrivileges, getServices }; }; diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts index 3f91a034c8103..1b720eeb31869 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/index.ts @@ -41,11 +41,12 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => { try { const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); const [infraMetricsClient, alertsClient, apmDataAccessServices] = await Promise.all([ getInfraMetricsClient({ request, libs, context }), getInfraAlertsClient({ libs, request }), - apmDataAccessClient.getServices(), + hasApmPrivileges ? apmDataAccessClient.getServices() : undefined, ]); const hosts = await getHosts({ @@ -96,10 +97,11 @@ export const initInfraAssetRoutes = (libs: InfraBackendLibs) => { try { const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); const [infraMetricsClient, apmDataAccessServices] = await Promise.all([ getInfraMetricsClient({ request, libs, context }), - apmDataAccessClient.getServices(), + hasApmPrivileges ? apmDataAccessClient.getServices() : undefined, ]); const count = await getHostsCount({ diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts index 52da69cd7c008..570c1499f3b74 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/helpers/query.ts @@ -9,7 +9,6 @@ import { findInventoryModel } from '@kbn/metrics-data-access-plugin/common'; import { termQuery } from '@kbn/observability-plugin/server'; import { ApmDocumentType, type TimeRangeMetadata } from '@kbn/apm-data-access-plugin/common'; import { estypes } from '@elastic/elasticsearch'; -import { castArray } from 'lodash'; import type { ApmDataAccessServicesWrapper } from '../../../../lib/helpers/get_apm_data_access_client'; import { EVENT_MODULE, @@ -18,16 +17,12 @@ import { } from '../../../../../common/constants'; import type { InfraAssetMetricType } from '../../../../../common/http_api/infra'; -export const getFilterByIntegration = ( - integration: typeof SYSTEM_INTEGRATION, - extraFilter: estypes.QueryDslQueryContainer[] = [] -) => { +export const getFilterByIntegration = (integration: typeof SYSTEM_INTEGRATION) => { return { bool: { should: [ ...termQuery(EVENT_MODULE, integration), ...termQuery(METRICSET_MODULE, integration), - ...extraFilter, ], minimum_should_match: 1, }, @@ -68,6 +63,7 @@ export const getDocumentsFilter = async ({ from: number; to: number; }) => { + const filters: estypes.QueryDslQueryContainer[] = [getFilterByIntegration('system')]; const apmDocumentsFilter = apmDataAccessServices && apmDocumentSources ? await getApmDocumentsFilter({ @@ -78,9 +74,9 @@ export const getDocumentsFilter = async ({ }) : undefined; - const filters: estypes.QueryDslQueryContainer[] = [ - getFilterByIntegration('system', apmDocumentsFilter && castArray(apmDocumentsFilter)), - ]; + if (apmDocumentsFilter) { + filters.push(apmDocumentsFilter); + } return filters; }; diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts index 63fef5d438b00..bb5bd51cfe1f9 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts.ts @@ -49,7 +49,6 @@ export const getHosts = async ({ const [hostMetricsResponse, alertsCountResponse] = await Promise.all([ getAllHosts({ infraMetricsClient, - apmDataAccessServices, apmDocumentSources, from, to, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts index e36811ea5b87a..154fd8796520d 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_hosts_count.ts @@ -25,14 +25,8 @@ export async function getHostsCount({ }) { assertQueryStructure(query); - const apmDocumentSources = await apmDataAccessServices?.getDocumentSources({ - start: from, - end: to, - }); - const documentsFilter = await getDocumentsFilter({ apmDataAccessServices, - apmDocumentSources, from, to, }); @@ -45,7 +39,7 @@ export async function getHostsCount({ query: { bool: { filter: [query, ...rangeQuery(from, to)], - must: [...documentsFilter], + should: [...documentsFilter], }, }, aggs: { diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts index 8f50d9eb89f13..87679f24271d6 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/types.ts @@ -13,5 +13,5 @@ import { InfraMetricsClient } from '../../../lib/helpers/get_infra_metrics_clien export interface GetHostParameters extends GetInfraMetricsRequestBodyPayload { infraMetricsClient: InfraMetricsClient; alertsClient: InfraAlertsClient; - apmDataAccessServices: ApmDataAccessServicesWrapper; + apmDataAccessServices?: ApmDataAccessServicesWrapper; } diff --git a/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts index bc6ce91e830ad..9673b31788487 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/services/index.ts @@ -36,6 +36,16 @@ export const initServicesRoute = (libs: InfraBackendLibs) => { const { from, to, size = 10, validatedFilters } = request.query; const apmDataAccessClient = getApmDataAccessClient({ request, libs, context }); + const hasApmPrivileges = await apmDataAccessClient.hasPrivileges(); + + if (!hasApmPrivileges) { + return response.customError({ + statusCode: 403, + body: { + message: 'APM data access service is not available', + }, + }); + } const apmDataAccessServices = await apmDataAccessClient.getServices(); diff --git a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts index 4d5a7cca0ff7f..7ad001831c0e4 100644 --- a/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts +++ b/x-pack/plugins/observability_solution/profiling/server/routes/apm.ts @@ -52,7 +52,9 @@ export function registerTopNFunctionsAPMTransactionsRoute({ }); } const core = await context.core; - const { transaction: transactionIndices } = await apmDataAccess.getApmIndices(); + const { transaction: transactionIndices } = await apmDataAccess.getApmIndices( + core.savedObjects.client + ); const esClient = await getClient(context);