diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2add1ca0d24c5..650c71e26c93b 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -36,6 +36,7 @@ packages/analytics/shippers/elastic_v3/server @elastic/kibana-core
 packages/analytics/shippers/fullstory @elastic/kibana-core
 packages/analytics/shippers/gainsight @elastic/kibana-core
 packages/kbn-apm-config-loader @elastic/kibana-core @vigneshshanmugam
+x-pack/plugins/apm_data_access @elastic/apm-ui
 x-pack/plugins/apm @elastic/apm-ui
 packages/kbn-apm-synthtrace @elastic/apm-ui
 packages/kbn-apm-synthtrace-client @elastic/apm-ui
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index 57e5ed40571ea..e8c008af6e0e8 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -434,6 +434,10 @@ The plugin exposes the static DefaultEditorController class to consume.
 |This plugin provides access to App Monitoring features provided by Elastic. It allows you to monitor your software services and applications in real-time; visualize detailed performance information on your services, identify and analyze errors, and monitor host-level and APM agent-specific metrics like JVM and Go runtime metrics.
 
 
+|{kib-repo}blob/{branch}/x-pack/plugins/apm_data_access[apmDataAccess]
+|WARNING: Missing README.
+
+
 |{kib-repo}blob/{branch}/x-pack/plugins/asset_manager/README.md[assetManager]
 |This plugin provides access to the asset data stored in assets-* indices, primarily
 for inventory and topology purposes.
diff --git a/fleet_packages.json b/fleet_packages.json
index f93c40d039e6a..0999f88041d11 100644
--- a/fleet_packages.json
+++ b/fleet_packages.json
@@ -34,7 +34,7 @@
   },
   {
     "name": "endpoint",
-    "version": "8.9.1"
+    "version": "8.10.0"
   },
   {
     "name": "fleet_server",
diff --git a/package.json b/package.json
index ba07ef6fe5c17..e4bb9e23dbd49 100644
--- a/package.json
+++ b/package.json
@@ -152,6 +152,7 @@
     "@kbn/analytics-shippers-fullstory": "link:packages/analytics/shippers/fullstory",
     "@kbn/analytics-shippers-gainsight": "link:packages/analytics/shippers/gainsight",
     "@kbn/apm-config-loader": "link:packages/kbn-apm-config-loader",
+    "@kbn/apm-data-access-plugin": "link:x-pack/plugins/apm_data_access",
     "@kbn/apm-plugin": "link:x-pack/plugins/apm",
     "@kbn/apm-utils": "link:packages/kbn-apm-utils",
     "@kbn/app-link-test-plugin": "link:test/plugin_functional/plugins/app_link_test",
diff --git a/tsconfig.base.json b/tsconfig.base.json
index dd6a27a32dfa9..d13cc53e6f546 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -66,6 +66,8 @@
       "@kbn/analytics-shippers-gainsight/*": ["packages/analytics/shippers/gainsight/*"],
       "@kbn/apm-config-loader": ["packages/kbn-apm-config-loader"],
       "@kbn/apm-config-loader/*": ["packages/kbn-apm-config-loader/*"],
+      "@kbn/apm-data-access-plugin": ["x-pack/plugins/apm_data_access"],
+      "@kbn/apm-data-access-plugin/*": ["x-pack/plugins/apm_data_access/*"],
       "@kbn/apm-plugin": ["x-pack/plugins/apm"],
       "@kbn/apm-plugin/*": ["x-pack/plugins/apm/*"],
       "@kbn/apm-synthtrace": ["packages/kbn-apm-synthtrace"],
diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json
index bda54b23a7f9a..3fa5a2da7c0ff 100644
--- a/x-pack/.i18nrc.json
+++ b/x-pack/.i18nrc.json
@@ -8,6 +8,7 @@
     "xpack.stackAlerts": "plugins/stack_alerts",
     "xpack.stackConnectors": "plugins/stack_connectors",
     "xpack.apm": "plugins/apm",
+    "xpack.apmDataAccess": "plugins/apm_data_access",
     "xpack.banners": "plugins/banners",
     "xpack.canvas": "plugins/canvas",
     "xpack.cases": "plugins/cases",
diff --git a/x-pack/plugins/apm/common/apm_saved_object_constants.ts b/x-pack/plugins/apm/common/apm_saved_object_constants.ts
index 17c5a802a440a..42ee9fb505adb 100644
--- a/x-pack/plugins/apm/common/apm_saved_object_constants.ts
+++ b/x-pack/plugins/apm/common/apm_saved_object_constants.ts
@@ -5,13 +5,6 @@
  * 2.0.
  */
 
-// the types have to match the names of the saved object mappings
-// in /x-pack/plugins/apm/mappings.json
-
-// APM index settings
-export const APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE = 'apm-indices';
-export const APM_INDEX_SETTINGS_SAVED_OBJECT_ID = 'apm-indices';
-
 // APM telemetry
 export const APM_TELEMETRY_SAVED_OBJECT_TYPE = 'apm-telemetry';
 export const APM_TELEMETRY_SAVED_OBJECT_ID = 'apm-telemetry';
diff --git a/x-pack/plugins/apm/kibana.jsonc b/x-pack/plugins/apm/kibana.jsonc
index 7c6b3266940a4..ed7f8fca0a241 100644
--- a/x-pack/plugins/apm/kibana.jsonc
+++ b/x-pack/plugins/apm/kibana.jsonc
@@ -9,6 +9,7 @@
     "browser": true,
     "configPath": ["xpack", "apm"],
     "requiredPlugins": [
+      "apmDataAccess",
       "data",
       "dashboard",
       "controls",
diff --git a/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts b/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
index 92fe9f08e260b..a620d3e0be017 100644
--- a/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
+++ b/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
@@ -10,9 +10,9 @@
 import { Client } from '@elastic/elasticsearch';
 import fs from 'fs/promises';
 import axios, { AxiosInstance } from 'axios';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { APIReturnType } from '../../public/services/rest/create_call_apm_api';
 import { getDiagnosticsBundle } from '../../server/routes/diagnostics/get_diagnostics_bundle';
-import { ApmIndicesConfig } from '../../server/routes/settings/apm_indices/get_apm_indices';
 
 type DiagnosticsBundle = APIReturnType<'GET /internal/apm/diagnostics'>;
 
@@ -100,7 +100,7 @@ async function getApmIndices(kibanaClient: AxiosInstance) {
         savedValue ?? defaultValue,
       ]
     )
-  ) as ApmIndicesConfig;
+  ) as APMIndices;
 }
 
 async function getFleetPackageInfo(kibanaClient: AxiosInstance) {
diff --git a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
index 8496672e40f07..9252ed46aa6df 100644
--- a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
+++ b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
@@ -10,8 +10,8 @@ import { kibanaPackageJson } from '@kbn/repo-info';
 import { GetDeprecationsContext } from '@kbn/core/server';
 import { CloudSetup } from '@kbn/cloud-plugin/server';
 import { getDeprecations } from '.';
-import { APMRouteHandlerResources } from '..';
 import { AgentPolicy } from '@kbn/fleet-plugin/common';
+import { APMRouteHandlerResources } from '../routes/apm_routes/register_apm_server_routes';
 
 const deprecationContext = {
   esClient: {},
diff --git a/x-pack/plugins/apm/server/deprecations/index.ts b/x-pack/plugins/apm/server/deprecations/index.ts
index 6545e4bfeff09..6606a932eb96b 100644
--- a/x-pack/plugins/apm/server/deprecations/index.ts
+++ b/x-pack/plugins/apm/server/deprecations/index.ts
@@ -13,7 +13,7 @@ import {
   getCloudAgentPolicy,
   getApmPackagePolicy,
 } from '../routes/fleet/get_cloud_apm_package_policy';
-import { APMRouteHandlerResources } from '..';
+import { APMRouteHandlerResources } from '../routes/apm_routes/register_apm_server_routes';
 
 export function getDeprecations({
   cloudSetup,
diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts
index 09681f01da2d6..490c75c658ad9 100644
--- a/x-pack/plugins/apm/server/feature.ts
+++ b/x-pack/plugins/apm/server/feature.ts
@@ -12,11 +12,11 @@ import {
   LicensingPluginSetup,
   LicensingApiRequestHandlerContext,
 } from '@kbn/licensing-plugin/server';
+import { APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE } from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
 import {
   ApmRuleType,
   APM_SERVER_FEATURE_ID,
 } from '../common/rules/apm_rule_types';
-import { APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE } from '../common/apm_saved_object_constants';
 
 export const APM_FEATURE = {
   id: APM_SERVER_FEATURE_ID,
diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts
index f79c83683a36b..decff8d362dfe 100644
--- a/x-pack/plugins/apm/server/index.ts
+++ b/x-pack/plugins/apm/server/index.ts
@@ -56,13 +56,6 @@ const configSchema = schema.object({
       enabled: schema.boolean({ defaultValue: false }),
     }),
   }),
-  indices: schema.object({
-    transaction: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
-    span: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
-    error: schema.string({ defaultValue: 'logs-apm*,apm-*' }),
-    metric: schema.string({ defaultValue: 'metrics-apm*,apm-*' }),
-    onboarding: schema.string({ defaultValue: 'apm-*' }),
-  }),
   forceSyntheticSource: schema.boolean({ defaultValue: false }),
   latestAgentVersionsUrl: schema.string({
     defaultValue: 'https://apm-agent-versions.elastic.co/versions.json',
@@ -109,35 +102,12 @@ export const config: PluginConfigDescriptor<APMConfig> = {
     deprecateFromRoot,
     unusedFromRoot,
   }) => [
-    unused('indices.sourcemap', { level: 'warning' }),
     unused('ui.transactionGroupBucketSize', {
       level: 'warning',
     }),
     rename('autocreateApmIndexPattern', 'autoCreateApmDataView', {
       level: 'warning',
     }),
-    renameFromRoot(
-      'apm_oss.transactionIndices',
-      'xpack.apm.indices.transaction',
-      { level: 'warning' }
-    ),
-    renameFromRoot('apm_oss.spanIndices', 'xpack.apm.indices.span', {
-      level: 'warning',
-    }),
-    renameFromRoot('apm_oss.errorIndices', 'xpack.apm.indices.error', {
-      level: 'warning',
-    }),
-    renameFromRoot('apm_oss.metricsIndices', 'xpack.apm.indices.metric', {
-      level: 'warning',
-    }),
-    renameFromRoot('apm_oss.sourcemapIndices', 'xpack.apm.indices.sourcemap', {
-      level: 'warning',
-    }),
-    renameFromRoot(
-      'apm_oss.onboardingIndices',
-      'xpack.apm.indices.onboarding',
-      { level: 'warning' }
-    ),
     deprecateFromRoot('apm_oss.enabled', '8.0.0', { level: 'warning' }),
     unusedFromRoot('apm_oss.fleetMode', { level: 'warning' }),
     unusedFromRoot('apm_oss.indexPattern', { level: 'warning' }),
@@ -165,7 +135,6 @@ export const config: PluginConfigDescriptor<APMConfig> = {
 };
 
 export type APMConfig = TypeOf<typeof configSchema>;
-export type ApmIndicesConfigName = keyof APMConfig['indices'];
 
 export const plugin = (initContext: PluginInitializerContext) =>
   new APMPlugin(initContext);
@@ -177,4 +146,3 @@ export type {
   APMServerRouteRepository,
   APIEndpoint,
 } from './routes/apm_routes/get_global_apm_server_route_repository';
-export type { APMRouteHandlerResources } from './routes/typings';
diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
index 636c7b2fde323..e90776a4ee666 100644
--- a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
+++ b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
@@ -12,6 +12,7 @@ import moment from 'moment';
 import { v4 as uuidv4 } from 'uuid';
 import { ProcessorEvent } from '@kbn/observability-plugin/common';
 import { waitForIndexStatus } from '@kbn/core-saved-objects-migration-server-internal';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { ML_ERRORS } from '../../../common/anomaly_detection';
 import { METRICSET_NAME, PROCESSOR_EVENT } from '../../../common/es_fields/apm';
 import { Environment } from '../../../common/environment_rt';
@@ -20,7 +21,6 @@ import { withApmSpan } from '../../utils/with_apm_span';
 import { MlClient } from '../helpers/get_ml_client';
 import { APM_ML_JOB_GROUP, ML_MODULE_ID_APM_TRANSACTION } from './constants';
 import { getAnomalyDetectionJobs } from './get_anomaly_detection_jobs';
-import { ApmIndicesConfig } from '../../routes/settings/apm_indices/get_apm_indices';
 
 const DEFAULT_TIMEOUT = '60s';
 
@@ -33,7 +33,7 @@ export async function createAnomalyDetectionJobs({
 }: {
   mlClient?: MlClient;
   esClient: ElasticsearchClient;
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
   environments: Environment[];
   logger: Logger;
 }) {
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
index d48ab312a5674..fb061eec49baf 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
@@ -6,7 +6,7 @@
  */
 
 import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks';
-import { ApmIndicesConfig } from '../../../routes/settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { tasks } from './tasks';
 import {
   SERVICE_NAME,
@@ -19,7 +19,7 @@ describe('data telemetry collection tasks', () => {
     metric: 'apm-8.0.0-metric',
     span: 'apm-8.0.0-span',
     transaction: 'apm-8.0.0-transaction',
-  } as ApmIndicesConfig;
+  } as APMIndices;
 
   describe('environments', () => {
     const task = tasks.find((t) => t.name === 'environments');
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
index a43c67eb6c66d..beb84481e84b7 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
@@ -10,6 +10,7 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common';
 import { createHash } from 'crypto';
 import { flatten, merge, pickBy, sortBy, sum, uniq } from 'lodash';
 import { SavedObjectsClient } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { AGENT_NAMES, RUM_AGENT_NAMES } from '../../../../common/agent_name';
 import {
   AGENT_ACTIVATION_METHOD,
@@ -56,10 +57,7 @@ import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent';
 import { Span } from '../../../../typings/es_schemas/ui/span';
 import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
 import { APMTelemetry, APMPerService, APMDataTelemetry } from '../types';
-import {
-  ApmIndicesConfig,
-  APM_AGENT_CONFIGURATION_INDEX,
-} from '../../../routes/settings/apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../../../routes/settings/apm_indices/apm_system_index_constants';
 import { TelemetryClient } from '../telemetry_client';
 
 type ISavedObjectsClient = Pick<SavedObjectsClient, 'find'>;
@@ -76,7 +74,7 @@ interface TelemetryTask {
 
 export interface TelemetryTaskExecutorParams {
   telemetryClient: TelemetryClient;
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
   savedObjectsClient: ISavedObjectsClient;
 }
 
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
index d9b8fb3f01c83..3c990dd85e23c 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
@@ -6,12 +6,17 @@
  */
 
 import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
-import { CoreSetup, Logger, SavedObjectsErrorHelpers } from '@kbn/core/server';
+import {
+  CoreSetup,
+  Logger,
+  SavedObjectsClientContract,
+  SavedObjectsErrorHelpers,
+} from '@kbn/core/server';
 import {
   TaskManagerSetupContract,
   TaskManagerStartContract,
 } from '@kbn/task-manager-plugin/server';
-import { APMConfig } from '../..';
+import { APMDataAccessConfig } from '@kbn/apm-data-access-plugin/server';
 import {
   APM_TELEMETRY_SAVED_OBJECT_ID,
   APM_TELEMETRY_SAVED_OBJECT_TYPE,
@@ -20,14 +25,13 @@ import { getInternalSavedObjectsClient } from '../helpers/get_internal_saved_obj
 import { collectDataTelemetry } from './collect_data_telemetry';
 import { APMUsage } from './types';
 import { apmSchema } from './schema';
-import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices';
 import { getTelemetryClient } from './telemetry_client';
 
 export const APM_TELEMETRY_TASK_NAME = 'apm-telemetry-task';
 
 export async function createApmTelemetry({
   core,
-  config,
+  getApmIndices,
   usageCollector,
   taskManager,
   logger,
@@ -35,7 +39,9 @@ export async function createApmTelemetry({
   isProd,
 }: {
   core: CoreSetup;
-  config: APMConfig;
+  getApmIndices: (
+    soClient: SavedObjectsClientContract
+  ) => Promise<APMDataAccessConfig['indices']>;
   usageCollector: UsageCollectionSetup;
   taskManager: TaskManagerSetupContract;
   logger: Logger;
@@ -56,14 +62,14 @@ export async function createApmTelemetry({
     },
   });
 
+  const telemetryClient = await getTelemetryClient({ core });
   const [coreStart] = await core.getStartServices();
   const savedObjectsClient = await getInternalSavedObjectsClient(coreStart);
-  const indices = await getApmIndices({ config, savedObjectsClient });
-  const telemetryClient = await getTelemetryClient({ core });
+  const apmIndices = await getApmIndices(savedObjectsClient);
 
   const collectAndStore = async () => {
     const dataTelemetry = await collectDataTelemetry({
-      indices,
+      indices: apmIndices,
       telemetryClient,
       logger,
       savedObjectsClient,
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
index 58be670cbb30c..253a0993d1a8c 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
@@ -6,7 +6,7 @@
  */
 
 import { APMEventESSearchRequest } from '.';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getRequestBase } from './get_request_base';
 
 describe('getRequestBase', () => {
@@ -26,7 +26,7 @@ describe('getRequestBase', () => {
       error: 'my-apm-*-error-*',
       span: 'my-apm-*-span-*',
       onboarding: 'my-apm-*-onboarding-*',
-    } as ApmIndicesConfig;
+    } as APMIndices;
 
     res = getRequestBase({ ...request, indices });
   });
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
index 16e8b0edba21a..1c2c3ad296101 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
@@ -6,12 +6,12 @@
  */
 
 import type { ESFilter } from '@kbn/es-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { ProcessorEvent } from '@kbn/observability-plugin/common';
 import { uniq } from 'lodash';
 import { ApmDataSource } from '../../../../../common/data_source';
 import {} from '../../../../../common/document_type';
 import { PROCESSOR_EVENT } from '../../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
 import {
   getConfigForDocumentType,
   getProcessorEventForDocumentType,
@@ -26,7 +26,7 @@ const processorEventIndexMap = {
 
 export function processorEventsToIndex(
   events: ProcessorEvent[],
-  indices: ApmIndicesConfig
+  indices: APMIndices
 ) {
   return uniq(
     events.flatMap((event) =>
@@ -37,7 +37,7 @@ export function processorEventsToIndex(
 
 export function getRequestBase(options: {
   apm: { events: ProcessorEvent[] } | { sources: ApmDataSource[] };
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
 }) {
   const events =
     'events' in options.apm
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
index b40918cbf750e..a9a5e02b9eae1 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
@@ -20,12 +20,12 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common';
 import { unwrapEsResponse } from '@kbn/observability-plugin/server';
 import { compact, omit } from 'lodash';
 import { ValuesType } from 'utility-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { ApmDataSource } from '../../../../../common/data_source';
 import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
 import { Metric } from '../../../../../typings/es_schemas/ui/metric';
 import { Span } from '../../../../../typings/es_schemas/ui/span';
 import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
 import { withApmSpan } from '../../../../utils/with_apm_span';
 import {
   callAsyncWithDebug,
@@ -87,7 +87,7 @@ export interface APMEventClientConfig {
   esClient: ElasticsearchClient;
   debug: boolean;
   request: KibanaRequest;
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
   options: {
     includeFrozen: boolean;
     forceSyntheticSource: boolean;
@@ -98,7 +98,7 @@ export class APMEventClient {
   private readonly esClient: ElasticsearchClient;
   private readonly debug: boolean;
   private readonly request: KibanaRequest;
-  public readonly indices: ApmIndicesConfig;
+  public readonly indices: APMIndices;
   private readonly includeFrozen: boolean;
   private readonly forceSyntheticSource: boolean;
 
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
index 5cc9f8bb427cf..0128d6aa92d21 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
@@ -6,7 +6,7 @@
  */
 
 import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
-import { APMRouteHandlerResources } from '../../../../routes/typings';
+import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
 import { getInfraMetricIndices } from '../../get_infra_metric_indices';
 
 type InfraMetricsSearchParams = Omit<ESSearchRequest, 'index'> & {
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
index d1cd9054fbac1..e205a07129d3d 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
@@ -8,17 +8,15 @@
 import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
 import { unwrapEsResponse } from '@kbn/observability-plugin/server';
 import type { ESSearchResponse, ESSearchRequest } from '@kbn/es-types';
-import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { APMConfig } from '../../../..';
-import { APMRouteHandlerResources } from '../../../../routes/typings';
+import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
 import {
   callAsyncWithDebug,
   getDebugBody,
   getDebugTitle,
 } from '../call_async_with_debug';
 import { cancelEsRequestOnAbort } from '../cancel_es_request_on_abort';
-import { getApmIndices } from '../../../../routes/settings/apm_indices/get_apm_indices';
 
 export type APMIndexDocumentParams<T> = estypes.IndexRequest<T>;
 
@@ -28,39 +26,35 @@ export type APMInternalESClient = Awaited<
 
 export async function createInternalESClientWithContext({
   debug,
-  config,
+  apmIndices,
   request,
   context,
 }: {
   debug: boolean;
-  config: APMConfig;
+  apmIndices: APMIndices;
   request: APMRouteHandlerResources['request'];
   context: APMRouteHandlerResources['context'];
 }) {
   const coreContext = await context.core;
   const { asInternalUser } = coreContext.elasticsearch.client;
-  const savedObjectsClient = coreContext.savedObjects.client;
 
   return createInternalESClient({
     debug,
-    config,
+    apmIndices,
     request,
-    savedObjectsClient,
     elasticsearchClient: asInternalUser,
   });
 }
 
 export async function createInternalESClient({
   debug,
-  config,
+  apmIndices,
   request,
-  savedObjectsClient,
   elasticsearchClient,
 }: {
   debug: boolean;
-  config: APMConfig;
+  apmIndices: APMIndices;
   request?: APMRouteHandlerResources['request'];
-  savedObjectsClient: SavedObjectsClientContract;
   elasticsearchClient: ElasticsearchClient;
 }) {
   function callEs<T extends { body: any }>(
@@ -98,7 +92,7 @@ export async function createInternalESClient({
   }
 
   return {
-    apmIndices: await getApmIndices({ savedObjectsClient, config }),
+    apmIndices,
     search: async <
       TDocument = unknown,
       TSearchRequest extends ESSearchRequest = ESSearchRequest
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
index 5be010b613383..1a63067aa7ea2 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
@@ -8,7 +8,7 @@
 import { isEmpty } from 'lodash';
 import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
 import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
 
 export type ApmAlertsClient = Awaited<ReturnType<typeof getApmAlertsClient>>;
 
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
index 7ed4902fa0615..e7425a01c4bd1 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
@@ -6,24 +6,21 @@
  */
 
 import { UI_SETTINGS } from '@kbn/data-plugin/common';
-import { APMRouteHandlerResources } from '../../routes/typings';
-import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices';
 import { APMEventClient } from './create_es_client/create_apm_event_client';
 import { withApmSpan } from '../../utils/with_apm_span';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
 
 export async function getApmEventClient({
   context,
   params,
   config,
+  getApmIndices,
   request,
 }: APMRouteHandlerResources): Promise<APMEventClient> {
   return withApmSpan('get_apm_event_client', async () => {
     const coreContext = await context.core;
     const [indices, includeFrozen] = await Promise.all([
-      getApmIndices({
-        savedObjectsClient: coreContext.savedObjects.client,
-        config,
-      }),
+      getApmIndices(),
       withApmSpan('get_ui_settings', () =>
         coreContext.uiSettings.client.get<boolean>(
           UI_SETTINGS.SEARCH_INCLUDE_FROZEN
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
index aa978b1643a86..aec76a75fb944 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
@@ -6,7 +6,7 @@
  */
 
 import { SavedObjectsClientContract } from '@kbn/core/server';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
 
 export async function getInfraMetricIndices({
   infraPlugin,
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
index 8d2609867d8f2..a69a705b2f374 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
@@ -7,10 +7,6 @@
 
 import { CoreStart } from '@kbn/core/server';
 
-export type InternalSavedObjectsClient = Awaited<
-  ReturnType<typeof getInternalSavedObjectsClient>
->;
-
 export async function getInternalSavedObjectsClient(coreStart: CoreStart) {
   return coreStart.savedObjects.createInternalRepository();
 }
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
index 37f17833ed9da..32ebc4f11f90d 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
@@ -11,7 +11,7 @@ import {
   MlModules,
 } from '@kbn/ml-plugin/server';
 import { isActivePlatinumLicense } from '../../../common/license_check';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
 
 export interface MlClient {
   mlSystem: MlMlSystem;
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts b/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
index 5c822ca762dc9..071969cae7251 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
@@ -7,7 +7,7 @@
 
 import { KibanaRequest } from '@kbn/core/server';
 import seedrandom from 'seedrandom';
-import { APMRouteHandlerResources } from '../../..';
+import { APMRouteHandlerResources } from '../../../routes/apm_routes/register_apm_server_routes';
 
 export async function getRandomSampler({
   security,
diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts
index 618c1b388bfab..79e5f353f3ce3 100644
--- a/x-pack/plugins/apm/server/plugin.ts
+++ b/x-pack/plugins/apm/server/plugin.ts
@@ -5,18 +5,15 @@
  * 2.0.
  */
 
-import { firstValueFrom } from 'rxjs';
 import {
   CoreSetup,
   CoreStart,
-  KibanaRequest,
   Logger,
   Plugin,
   PluginInitializerContext,
 } from '@kbn/core/server';
 import { isEmpty, mapValues } from 'lodash';
 import { Dataset } from '@kbn/rule-registry-plugin/server';
-import { UI_SETTINGS } from '@kbn/data-plugin/common';
 import { mappingFromFieldMap } from '@kbn/alerting-plugin/common';
 import { alertsLocatorID } from '@kbn/observability-plugin/common';
 import { APMConfig, APM_SERVER_FEATURE_ID } from '.';
@@ -28,30 +25,25 @@ import {
 } from './routes/alerts/register_apm_rule_types';
 import { registerFleetPolicyCallbacks } from './routes/fleet/register_fleet_policy_callbacks';
 import { createApmTelemetry } from './lib/apm_telemetry';
-import { APMEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
 import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client';
 import { createApmAgentConfigurationIndex } from './routes/settings/agent_configuration/create_agent_config_index';
-import { getApmIndices } from './routes/settings/apm_indices/get_apm_indices';
 import { createApmCustomLinkIndex } from './routes/settings/custom_link/create_custom_link_index';
 import {
-  apmIndices,
   apmTelemetry,
   apmServerSettings,
   apmServiceGroups,
 } from './saved_objects';
-import type {
-  ApmPluginRequestHandlerContext,
-  APMRouteHandlerResources,
-} from './routes/typings';
 import {
   APMPluginSetup,
   APMPluginSetupDependencies,
   APMPluginStartDependencies,
 } from './types';
-import { registerRoutes } from './routes/apm_routes/register_apm_server_routes';
+import {
+  APMRouteHandlerResources,
+  registerRoutes,
+} from './routes/apm_routes/register_apm_server_routes';
 import { getGlobalApmServerRouteRepository } from './routes/apm_routes/get_global_apm_server_route_repository';
 import { tutorialProvider } from './tutorial';
-import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware';
 import { scheduleSourceMapMigration } from './routes/source_maps/schedule_source_map_migration';
 import { createApmSourceMapIndexTemplate } from './routes/source_maps/create_apm_source_map_index_template';
 import { addApiKeysToEveryPackagePolicyIfMissing } from './routes/fleet/api_keys/add_api_keys_to_policies_if_missing';
@@ -80,7 +72,6 @@ export class APMPlugin
     this.logger = this.initContext.logger.get();
     const config$ = this.initContext.config.create<APMConfig>();
 
-    core.savedObjects.registerType(apmIndices);
     core.savedObjects.registerType(apmTelemetry);
     core.savedObjects.registerType(apmServerSettings);
     core.savedObjects.registerType(apmServiceGroups);
@@ -95,7 +86,7 @@ export class APMPlugin
     ) {
       createApmTelemetry({
         core,
-        config: currentConfig,
+        getApmIndices: plugins.apmDataAccess.getApmIndices,
         usageCollector: plugins.usageCollection,
         taskManager: plugins.taskManager,
         logger: this.logger,
@@ -141,13 +132,12 @@ export class APMPlugin
       };
     }) as APMRouteHandlerResources['plugins'];
 
-    const boundGetApmIndices = async () => {
+    const apmIndicesPromise = (async () => {
       const coreStart = await getCoreStart();
-      return getApmIndices({
-        savedObjectsClient: await getInternalSavedObjectsClient(coreStart),
-        config: await firstValueFrom(config$),
-      });
-    };
+      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
@@ -158,11 +148,11 @@ export class APMPlugin
         apmTutorialCustomIntegration
       );
     } else {
-      boundGetApmIndices().then((indices) => {
+      apmIndicesPromise.then((apmIndices) => {
         plugins.home?.tutorials.registerTutorial(
           tutorialProvider({
             apmConfig: currentConfig,
-            apmIndices: indices,
+            apmIndices,
             cloud: plugins.cloud,
             isFleetPluginEnabled: !isEmpty(resourcePlugins.fleet),
           })
@@ -190,11 +180,14 @@ export class APMPlugin
       kibanaVersion: this.initContext.env.packageInfo.version,
     });
 
+    const { getApmIndices } = plugins.apmDataAccess;
+
     if (plugins.alerting) {
       registerApmRuleTypes({
+        getApmIndices,
         alerting: plugins.alerting,
         basePath: core.http.basePath,
-        config$,
+        apmConfig: currentConfig,
         logger: this.logger!.get('rule'),
         ml: plugins.ml,
         observability: plugins.observability,
@@ -207,7 +200,6 @@ export class APMPlugin
       logger: this.logger,
       coreStartPromise: getCoreStart(),
       plugins: resourcePlugins,
-      config: currentConfig,
     }).catch((e) => {
       this.logger?.error('Failed to register APM Fleet policy callbacks');
       this.logger?.error(e);
@@ -236,38 +228,7 @@ export class APMPlugin
       this.logger?.error(e);
     });
 
-    return {
-      config$,
-      getApmIndices: boundGetApmIndices,
-      createApmEventClient: async ({
-        request,
-        context,
-        debug,
-      }: {
-        debug?: boolean;
-        request: KibanaRequest;
-        context: ApmPluginRequestHandlerContext;
-      }) => {
-        const coreContext = await context.core;
-        const [indices, includeFrozen] = await Promise.all([
-          boundGetApmIndices(),
-          coreContext.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
-        ]);
-
-        const esClient = coreContext.elasticsearch.client.asCurrentUser;
-
-        return new APMEventClient({
-          debug: debug ?? false,
-          esClient,
-          request,
-          indices,
-          options: {
-            includeFrozen,
-            forceSyntheticSource: currentConfig.forceSyntheticSource,
-          },
-        });
-      },
-    };
+    return { config$ };
   }
 
   public start(core: CoreStart, plugins: APMPluginStartDependencies) {
@@ -295,14 +256,6 @@ export class APMPlugin
       logger.error('Failed to create apm-source-map index template');
       logger.error(e);
     });
-
-    // TODO: remove in 9.0
-    migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger }).catch(
-      (e) => {
-        logger.error('Failed to run migration making APM indices space aware');
-        logger.error(e);
-      }
-    );
   }
 
   public stop() {}
diff --git a/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts b/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
index 2245ddf574885..54f4a824ee687 100644
--- a/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
@@ -7,8 +7,11 @@
 
 import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
 import { LocatorPublic } from '@kbn/share-plugin/common';
-import { Observable } from 'rxjs';
-import { IBasePath, Logger } from '@kbn/core/server';
+import {
+  IBasePath,
+  Logger,
+  SavedObjectsClientContract,
+} from '@kbn/core/server';
 import {
   PluginSetupContract as AlertingPluginSetupContract,
   type IRuleTypeAlerts,
@@ -17,6 +20,7 @@ import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
 import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
 import { MlPluginSetup } from '@kbn/ml-plugin/server';
 import { legacyExperimentalFieldMap } from '@kbn/alerts-as-data-utils';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   AGENT_NAME,
   ERROR_GROUP_ID,
@@ -91,7 +95,8 @@ export const ApmRuleTypeAlertDefinition: IRuleTypeAlerts = {
 export interface RegisterRuleDependencies {
   alerting: AlertingPluginSetupContract;
   basePath: IBasePath;
-  config$: Observable<APMConfig>;
+  getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMIndices>;
+  apmConfig: APMConfig;
   logger: Logger;
   ml?: MlPluginSetup;
   observability: ObservabilityPluginSetup;
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
index a5c4205298438..168d4456d3f2c 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
@@ -4,11 +4,12 @@
  * 2.0; you may not use this file except in compliance with the Elastic License
  * 2.0.
  */
-import { firstValueFrom } from 'rxjs';
+
 import {
   IScopedClusterClient,
   SavedObjectsClientContract,
 } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   SERVICE_ENVIRONMENT,
   SERVICE_NAME,
@@ -20,20 +21,17 @@ import {
   getServiceGroupFields,
   getServiceGroupFieldsAgg,
 } from '../get_service_group_fields';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
-import { RegisterRuleDependencies } from '../../register_apm_rule_types';
 
 export async function getServiceGroupFieldsForAnomaly({
-  config$,
+  apmIndices,
   scopedClusterClient,
-  savedObjectsClient,
   serviceName,
   environment,
   transactionType,
   timestamp,
   bucketSpan,
 }: {
-  config$: RegisterRuleDependencies['config$'];
+  apmIndices: APMIndices;
   scopedClusterClient: IScopedClusterClient;
   savedObjectsClient: SavedObjectsClientContract;
   serviceName: string;
@@ -42,15 +40,8 @@ export async function getServiceGroupFieldsForAnomaly({
   timestamp: number;
   bucketSpan: number;
 }) {
-  const config = await firstValueFrom(config$);
-  const indices = await getApmIndices({
-    config,
-    savedObjectsClient,
-  });
-  const { transaction: index } = indices;
-
   const params = {
-    index,
+    index: apmIndices.transaction,
     body: {
       size: 0,
       track_total_hits: false,
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
index 81da325350dbd..ed313b6f95dab 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
@@ -63,8 +63,8 @@ const ruleTypeConfig = RULE_TYPES_CONFIG[ApmRuleType.Anomaly];
 export function registerAnomalyRuleType({
   alerting,
   alertsLocator,
+  getApmIndices,
   basePath,
-  config$,
   logger,
   ml,
   ruleDataClient,
@@ -108,6 +108,8 @@ export function registerAnomalyRuleType({
           scopedClusterClient,
         } = services;
 
+        const apmIndices = await getApmIndices(savedObjectsClient);
+
         const ruleParams = params;
         const request = {} as KibanaRequest;
         const { mlAnomalySearch } = ml.mlSystemProvider(
@@ -256,7 +258,7 @@ export function registerAnomalyRuleType({
           } = anomaly;
 
           const eventSourceFields = await getServiceGroupFieldsForAnomaly({
-            config$,
+            apmIndices,
             scopedClusterClient,
             savedObjectsClient,
             serviceName,
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
index 6f736fb3e5d82..dde54fa604fc7 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
@@ -25,7 +25,6 @@ import {
 } from '@kbn/observability-plugin/server';
 import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
 import { asyncForEach } from '@kbn/std';
-import { firstValueFrom } from 'rxjs';
 import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
 import {
   ERROR_GROUP_ID,
@@ -42,7 +41,6 @@ import {
 import { errorCountParamsSchema } from '../../../../../common/rules/schema';
 import { environmentQuery } from '../../../../../common/utils/environment_query';
 import { getAlertUrlErrorCount } from '../../../../../common/utils/formatters';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
 import { apmActionVariables } from '../../action_variables';
 import { alertingEsClient } from '../../alerting_es_client';
 import {
@@ -63,7 +61,7 @@ export function registerErrorCountRuleType({
   alerting,
   alertsLocator,
   basePath,
-  config$,
+  getApmIndices,
   logger,
   ruleDataClient,
 }: RegisterRuleDependencies) {
@@ -108,8 +106,6 @@ export function registerErrorCountRuleType({
           ruleParams.groupBy
         );
 
-        const config = await firstValueFrom(config$);
-
         const {
           getAlertUuid,
           getAlertStartedDate,
@@ -117,10 +113,7 @@ export function registerErrorCountRuleType({
           scopedClusterClient,
         } = services;
 
-        const indices = await getApmIndices({
-          config,
-          savedObjectsClient,
-        });
+        const indices = await getApmIndices(savedObjectsClient);
 
         const termFilterQuery = !ruleParams.kqlFilter
           ? [
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
index c64eb650d8d84..05f1d6adf6e5b 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
@@ -26,7 +26,6 @@ import {
 } from '@kbn/rule-data-utils';
 import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server';
 import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
-import { firstValueFrom } from 'rxjs';
 import { getGroupByTerms } from '../utils/get_groupby_terms';
 import { SearchAggregatedTransactionSetting } from '../../../../../common/aggregated_transactions';
 import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
@@ -53,7 +52,6 @@ import {
   getDocumentTypeFilterForTransactions,
   getDurationFieldForTransactions,
 } from '../../../../lib/helpers/transactions';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
 import { apmActionVariables } from '../../action_variables';
 import { alertingEsClient } from '../../alerting_es_client';
 import {
@@ -76,7 +74,8 @@ const ruleTypeConfig = RULE_TYPES_CONFIG[ApmRuleType.TransactionDuration];
 export function registerTransactionDurationRuleType({
   alerting,
   ruleDataClient,
-  config$,
+  getApmIndices,
+  apmConfig,
   logger,
   basePath,
 }: RegisterRuleDependencies) {
@@ -114,21 +113,16 @@ export function registerTransactionDurationRuleType({
         ruleParams.groupBy
       );
 
-      const config = await firstValueFrom(config$);
-
       const { getAlertUuid, savedObjectsClient, scopedClusterClient } =
         services;
 
-      const indices = await getApmIndices({
-        config,
-        savedObjectsClient,
-      });
+      const indices = await getApmIndices(savedObjectsClient);
 
       // only query transaction events when set to 'never',
       // to prevent (likely) unnecessary blocking request
       // in rule execution
       const searchAggregatedTransactions =
-        config.searchAggregatedTransactions !==
+        apmConfig.searchAggregatedTransactions !==
         SearchAggregatedTransactionSetting.never;
 
       const index = searchAggregatedTransactions
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
index 7b39de2a1b3af..6761ca14abf86 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
@@ -26,7 +26,6 @@ import {
 import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server';
 import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
 import { asyncForEach } from '@kbn/std';
-import { firstValueFrom } from 'rxjs';
 import { SearchAggregatedTransactionSetting } from '../../../../../common/aggregated_transactions';
 import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
 import {
@@ -51,7 +50,6 @@ import {
   getAlertUrlTransaction,
 } from '../../../../../common/utils/formatters';
 import { getDocumentTypeFilterForTransactions } from '../../../../lib/helpers/transactions';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
 import { apmActionVariables } from '../../action_variables';
 import { alertingEsClient } from '../../alerting_es_client';
 import {
@@ -72,7 +70,8 @@ export function registerTransactionErrorRateRuleType({
   alerting,
   alertsLocator,
   basePath,
-  config$,
+  getApmIndices,
+  apmConfig,
   logger,
   ruleDataClient,
 }: RegisterRuleDependencies) {
@@ -117,8 +116,6 @@ export function registerTransactionErrorRateRuleType({
           ruleParams.groupBy
         );
 
-        const config = await firstValueFrom(config$);
-
         const {
           getAlertUuid,
           getAlertStartedDate,
@@ -126,16 +123,13 @@ export function registerTransactionErrorRateRuleType({
           scopedClusterClient,
         } = services;
 
-        const indices = await getApmIndices({
-          config,
-          savedObjectsClient,
-        });
+        const indices = await getApmIndices(savedObjectsClient);
 
         // only query transaction events when set to 'never',
         // to prevent (likely) unnecessary blocking request
         // in rule execution
         const searchAggregatedTransactions =
-          config.searchAggregatedTransactions !==
+          apmConfig.searchAggregatedTransactions !==
           SearchAggregatedTransactionSetting.never;
 
         const index = searchAggregatedTransactions
diff --git a/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts b/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
index fecb5c8fba19d..7071d43eec989 100644
--- a/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
@@ -5,7 +5,6 @@
  * 2.0.
  */
 
-import { of } from 'rxjs';
 import { IBasePath, Logger } from '@kbn/core/server';
 import { elasticsearchServiceMock } from '@kbn/core/server/mocks';
 import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
@@ -20,13 +19,6 @@ import { APMConfig, APM_SERVER_FEATURE_ID } from '../../..';
 export const createRuleTypeMocks = () => {
   let alertExecutor: (...args: any[]) => Promise<any>;
 
-  const mockedConfig$ = of({
-    indices: {
-      error: 'apm-*',
-      transaction: 'apm-*',
-    },
-  } as APMConfig);
-
   const loggerMock = {
     debug: jest.fn(),
     warn: jest.fn(),
@@ -64,7 +56,14 @@ export const createRuleTypeMocks = () => {
         publicBaseUrl: 'http://localhost:5601/eyr',
         serverBasePath: '/eyr',
       } as IBasePath,
-      config$: mockedConfig$,
+      apmConfig: { searchAggregatedTransactions: true } as any as APMConfig,
+      getApmIndices: async () => ({
+        error: 'apm-*',
+        transaction: 'apm-*',
+        span: 'apm-*',
+        metric: 'apm-*',
+        onboarding: 'apm-*',
+      }),
       observability: {
         getAlertDetailsConfig: jest.fn().mockReturnValue({ apm: true }),
       } as unknown as ObservabilityPluginSetup,
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts b/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
index b00b1ad6a1fa5..e2f0251a6343c 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
@@ -5,7 +5,8 @@
  * 2.0.
  */
 import { createServerRouteFactory } from '@kbn/server-route-repository';
-import { APMRouteCreateOptions, APMRouteHandlerResources } from '../typings';
+import { APMRouteCreateOptions } from '../typings';
+import { APMRouteHandlerResources } from './register_apm_server_routes';
 
 export const createApmServerRoute = createServerRouteFactory<
   APMRouteHandlerResources,
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
index ed879d2017e7b..339f7044583b4 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
@@ -13,8 +13,11 @@ import {
 import * as t from 'io-ts';
 import { CoreSetup, Logger } from '@kbn/core/server';
 import { APMConfig } from '../..';
-import { APMRouteCreateOptions, APMRouteHandlerResources } from '../typings';
-import { registerRoutes } from './register_apm_server_routes';
+import { APMRouteCreateOptions } from '../typings';
+import {
+  APMRouteHandlerResources,
+  registerRoutes,
+} from './register_apm_server_routes';
 import { NEVER } from 'rxjs';
 
 type RegisterRouteDependencies = Parameters<typeof registerRoutes>[0];
@@ -54,7 +57,18 @@ const getRegisterRouteDependencies = () => {
       },
       logger,
       config: {} as APMConfig,
-      plugins: {},
+      plugins: {
+        apmDataAccess: {
+          setup: {
+            indices: {
+              errorIndices: 'apm-*',
+              metricsIndices: 'apm-*',
+              spanIndices: 'apm-*',
+              transactionIndices: 'apm-*',
+            },
+          },
+        },
+      },
     } as unknown as RegisterRouteDependencies,
   };
 };
@@ -208,9 +222,7 @@ describe('createApi', () => {
         } = initApi([
           {
             endpoint: 'GET /foo',
-            options: {
-              tags: [],
-            },
+            options: { tags: [] },
             handler: handlerMock,
           },
         ]);
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
index 014c5139971eb..f4e6c1aaa98df 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
@@ -8,6 +8,7 @@
 import Boom from '@hapi/boom';
 import * as t from 'io-ts';
 import {
+  Logger,
   KibanaRequest,
   KibanaResponseFactory,
   RouteRegistrar,
@@ -25,9 +26,17 @@ import { jsonRt, mergeRt } from '@kbn/io-ts-utils';
 import { InspectResponse } from '@kbn/observability-plugin/typings/common';
 import apm from 'elastic-apm-node';
 import { VersionedRouteRegistrar } from '@kbn/core-http-server';
+import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
+import { ApmFeatureFlags } from '../../../common/apm_feature_flags';
 import { pickKeys } from '../../../common/utils/pick_keys';
-import { APMRouteHandlerResources, TelemetryUsageCounter } from '../typings';
+import { APMCore, TelemetryUsageCounter } from '../typings';
 import type { ApmPluginRequestHandlerContext } from '../typings';
+import { APMConfig } from '../..';
+import {
+  APMPluginSetupDependencies,
+  APMPluginStartDependencies,
+} from '../../types';
 
 const inspectRt = t.exact(
   t.partial({
@@ -99,6 +108,14 @@ export function registerRoutes({
           runtimeType
         );
 
+        const getApmIndices = async () => {
+          const coreContext = await context.core;
+          const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(
+            coreContext.savedObjects.client
+          );
+          return apmIndices;
+        };
+
         const { aborted, data } = await Promise.race([
           handler({
             request,
@@ -109,6 +126,7 @@ export function registerRoutes({
             core,
             plugins,
             telemetryUsageCounter,
+            getApmIndices,
             params: merge(
               {
                 query: {
@@ -231,3 +249,29 @@ export function registerRoutes({
     }
   });
 }
+
+type Plugins = {
+  [key in keyof APMPluginSetupDependencies]: {
+    setup: Required<APMPluginSetupDependencies>[key];
+    start: () => Promise<Required<APMPluginStartDependencies>[key]>;
+  };
+};
+
+export interface APMRouteHandlerResources {
+  request: KibanaRequest;
+  context: ApmPluginRequestHandlerContext;
+  params: {
+    query: {
+      _inspect: boolean;
+    };
+  };
+  config: APMConfig;
+  featureFlags: ApmFeatureFlags;
+  logger: Logger;
+  core: APMCore;
+  plugins: Plugins;
+  ruleDataClient: IRuleDataClient;
+  telemetryUsageCounter?: TelemetryUsageCounter;
+  kibanaVersion: string;
+  getApmIndices: () => Promise<APMIndices>;
+}
diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
index 512a1f78a62b7..714f97b1a4801 100644
--- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
@@ -8,9 +8,10 @@
 import { createStaticDataView } from './create_static_data_view';
 import * as HistoricalAgentData from '../historical_data/has_historical_agent_data';
 import { DataViewsService } from '@kbn/data-views-plugin/common';
-import { APMRouteHandlerResources, APMCore } from '../typings';
+import { APMCore } from '../typings';
 import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
 
 function getMockedDataViewService(existingDataViewTitle: string) {
   return {
@@ -42,7 +43,7 @@ const apmEventClientMock = {
     span: 'apm-*-span-*',
     error: 'apm-*-error-*',
     metric: 'apm-*-metrics-*',
-  } as APMConfig['indices'],
+  } as APMIndices,
 } as unknown as APMEventClient;
 
 describe('createStaticDataView', () => {
diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
index 7422c878163b7..715a568eaf6bd 100644
--- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
@@ -17,9 +17,8 @@ import { APM_STATIC_DATA_VIEW_ID } from '../../../common/data_view_constants';
 import { hasHistoricalAgentData } from '../historical_data/has_historical_agent_data';
 import { withApmSpan } from '../../utils/with_apm_span';
 import { getApmDataViewTitle } from './get_apm_data_view_title';
-
-import { APMRouteHandlerResources } from '../typings';
 import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
 
 export type CreateDataViewResponse = Promise<
   | { created: boolean; dataView: DataView }
diff --git a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
index 718316f4f241f..a8dc25e493006 100644
--- a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
@@ -5,7 +5,7 @@
  * 2.0.
  */
 
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getApmDataViewTitle } from './get_apm_data_view_title';
 
 describe('getApmDataViewTitle', () => {
@@ -15,7 +15,7 @@ describe('getApmDataViewTitle', () => {
       span: 'apm-*-span-*',
       error: 'apm-*-error-*',
       metric: 'apm-*-metrics-*',
-    } as ApmIndicesConfig);
+    } as APMIndices);
     expect(title).toBe(
       'apm-*-transaction-*,apm-*-span-*,apm-*-error-*,apm-*-metrics-*'
     );
@@ -27,7 +27,7 @@ describe('getApmDataViewTitle', () => {
       span: 'apm-*',
       error: 'apm-*',
       metric: 'apm-*',
-    } as ApmIndicesConfig);
+    } as APMIndices);
     expect(title).toBe('apm-*');
   });
 });
diff --git a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
index a70987fd2622c..3061a1ac15714 100644
--- a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
@@ -6,13 +6,13 @@
  */
 
 import { uniq } from 'lodash';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 
-export function getApmDataViewTitle(apmIndicesConfig: ApmIndicesConfig) {
+export function getApmDataViewTitle(apmIndices: APMIndices) {
   return uniq([
-    apmIndicesConfig.transaction,
-    apmIndicesConfig.span,
-    apmIndicesConfig.error,
-    apmIndicesConfig.metric,
+    apmIndices.transaction,
+    apmIndices.span,
+    apmIndices.error,
+    apmIndices.metric,
   ]).join(',');
 }
diff --git a/x-pack/plugins/apm/server/routes/data_view/route.ts b/x-pack/plugins/apm/server/routes/data_view/route.ts
index 53f4b3d68566f..388884c4f5761 100644
--- a/x-pack/plugins/apm/server/routes/data_view/route.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/route.ts
@@ -11,7 +11,6 @@ import {
 } from './create_static_data_view';
 import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
 import { getApmDataViewTitle } from './get_apm_data_view_title';
-import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
 import { getApmEventClient } from '../../lib/helpers/get_apm_event_client';
 
 const staticDataViewRoute = createApmServerRoute({
@@ -43,15 +42,8 @@ const staticDataViewRoute = createApmServerRoute({
 const dataViewTitleRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/data_view/title',
   options: { tags: ['access:apm'] },
-  handler: async ({
-    context,
-    config,
-  }): Promise<{ apmDataViewTitle: string }> => {
-    const coreContext = await context.core;
-    const apmIndicies = await getApmIndices({
-      savedObjectsClient: coreContext.savedObjects.client,
-      config,
-    });
+  handler: async ({ getApmIndices }): Promise<{ apmDataViewTitle: string }> => {
+    const apmIndicies = await getApmIndices();
     const apmDataViewTitle = getApmDataViewTitle(apmIndicies);
 
     return { apmDataViewTitle };
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
index b1dd52e630783..cefe5768f6542 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
@@ -8,6 +8,7 @@
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
 import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server';
 import { merge } from 'lodash';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   PROCESSOR_EVENT,
   METRICSET_NAME,
@@ -15,7 +16,6 @@ import {
   TRANSACTION_DURATION_SUMMARY,
   INDEX,
 } from '../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
 import { getTypedSearch, TypedSearch } from '../create_typed_es_client';
 import { getApmIndexPatterns } from './get_indices';
 
@@ -36,7 +36,7 @@ export async function getApmEvents({
   kuery,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
   start: number;
   end: number;
   kuery?: string;
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
index 44136bd1dd19f..6444739e6c4b5 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
@@ -6,7 +6,7 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getApmIndexPatterns } from './get_indices';
 
 export async function getDataStreams({
@@ -14,7 +14,7 @@ export async function getDataStreams({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const apmIndexPatterns = getApmIndexPatterns([
     apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
index de24c10945708..c734207fa7ece 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
@@ -6,8 +6,8 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { SERVICE_NAME } from '../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
 import { getApmIndexPatterns } from './get_indices';
 
 export function getFieldCaps({
@@ -15,7 +15,7 @@ export function getFieldCaps({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   return esClient.fieldCaps({
     index: getApmIndexPatterns([apmIndices.metric, apmIndices.transaction]),
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
index 58e6d7293737e..fc9d18c255ab1 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
@@ -9,7 +9,7 @@ import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
 import { IndicesSimulateTemplateResponse } from '@elastic/elasticsearch/lib/api/types';
 import { orderBy } from 'lodash';
 import { errors } from '@elastic/elasticsearch';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getApmIndexPatterns } from './get_indices';
 import { getIndexTemplate } from './get_index_template';
 import { getApmIndexTemplateNames } from '../helpers/get_apm_index_template_names';
@@ -19,7 +19,7 @@ export async function getIndexTemplatesByIndexPattern({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const indexPatterns = getApmIndexPatterns([
     apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
index 686fc7cde3170..e597495e171b4 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
@@ -7,7 +7,7 @@
 
 import { compact, uniq } from 'lodash';
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 
 export function getApmIndexPatterns(indices: string[]) {
   return uniq(indices.flatMap((index): string[] => index.split(',')));
@@ -18,7 +18,7 @@ export async function getIndicesAndIngestPipelines({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const indices = await esClient.indices.get({
     index: getApmIndexPatterns([
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
index 4aeaee5db5349..5a95cec4f2e6b 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
@@ -6,7 +6,7 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { SERVICE_NAME } from '../../../../common/es_fields/apm';
 import { getApmIndexTemplateNames } from '../helpers/get_apm_index_template_names';
 import { getFieldCaps } from './get_field_caps';
@@ -17,7 +17,7 @@ export async function getIndicesStates({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const { indices, ingestPipelines } = await getIndicesAndIngestPipelines({
     esClient,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
index 31629d5644eda..f2507657229a1 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
@@ -6,7 +6,7 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getApmIndexPatterns } from './get_indices';
 
 export async function getNonDataStreamIndices({
@@ -14,7 +14,7 @@ export async function getNonDataStreamIndices({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const apmIndexPatterns = getApmIndexPatterns([
     apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts b/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
index f00af8454fbe8..1fa6ae4fdba11 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
@@ -6,8 +6,8 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { NOT_AVAILABLE_LABEL } from '../../../common/i18n';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
 import { getDataStreams } from './bundle/get_data_streams';
 import { getNonDataStreamIndices } from './bundle/get_non_data_stream_indices';
 import { getElasticsearchVersion } from './get_elasticsearch_version';
@@ -30,7 +30,7 @@ export async function getDiagnosticsBundle({
   kuery,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
   start: number | undefined;
   end: number | undefined;
   kuery: string | undefined;
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts b/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
index 15d0dcb76a101..bbfc30c76ad7a 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
@@ -6,7 +6,7 @@
  */
 
 import { FleetUnauthorizedError } from '@kbn/fleet-plugin/server/errors';
-import { APMRouteHandlerResources } from '../typings';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
 
 export async function getFleetPackageInfo(resources: APMRouteHandlerResources) {
   const fleetPluginStart = await resources.plugins.fleet?.start();
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts b/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
index 9531d3dfde3a6..6d42658d3ac24 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
@@ -6,7 +6,7 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { getApmIndexPatterns } from '../bundle/get_indices';
 
 export async function getDiagnosticsPrivileges({
@@ -14,7 +14,7 @@ export async function getDiagnosticsPrivileges({
   apmIndices,
 }: {
   esClient: ElasticsearchClient;
-  apmIndices: ApmIndicesConfig;
+  apmIndices: APMIndices;
 }) {
   const indexPatterns = getApmIndexPatterns([
     apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/route.ts b/x-pack/plugins/apm/server/routes/diagnostics/route.ts
index 390e7bfa51f36..fcd41df55afc7 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/route.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/route.ts
@@ -13,13 +13,10 @@ import {
   IngestGetPipelineResponse,
   SecurityHasPrivilegesPrivileges,
 } from '@elastic/elasticsearch/lib/api/types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import * as t from 'io-ts';
 import { isoToEpochRt } from '@kbn/io-ts-utils';
 import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
-import {
-  ApmIndicesConfig,
-  getApmIndices,
-} from '../settings/apm_indices/get_apm_indices';
 import { ApmEvent } from './bundle/get_apm_events';
 import { getDiagnosticsBundle } from './get_diagnostics_bundle';
 import { getFleetPackageInfo } from './get_fleet_package_info';
@@ -38,6 +35,49 @@ export interface IndiciesItem {
   isValid: boolean;
 }
 
+export type DiagnosticsBundle = Promise<{
+  esResponses: {
+    existingIndexTemplates: IndicesGetIndexTemplateIndexTemplateItem[];
+    fieldCaps: FieldCapsResponse;
+    indices: IndicesGetResponse;
+    ingestPipelines: IngestGetPipelineResponse;
+  };
+  diagnosticsPrivileges: {
+    index: Record<string, SecurityHasPrivilegesPrivileges>;
+    cluster: Record<string, boolean>;
+    hasAllClusterPrivileges: boolean;
+    hasAllIndexPrivileges: boolean;
+    hasAllPrivileges: boolean;
+  };
+  apmIndices: APMIndices;
+  apmIndexTemplates: Array<{
+    name: string;
+    isNonStandard: boolean;
+    exists: boolean;
+  }>;
+  fleetPackageInfo: {
+    isInstalled: boolean;
+    version?: string;
+  };
+  kibanaVersion: string;
+  elasticsearchVersion: string;
+  apmEvents: ApmEvent[];
+  invalidIndices: IndiciesItem[];
+  validIndices: IndiciesItem[];
+  dataStreams: IndicesDataStream[];
+  nonDataStreamIndices: string[];
+  indexTemplatesByIndexPattern: Array<{
+    indexPattern: string;
+    indexTemplates: Array<{
+      priority: number | undefined;
+      isNonStandard: boolean;
+      templateIndexPatterns: string[];
+      templateName: string;
+    }>;
+  }>;
+  params: { start: number; end: number; kuery?: string };
+}>;
+
 const getDiagnosticsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/diagnostics',
   options: { tags: ['access:apm'] },
@@ -64,7 +104,7 @@ const getDiagnosticsRoute = createApmServerRoute({
       hasAllIndexPrivileges: boolean;
       hasAllPrivileges: boolean;
     };
-    apmIndices: ApmIndicesConfig;
+    apmIndices: APMIndices;
     apmIndexTemplates: Array<{
       name: string;
       isNonStandard: boolean;
@@ -94,11 +134,8 @@ const getDiagnosticsRoute = createApmServerRoute({
   }> => {
     const { start, end, kuery } = resources.params.query;
     const coreContext = await resources.context.core;
+    const apmIndices = await resources.getApmIndices();
     const { asCurrentUser: esClient } = coreContext.elasticsearch.client;
-    const apmIndices = await getApmIndices({
-      savedObjectsClient: coreContext.savedObjects.client,
-      config: resources.config,
-    });
 
     const bundle = await getDiagnosticsBundle({
       esClient,
diff --git a/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts b/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
index 7f69b7525e214..fbc365f775ddd 100644
--- a/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
@@ -9,7 +9,7 @@ import { CoreStart, Logger } from '@kbn/core/server';
 import {
   APM_AGENT_CONFIGURATION_INDEX,
   APM_SOURCE_MAP_INDEX,
-} from '../../settings/apm_indices/get_apm_indices';
+} from '../../settings/apm_indices/apm_system_index_constants';
 
 const apiKeyMetadata = {
   application: 'apm',
diff --git a/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts b/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
index 13815779c6013..9008fabdd3e3b 100644
--- a/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
@@ -5,7 +5,11 @@
  * 2.0.
  */
 
-import { Logger, CoreStart } from '@kbn/core/server';
+import {
+  Logger,
+  CoreStart,
+  SavedObjectsClientContract,
+} from '@kbn/core/server';
 import {
   FleetStartContract,
   PostPackagePolicyCreateCallback,
@@ -14,7 +18,7 @@ import {
   PutPackagePolicyUpdateCallback,
 } from '@kbn/fleet-plugin/server';
 import { get } from 'lodash';
-import { APMConfig, APMPlugin, APMRouteHandlerResources } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { decoratePackagePolicyWithAgentConfigAndSourceMap } from './merge_package_policy_with_apm';
 import { addApiKeysToPackagePolicyIfMissing } from './api_keys/add_api_keys_to_policies_if_missing';
 import {
@@ -23,33 +27,41 @@ import {
 } 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({
   logger,
   coreStartPromise,
   plugins,
-  config,
 }: {
   logger: Logger;
   coreStartPromise: Promise<CoreStart>;
   plugins: APMRouteHandlerResources['plugins'];
-  config: NonNullable<APMPlugin['currentConfig']>;
 }) {
   if (!plugins.fleet) {
     return;
   }
 
   const fleetPluginStart = await plugins.fleet.start();
+  const { getApmIndices } = plugins.apmDataAccess.setup;
   const coreStart = await coreStartPromise;
 
   fleetPluginStart.registerExternalCallback(
     'packagePolicyUpdate',
-    onPackagePolicyCreateOrUpdate({ fleetPluginStart, config, coreStart })
+    onPackagePolicyCreateOrUpdate({
+      fleetPluginStart,
+      getApmIndices,
+      coreStart,
+    })
   );
 
   fleetPluginStart.registerExternalCallback(
     'packagePolicyCreate',
-    onPackagePolicyCreateOrUpdate({ fleetPluginStart, config, coreStart })
+    onPackagePolicyCreateOrUpdate({
+      fleetPluginStart,
+      getApmIndices,
+      coreStart,
+    })
   );
 
   fleetPluginStart.registerExternalCallback(
@@ -143,11 +155,11 @@ function onPackagePolicyPostCreate({
  */
 function onPackagePolicyCreateOrUpdate({
   fleetPluginStart,
-  config,
+  getApmIndices,
   coreStart,
 }: {
   fleetPluginStart: FleetStartContract;
-  config: APMConfig;
+  getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMIndices>;
   coreStart: CoreStart;
 }): PutPackagePolicyUpdateCallback & PostPackagePolicyCreateCallback {
   return async (packagePolicy) => {
@@ -157,10 +169,11 @@ function onPackagePolicyCreateOrUpdate({
 
     const { asInternalUser } = coreStart.elasticsearch.client;
     const savedObjectsClient = await getInternalSavedObjectsClient(coreStart);
+    const apmIndices = await getApmIndices(savedObjectsClient);
+
     const internalESClient = await createInternalESClient({
       debug: false,
-      config,
-      savedObjectsClient,
+      apmIndices,
       elasticsearchClient: asInternalUser,
     });
 
diff --git a/x-pack/plugins/apm/server/routes/fleet/route.ts b/x-pack/plugins/apm/server/routes/fleet/route.ts
index 592042b30c56e..3223d71a77b49 100644
--- a/x-pack/plugins/apm/server/routes/fleet/route.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/route.ts
@@ -153,11 +153,13 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({
       coreStart,
       fleetPluginStart,
       securityPluginStart,
+      apmIndices,
     ] = await Promise.all([
       (await context.core).savedObjects.client,
       resources.core.start(),
       plugins.fleet.start(),
       plugins.security.start(),
+      resources.getApmIndices(),
     ]);
 
     const esClient = coreStart.elasticsearch.client.asScoped(
@@ -174,7 +176,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({
       context,
       request,
       debug: resources.params.query._inspect,
-      config: resources.config,
+      apmIndices,
     });
 
     const cloudApmPackagePolicy = await createCloudApmPackgePolicy({
diff --git a/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts b/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
index 072d280200850..124350a70c093 100644
--- a/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
@@ -6,7 +6,7 @@
  */
 
 import { PackagePolicy } from '@kbn/fleet-plugin/common';
-import { APMRouteHandlerResources } from '../typings';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
 import { getApmPackagePolicies } from './get_apm_package_policies';
 import {
   getApmPackagePolicy,
diff --git a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
index 01cb73ebeedf9..8d503628d6c1a 100644
--- a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
+++ b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
@@ -6,8 +6,8 @@
  */
 
 import { ProcessorEvent } from '@kbn/observability-plugin/common';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
 
 export interface HasDataResponse {
   hasData: boolean;
@@ -24,7 +24,7 @@ export async function getHasData({
   indices,
   apmEventClient,
 }: {
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
   apmEventClient: APMEventClient;
 }): Promise<HasDataResponse> {
   try {
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
index 4aebdfaf03e6a..b6d1e153c5e73 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
@@ -10,7 +10,7 @@ import {
   createOrUpdateIndex,
   Mappings,
 } from '@kbn/observability-plugin/server';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export async function createApmAgentConfigurationIndex({
   client,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
index 5520b51137235..3839949df6cc4 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
@@ -14,7 +14,7 @@ import {
   APMIndexDocumentParams,
   APMInternalESClient,
 } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export function createOrUpdateConfiguration({
   configurationId,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
index d0897fb48941b..fc49660cd53e1 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
@@ -6,7 +6,7 @@
  */
 
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export async function deleteConfiguration({
   configurationId,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
index 3d65d534e9545..3cd71c1d29027 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
@@ -12,7 +12,7 @@ import {
   SERVICE_NAME,
 } from '../../../../common/es_fields/apm';
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 import { convertConfigSettingsToString } from './convert_settings_to_string';
 import { getConfigsAppliedToAgentsThroughFleet } from './get_config_applied_to_agent_through_fleet';
 
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
index 3e588a5c8d9e5..67286f3413e36 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
@@ -11,7 +11,7 @@ import {
 } from '../../../../../common/es_fields/apm';
 import { ALL_OPTION_VALUE } from '../../../../../common/agent_configuration/all_option';
 import { APMInternalESClient } from '../../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../../apm_indices/apm_system_index_constants';
 
 export async function getExistingEnvironmentsForService({
   serviceName,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
index 6a7e53097945e..1cca702dfb45f 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
@@ -9,7 +9,7 @@ import { AgentConfiguration } from '../../../../common/agent_configuration/confi
 import { convertConfigSettingsToString } from './convert_settings_to_string';
 import { getConfigsAppliedToAgentsThroughFleet } from './get_config_applied_to_agent_through_fleet';
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export async function listConfigurations(
   internalESClient: APMInternalESClient
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
index 6b32bbacd3b2a..33a97a3a85ed4 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
@@ -7,7 +7,7 @@
 
 import { AgentConfiguration } from '../../../../common/agent_configuration/configuration_types';
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 // We're not wrapping this function with a span as it is not blocking the request
 export async function markAppliedByAgent({
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
index ffadf970dc414..c11eba5ac7740 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
@@ -49,13 +49,14 @@ const agentConfigurationRoute = createApmServerRoute({
   }> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
-    const { context, request, params, config } = resources;
+    const { context, request, params } = resources;
+    const apmIndices = await resources.getApmIndices();
 
     const internalESClient = await createInternalESClientWithContext({
       context,
       request,
       debug: params.query._inspect,
-      config,
+      apmIndices,
     });
 
     const configurations = await listConfigurations(internalESClient);
@@ -74,15 +75,16 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({
   handler: async (resources): Promise<AgentConfiguration> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
-    const { params, logger, context, request, config } = resources;
+    const { params, logger, context, request } = resources;
     const { name, environment, _inspect } = params.query;
     const service = { name, environment };
+    const apmIndices = await resources.getApmIndices();
 
     const internalESClient = await createInternalESClientWithContext({
       context,
       request,
       debug: _inspect,
-      config,
+      apmIndices,
     });
     const exactConfig = await findExactConfiguration({
       service,
@@ -115,22 +117,16 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
   handler: async (resources): Promise<{ result: string }> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
-    const {
-      params,
-      logger,
-      core,
-      telemetryUsageCounter,
-      context,
-      request,
-      config,
-    } = resources;
+    const { params, logger, core, telemetryUsageCounter, context, request } =
+      resources;
     const { service } = params.body;
+    const apmIndices = await resources.getApmIndices();
 
     const internalESClient = await createInternalESClientWithContext({
       context,
       request,
       debug: params.query._inspect,
-      config,
+      apmIndices,
     });
     const exactConfig = await findExactConfiguration({
       service,
@@ -181,22 +177,16 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
   ]),
   handler: async (resources): Promise<void> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
-    const {
-      params,
-      logger,
-      core,
-      telemetryUsageCounter,
-      context,
-      request,
-      config,
-    } = resources;
+    const { params, logger, core, telemetryUsageCounter, context, request } =
+      resources;
     const { body, query } = params;
+    const apmIndices = await resources.getApmIndices();
 
     const internalESClient = await createInternalESClientWithContext({
       context,
       request,
       debug: params.query._inspect,
-      config,
+      apmIndices,
     });
 
     // if the config already exists, it is fetched and updated
@@ -258,19 +248,20 @@ const agentConfigurationSearchRoute = createApmServerRoute({
   ): Promise<SearchHit<AgentConfiguration, undefined, undefined> | null> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
-    const { params, logger, context, config, request } = resources;
+    const { params, logger, context, request } = resources;
 
     const {
       service,
       etag,
       mark_as_applied_by_agent: markAsAppliedByAgent,
     } = params.body;
+    const apmIndices = await resources.getApmIndices();
 
     const internalESClient = await createInternalESClientWithContext({
       context,
       request,
       debug: params.query._inspect,
-      config,
+      apmIndices,
     });
     const configuration = await searchConfigurations({
       service,
@@ -332,12 +323,14 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
     const { context, request, params, config } = resources;
+    const apmIndices = await resources.getApmIndices();
+
     const [internalESClient, apmEventClient] = await Promise.all([
       createInternalESClientWithContext({
         context,
         request,
         debug: params.query._inspect,
-        config,
+        apmIndices,
       }),
       getApmEventClient(resources),
     ]);
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
index 77da47b62c1c8..f2673433791e3 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
@@ -13,7 +13,7 @@ import {
 import { AgentConfiguration } from '../../../../common/agent_configuration/configuration_types';
 import { convertConfigSettingsToString } from './convert_settings_to_string';
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export async function searchConfigurations({
   service,
diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
index 451ec87bc3670..8ad3d6bb92b6c 100644
--- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
@@ -21,7 +21,6 @@ import { updateToV3 } from './update_to_v3';
 import { environmentStringRt } from '../../../../common/environment_rt';
 import { getMlJobsWithAPMGroup } from '../../../lib/anomaly_detection/get_ml_jobs_with_apm_group';
 import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client';
-import { getApmIndices } from '../apm_indices/get_apm_indices';
 import { ApmMlJob } from '../../../../common/anomaly_detection/apm_ml_job';
 // get ML anomaly detection jobs for each environment
 const anomalyDetectionJobsRoute = createApmServerRoute({
@@ -68,18 +67,14 @@ const createAnomalyDetectionJobsRoute = createApmServerRoute({
     }),
   }),
   handler: async (resources): Promise<{ jobCreated: true }> => {
-    const { params, context, logger, config } = resources;
+    const { params, context, logger, getApmIndices } = resources;
     const { environments } = params.body;
     const licensingContext = await context.licensing;
-    const coreContext = await context.core;
     const esClient = (await context.core).elasticsearch.client;
 
     const [mlClient, indices] = await Promise.all([
       getMlClient(resources),
-      getApmIndices({
-        savedObjectsClient: coreContext.savedObjects.client,
-        config,
-      }),
+      getApmIndices(),
     ]);
 
     if (!isActivePlatinumLicense(licensingContext.license)) {
@@ -142,9 +137,9 @@ const anomalyDetectionUpdateToV3Route = createApmServerRoute({
     ],
   },
   handler: async (resources): Promise<{ update: boolean }> => {
-    const { config, context } = resources;
-    const coreContext = await context.core;
-    const [mlClient, esClient, indices] = await Promise.all([
+    const { getApmIndices } = resources;
+    const [indices, mlClient, esClient] = await Promise.all([
+      getApmIndices(),
       getMlClient(resources),
       resources.core
         .start()
@@ -152,10 +147,6 @@ const anomalyDetectionUpdateToV3Route = createApmServerRoute({
           (start): ElasticsearchClient =>
             start.elasticsearch.client.asInternalUser
         ),
-      getApmIndices({
-        config,
-        savedObjectsClient: coreContext.savedObjects.client,
-      }),
     ]);
 
     const { logger } = resources;
diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
index 32ab3815dd307..577273cbfb03c 100644
--- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
+++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
@@ -9,11 +9,11 @@ import { uniq } from 'lodash';
 import pLimit from 'p-limit';
 import { ElasticsearchClient } from '@kbn/core/server';
 import { JOB_STATE } from '@kbn/ml-plugin/common';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { createAnomalyDetectionJobs } from '../../../lib/anomaly_detection/create_anomaly_detection_jobs';
 import { getAnomalyDetectionJobs } from '../../../lib/anomaly_detection/get_anomaly_detection_jobs';
 import { MlClient } from '../../../lib/helpers/get_ml_client';
 import { withApmSpan } from '../../../utils/with_apm_span';
-import { ApmIndicesConfig } from '../apm_indices/get_apm_indices';
 
 export async function updateToV3({
   logger,
@@ -23,7 +23,7 @@ export async function updateToV3({
 }: {
   logger: Logger;
   mlClient?: MlClient;
-  indices: ApmIndicesConfig;
+  indices: APMIndices;
   esClient: ElasticsearchClient;
 }) {
   const allJobs = await getAnomalyDetectionJobs(mlClient);
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts
new file mode 100644
index 0000000000000..bd74af0536ba7
--- /dev/null
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts
@@ -0,0 +1,10 @@
+/*
+ * 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.
+ */
+
+export const APM_AGENT_CONFIGURATION_INDEX = '.apm-agent-configuration';
+export const APM_CUSTOM_LINK_INDEX = '.apm-custom-link';
+export const APM_SOURCE_MAP_INDEX = '.apm-source-map';
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
index b652fcde39d13..b6a1cd750f102 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
@@ -5,71 +5,8 @@
  * 2.0.
  */
 
-import { SavedObjectsClient } from '@kbn/core/server';
-import {
-  APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-  APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
-} from '../../../../common/apm_saved_object_constants';
-import { APMConfig } from '../../..';
-import { APMRouteHandlerResources } from '../../typings';
-import { withApmSpan } from '../../../utils/with_apm_span';
-import { APMIndices } from '../../../saved_objects/apm_indices';
-
-export type ApmIndicesConfig = Readonly<{
-  error: string;
-  onboarding: string;
-  span: string;
-  transaction: string;
-  metric: string;
-}>;
-
-export const APM_AGENT_CONFIGURATION_INDEX = '.apm-agent-configuration';
-export const APM_CUSTOM_LINK_INDEX = '.apm-custom-link';
-export const APM_SOURCE_MAP_INDEX = '.apm-source-map';
-
-type ISavedObjectsClient = Pick<SavedObjectsClient, 'get'>;
-
-async function getApmIndicesSavedObject(
-  savedObjectsClient: ISavedObjectsClient
-) {
-  const apmIndicesSavedObject = await withApmSpan(
-    'get_apm_indices_saved_object',
-    () =>
-      savedObjectsClient.get<Partial<APMIndices>>(
-        APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-        APM_INDEX_SETTINGS_SAVED_OBJECT_ID
-      )
-  );
-  return apmIndicesSavedObject.attributes.apmIndices;
-}
-
-export function getApmIndicesConfig(config: APMConfig): ApmIndicesConfig {
-  return {
-    error: config.indices.error,
-    onboarding: config.indices.onboarding,
-    span: config.indices.span,
-    transaction: config.indices.transaction,
-    metric: config.indices.metric,
-  };
-}
-
-export async function getApmIndices({
-  config,
-  savedObjectsClient,
-}: {
-  config: APMConfig;
-  savedObjectsClient: ISavedObjectsClient;
-}): Promise<ApmIndicesConfig> {
-  try {
-    const apmIndicesSavedObject = await getApmIndicesSavedObject(
-      savedObjectsClient
-    );
-    const apmIndicesConfig = getApmIndicesConfig(config);
-    return { ...apmIndicesConfig, ...apmIndicesSavedObject };
-  } catch (error) {
-    return getApmIndicesConfig(config);
-  }
-}
+import { getApmIndicesSavedObject } from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
+import { APMRouteHandlerResources } from '../../apm_routes/register_apm_server_routes';
 
 export type ApmIndexSettingsResponse = Array<{
   configurationName: 'transaction' | 'span' | 'error' | 'metric' | 'onboarding';
@@ -77,35 +14,21 @@ export type ApmIndexSettingsResponse = Array<{
   savedValue: string | undefined;
 }>;
 
-export async function getApmIndexSettings({
-  context,
-  config,
-}: Pick<
-  APMRouteHandlerResources,
-  'context' | 'config'
->): Promise<ApmIndexSettingsResponse> {
-  let apmIndicesSavedObject: Awaited<
-    ReturnType<typeof getApmIndicesSavedObject>
-  >;
-  try {
-    const soClient = (await context.core).savedObjects.client;
-    apmIndicesSavedObject = await getApmIndicesSavedObject(soClient);
-  } catch (error: any) {
-    if (error.output && error.output.statusCode === 404) {
-      apmIndicesSavedObject = {};
-    } else {
-      throw error;
-    }
-  }
-  const apmIndicesConfig = getApmIndicesConfig(config);
+export async function getApmIndexSettings(
+  resources: APMRouteHandlerResources
+): Promise<ApmIndexSettingsResponse> {
+  const { apmIndicesFromConfigFile } = resources.plugins.apmDataAccess.setup;
+
+  const soClient = (await resources.context.core).savedObjects.client;
+  const apmIndicesSavedObject = await getApmIndicesSavedObject(soClient);
 
-  const apmIndices = Object.keys(config.indices) as Array<
-    keyof typeof config.indices
+  const apmIndicesKeys = Object.keys(apmIndicesFromConfigFile) as Array<
+    keyof typeof apmIndicesFromConfigFile
   >;
 
-  return apmIndices.map((configurationName) => ({
+  return apmIndicesKeys.map((configurationName) => ({
     configurationName,
-    defaultValue: apmIndicesConfig[configurationName], // value defined in kibana[.dev].yml
+    defaultValue: apmIndicesFromConfigFile[configurationName], // value defined in kibana[.dev].yml
     savedValue: apmIndicesSavedObject?.[configurationName], // value saved via Saved Objects service
   }));
 }
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
index 24b6d48e92314..434ae4785ce5a 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
@@ -7,27 +7,24 @@
 
 import * as t from 'io-ts';
 import { SavedObject } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { createApmServerRoute } from '../../apm_routes/create_apm_server_route';
 import {
-  getApmIndices,
   getApmIndexSettings,
   ApmIndexSettingsResponse,
-  ApmIndicesConfig,
 } from './get_apm_indices';
 import { saveApmIndices } from './save_apm_indices';
-import { APMConfig } from '../../..';
 
 // get list of apm indices and values
 const apmIndexSettingsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/apm-index-settings',
   options: { tags: ['access:apm'] },
-  handler: async ({
-    config,
-    context,
-  }): Promise<{
+  handler: async (
+    resources
+  ): Promise<{
     apmIndexSettings: ApmIndexSettingsResponse;
   }> => {
-    const apmIndexSettings = await getApmIndexSettings({ config, context });
+    const apmIndexSettings = await getApmIndexSettings(resources);
     return { apmIndexSettings };
   },
 });
@@ -36,18 +33,13 @@ const apmIndexSettingsRoute = createApmServerRoute({
 const apmIndicesRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/apm-indices',
   options: { tags: ['access:apm'] },
-  handler: async (resources): Promise<ApmIndicesConfig> => {
-    const { context, config } = resources;
-    const savedObjectsClient = (await context.core).savedObjects.client;
-    return await getApmIndices({
-      savedObjectsClient,
-      config,
-    });
+  handler: async (resources): Promise<APMIndices> => {
+    return await resources.getApmIndices();
   },
 });
 
 type SaveApmIndicesBodySchema = {
-  [Property in keyof APMConfig['indices']]: t.StringC;
+  [Property in keyof APMIndices]: t.StringC;
 };
 
 // save ui indices
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
index a5926c6dfc0cb..e9d2bd5fbea92 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
@@ -6,20 +6,20 @@
  */
 
 import { SavedObjectsClientContract } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
-  APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+  APMIndicesSavedObjectBody,
   APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
-} from '../../../../common/apm_saved_object_constants';
-import { APMIndices } from '../../../saved_objects/apm_indices';
+  APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+} from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
 import { withApmSpan } from '../../../utils/with_apm_span';
-import { ApmIndicesConfig } from './get_apm_indices';
 
 export function saveApmIndices(
   savedObjectsClient: SavedObjectsClientContract,
-  apmIndices: Partial<ApmIndicesConfig>
+  apmIndices: Partial<APMIndices>
 ) {
   return withApmSpan('save_apm_indices', () =>
-    savedObjectsClient.create<APMIndices>(
+    savedObjectsClient.create<APMIndicesSavedObjectBody>(
       APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
       { apmIndices: removeEmpty(apmIndices), isSpaceAware: true },
       { id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID, overwrite: true }
@@ -28,7 +28,7 @@ export function saveApmIndices(
 }
 
 // remove empty/undefined values
-function removeEmpty(apmIndices: Partial<ApmIndicesConfig>) {
+function removeEmpty(apmIndices: Partial<APMIndices>) {
   return Object.entries(apmIndices)
     .map(([key, value]) => [key, value?.trim()])
     .filter(([_, value]) => !!value)
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
index b8bfc3b3f2f72..ba3b06f6dbbc9 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
@@ -11,7 +11,7 @@ import {
   createOrUpdateIndex,
   Mappings,
 } from '@kbn/observability-plugin/server';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export const createApmCustomLinkIndex = async ({
   client,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
index 979c16ad53473..e70b5257a7680 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
@@ -14,7 +14,7 @@ import {
   APMIndexDocumentParams,
   APMInternalESClient,
 } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export function createOrUpdateCustomLink({
   customLinkId,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
index 16318fe696712..cc000ceda963f 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
@@ -6,7 +6,7 @@
  */
 
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export function deleteCustomLink({
   customLinkId,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
index 27b7c08ca9a4b..38d371e0a5b6d 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
@@ -14,7 +14,7 @@ import {
 import { fromESFormat } from './helper';
 import { filterOptionsRt } from './custom_link_types';
 import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
 
 export async function listCustomLinks({
   internalESClient,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
index 7e79a2d241224..1db1d74fb7134 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
@@ -50,8 +50,9 @@ const listCustomLinksRoute = createApmServerRoute({
   ): Promise<{
     customLinks: CustomLink[];
   }> => {
-    const { context, params, request, config } = resources;
+    const { context, params, request } = resources;
     const licensingContext = await context.licensing;
+    const apmIndices = await resources.getApmIndices();
 
     if (!isActiveGoldLicense(licensingContext.license)) {
       throw Boom.forbidden(INVALID_LICENSE);
@@ -63,7 +64,7 @@ const listCustomLinksRoute = createApmServerRoute({
       context,
       request,
       debug: resources.params.query._inspect,
-      config,
+      apmIndices,
     });
 
     // picks only the items listed in FILTER_OPTIONS
@@ -83,8 +84,9 @@ const createCustomLinkRoute = createApmServerRoute({
   }),
   options: { tags: ['access:apm', 'access:apm_write'] },
   handler: async (resources): Promise<void> => {
-    const { context, params, request, config } = resources;
+    const { context, params, request } = resources;
     const licensingContext = await context.licensing;
+    const apmIndices = await resources.getApmIndices();
 
     if (!isActiveGoldLicense(licensingContext.license)) {
       throw Boom.forbidden(INVALID_LICENSE);
@@ -94,7 +96,7 @@ const createCustomLinkRoute = createApmServerRoute({
       context,
       request,
       debug: resources.params.query._inspect,
-      config,
+      apmIndices,
     });
     const customLink = params.body;
 
@@ -119,8 +121,9 @@ const updateCustomLinkRoute = createApmServerRoute({
     tags: ['access:apm', 'access:apm_write'],
   },
   handler: async (resources): Promise<void> => {
-    const { params, context, request, config } = resources;
+    const { params, context, request } = resources;
     const licensingContext = await context.licensing;
+    const apmIndices = await resources.getApmIndices();
 
     if (!isActiveGoldLicense(licensingContext.license)) {
       throw Boom.forbidden(INVALID_LICENSE);
@@ -130,7 +133,7 @@ const updateCustomLinkRoute = createApmServerRoute({
       context,
       request,
       debug: resources.params.query._inspect,
-      config,
+      apmIndices,
     });
 
     const { id } = params.path;
@@ -155,8 +158,9 @@ const deleteCustomLinkRoute = createApmServerRoute({
     tags: ['access:apm', 'access:apm_write'],
   },
   handler: async (resources): Promise<{ result: string }> => {
-    const { context, params, request, config } = resources;
+    const { context, params, request } = resources;
     const licensingContext = await context.licensing;
+    const apmIndices = await resources.getApmIndices();
 
     if (!isActiveGoldLicense(licensingContext.license)) {
       throw Boom.forbidden(INVALID_LICENSE);
@@ -166,7 +170,7 @@ const deleteCustomLinkRoute = createApmServerRoute({
       context,
       request,
       debug: resources.params.query._inspect,
-      config,
+      apmIndices,
     });
     const { id } = params.path;
     const res = await deleteCustomLink({
diff --git a/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts b/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
index 5cc9f93e49b7b..3aa5c9a780aa3 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
@@ -8,7 +8,7 @@
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
 import { Artifact } from '@kbn/fleet-plugin/server';
 import { getUnzippedArtifactBody } from '../fleet/source_maps';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
 import { ApmSourceMap } from './create_apm_source_map_index_template';
 import { getEncodedSourceMapContent, getSourceMapId } from './sourcemap_utils';
 
diff --git a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
index 132a92a225187..bda2601080434 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
@@ -7,7 +7,7 @@
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
 import { Logger } from '@kbn/core/server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
 import { ApmSourceMap } from './create_apm_source_map_index_template';
 import { SourceMap } from './route';
 import {
diff --git a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
index 4fa24358e7b07..c99e834b65483 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
@@ -8,7 +8,7 @@
 import { IndicesPutIndexTemplateRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
 import { ElasticsearchClient, Logger } from '@kbn/core/server';
 import { createOrUpdateIndexTemplate } from '@kbn/observability-plugin/server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
 
 const indexTemplate: IndicesPutIndexTemplateRequest = {
   name: 'apm-source-map',
diff --git a/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts b/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
index ffdaf02c165d8..2f4723f9e470f 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
@@ -6,7 +6,7 @@
  */
 
 import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
 
 export async function deleteApmSourceMap({
   internalESClient,
diff --git a/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts b/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
index 3ab48db456845..71f1e3af0b5c2 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
@@ -12,7 +12,7 @@ import { TaskManagerSetupContract } from '@kbn/task-manager-plugin/server';
 import { CoreStart, Logger } from '@kbn/core/server';
 import { getApmArtifactClient } from '../fleet/source_maps';
 import { bulkCreateApmSourceMaps } from './bulk_create_apm_source_maps';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
 import { ApmSourceMap } from './create_apm_source_map_index_template';
 import { APMPluginStartDependencies } from '../../types';
 import { createApmSourceMapIndexTemplate } from './create_apm_source_map_index_template';
diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts b/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
index edb28d9bfa490..21b5b163e7663 100644
--- a/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
+++ b/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
@@ -6,7 +6,7 @@
  */
 
 import { isCrossClusterSearch } from './is_cross_cluster_search';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
 
 describe('isCrossClusterSearch', () => {
@@ -17,7 +17,7 @@ describe('isCrossClusterSearch', () => {
         span: 'traces-apm*',
         metric: 'metrics-apm*',
         error: 'logs-apm*',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -30,7 +30,7 @@ describe('isCrossClusterSearch', () => {
         span: 'traces-apm*,test-apm*',
         metric: 'metrics-apm*,test-apm*',
         error: 'logs-apm*,test-apm*',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -44,7 +44,7 @@ describe('isCrossClusterSearch', () => {
         metric: '',
         error: '',
         onboarding: 'apm-*,remote_cluster:apm-*',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -57,7 +57,7 @@ describe('isCrossClusterSearch', () => {
         span: '',
         metric: '',
         error: '',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -70,7 +70,7 @@ describe('isCrossClusterSearch', () => {
         span: 'traces-apm*,remote_cluster:traces-apm*',
         metric: '',
         error: '',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -83,7 +83,7 @@ describe('isCrossClusterSearch', () => {
         span: '',
         metric: 'metrics-apm*,remote_cluster:metrics-apm*',
         error: '',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -96,7 +96,7 @@ describe('isCrossClusterSearch', () => {
         span: '',
         metric: '',
         error: 'logs-apm*,remote_cluster:logs-apm*',
-      } as ApmIndicesConfig,
+      } as APMIndices,
     } as unknown as APMEventClient;
 
     expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
diff --git a/x-pack/plugins/apm/server/routes/typings.ts b/x-pack/plugins/apm/server/routes/typings.ts
index 6e83404b2c905..c25d30cdb77e4 100644
--- a/x-pack/plugins/apm/server/routes/typings.ts
+++ b/x-pack/plugins/apm/server/routes/typings.ts
@@ -8,22 +8,13 @@
 import {
   CoreSetup,
   CustomRequestHandlerContext,
-  Logger,
-  KibanaRequest,
   CoreStart,
   RouteConfigOptions,
 } from '@kbn/core/server';
-import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
 import { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server';
 import type { RacApiRequestHandlerContext } from '@kbn/rule-registry-plugin/server';
 import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server';
 import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
-import { APMConfig } from '..';
-import {
-  APMPluginSetupDependencies,
-  APMPluginStartDependencies,
-} from '../types';
-import { ApmFeatureFlags } from '../../common/apm_feature_flags';
 
 export type ApmPluginRequestHandlerContext = CustomRequestHandlerContext<{
   licensing: LicensingApiRequestHandlerContext;
@@ -54,26 +45,3 @@ export interface APMCore {
   setup: CoreSetup;
   start: () => Promise<CoreStart>;
 }
-
-export interface APMRouteHandlerResources {
-  request: KibanaRequest;
-  context: ApmPluginRequestHandlerContext;
-  params: {
-    query: {
-      _inspect: boolean;
-    };
-  };
-  config: APMConfig;
-  featureFlags: ApmFeatureFlags;
-  logger: Logger;
-  core: APMCore;
-  plugins: {
-    [key in keyof APMPluginSetupDependencies]: {
-      setup: Required<APMPluginSetupDependencies>[key];
-      start: () => Promise<Required<APMPluginStartDependencies>[key]>;
-    };
-  };
-  ruleDataClient: IRuleDataClient;
-  telemetryUsageCounter?: TelemetryUsageCounter;
-  kibanaVersion: string;
-}
diff --git a/x-pack/plugins/apm/server/saved_objects/index.ts b/x-pack/plugins/apm/server/saved_objects/index.ts
index 048db493cb2fa..b39e032ad14bd 100644
--- a/x-pack/plugins/apm/server/saved_objects/index.ts
+++ b/x-pack/plugins/apm/server/saved_objects/index.ts
@@ -5,7 +5,6 @@
  * 2.0.
  */
 
-export { apmIndices } from './apm_indices';
 export { apmTelemetry } from './apm_telemetry';
 export { apmServerSettings } from './apm_server_settings';
 export { apmServiceGroups } from './apm_service_groups';
diff --git a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
index f2804ce645a7f..358f69020598d 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
@@ -11,8 +11,8 @@ import {
   TutorialSchema,
   InstructionSetSchema,
 } from '@kbn/home-plugin/server';
-
 import { CloudSetup } from '@kbn/cloud-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   createNodeAgentInstructions,
   createDjangoAgentInstructions,
@@ -26,16 +26,15 @@ import {
   createPhpAgentInstructions,
   createOpenTelemetryAgentInstructions,
 } from '../../../common/tutorial/instructions/apm_agent_instructions';
-import { APMConfig } from '../..';
 import { getOnPremApmServerInstructionSet } from './on_prem_apm_server_instruction_set';
 
 export function createElasticCloudInstructions({
   cloudSetup,
-  apmConfig,
+  apmIndices,
   isFleetPluginEnabled,
 }: {
   cloudSetup?: CloudSetup;
-  apmConfig: APMConfig;
+  apmIndices: APMIndices;
   isFleetPluginEnabled: boolean;
 }): TutorialSchema['elasticCloud'] {
   const apmServerUrl = cloudSetup?.apm.url;
@@ -46,7 +45,7 @@ export function createElasticCloudInstructions({
   }
 
   instructionSets.push(
-    getOnPremApmServerInstructionSet({ apmConfig, isFleetPluginEnabled })
+    getOnPremApmServerInstructionSet({ apmIndices, isFleetPluginEnabled })
   );
   instructionSets.push(getApmAgentInstructionSet(cloudSetup));
 
diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
index 1780c5bd87bcd..b7a4f4568928d 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
@@ -10,7 +10,7 @@ import {
   INSTRUCTION_VARIANT,
   InstructionsSchema,
 } from '@kbn/home-plugin/server';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   createDjangoAgentInstructions,
   createDotNetAgentInstructions,
@@ -27,15 +27,18 @@ import {
 import { getOnPremApmServerInstructionSet } from './on_prem_apm_server_instruction_set';
 
 export function onPremInstructions({
-  apmConfig,
+  apmIndices,
   isFleetPluginEnabled,
 }: {
-  apmConfig: APMConfig;
+  apmIndices: APMIndices;
   isFleetPluginEnabled: boolean;
 }): InstructionsSchema {
   return {
     instructionSets: [
-      getOnPremApmServerInstructionSet({ apmConfig, isFleetPluginEnabled }),
+      getOnPremApmServerInstructionSet({
+        apmIndices,
+        isFleetPluginEnabled,
+      }),
       {
         title: i18n.translate('xpack.apm.tutorial.apmAgents.title', {
           defaultMessage: 'APM Agents',
@@ -121,9 +124,9 @@ export function onPremInstructions({
           ),
           esHitsCheck: {
             index: [
-              apmConfig.indices.error,
-              apmConfig.indices.transaction,
-              apmConfig.indices.metric,
+              apmIndices.error,
+              apmIndices.transaction,
+              apmIndices.metric,
             ],
             query: {
               bool: {
diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
index 2409c78cf1f37..ce4b1f49a0091 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
@@ -10,7 +10,7 @@ import {
   InstructionsSchema,
   INSTRUCTION_VARIANT,
 } from '@kbn/home-plugin/server';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import {
   createDownloadServerDeb,
   createDownloadServerOsx,
@@ -29,10 +29,10 @@ const START_SERVER_UNIX_SYSV = createStartServerUnixSysv();
 const START_SERVER_UNIX_BINARI = createStartServerUnixBinari();
 
 export function getOnPremApmServerInstructionSet({
-  apmConfig,
+  apmIndices,
   isFleetPluginEnabled,
 }: {
-  apmConfig: APMConfig;
+  apmIndices: APMIndices;
   isFleetPluginEnabled: boolean;
 }): InstructionsSchema['instructionSets'][0] {
   return {
@@ -132,7 +132,7 @@ export function getOnPremApmServerInstructionSet({
         }
       ),
       esHitsCheck: {
-        index: apmConfig.indices.onboarding,
+        index: apmIndices.onboarding,
         query: {
           bool: {
             filter: [{ term: { 'processor.event': 'onboarding' } }],
diff --git a/x-pack/plugins/apm/server/tutorial/index.ts b/x-pack/plugins/apm/server/tutorial/index.ts
index a22919b2f9f39..b8201564f4154 100644
--- a/x-pack/plugins/apm/server/tutorial/index.ts
+++ b/x-pack/plugins/apm/server/tutorial/index.ts
@@ -12,8 +12,8 @@ import {
   TutorialSchema,
 } from '@kbn/home-plugin/server';
 import { CloudSetup } from '@kbn/cloud-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { APMConfig } from '..';
-import { ApmIndicesConfig } from '../routes/settings/apm_indices/get_apm_indices';
 import { createElasticCloudInstructions } from './envs/elastic_cloud';
 import { onPremInstructions } from './envs/on_prem';
 
@@ -31,7 +31,7 @@ export const tutorialProvider =
     isFleetPluginEnabled,
   }: {
     apmConfig: APMConfig;
-    apmIndices: ApmIndicesConfig;
+    apmIndices: APMIndices;
     cloud?: CloudSetup;
     isFleetPluginEnabled: boolean;
   }) =>
@@ -90,9 +90,9 @@ It allows you to monitor the performance of thousands of applications in real ti
       integrationBrowserCategories: ['observability', 'apm'],
       artifacts,
       customStatusCheckName: 'apm_fleet_server_status_check',
-      onPrem: onPremInstructions({ apmConfig, isFleetPluginEnabled }),
+      onPrem: onPremInstructions({ apmIndices, isFleetPluginEnabled }),
       elasticCloud: createElasticCloudInstructions({
-        apmConfig,
+        apmIndices,
         isFleetPluginEnabled,
         cloudSetup: cloud,
       }),
diff --git a/x-pack/plugins/apm/server/types.ts b/x-pack/plugins/apm/server/types.ts
index 51ed7a3a7c0a6..054861a082b44 100644
--- a/x-pack/plugins/apm/server/types.ts
+++ b/x-pack/plugins/apm/server/types.ts
@@ -7,7 +7,6 @@
 
 import { SharePluginSetup } from '@kbn/share-plugin/server';
 import { Observable } from 'rxjs';
-import { KibanaRequest } from '@kbn/core/server';
 import {
   RuleRegistryPluginSetupContract,
   RuleRegistryPluginStartContract,
@@ -16,6 +15,11 @@ import {
   PluginSetup as DataPluginSetup,
   PluginStart as DataPluginStart,
 } from '@kbn/data-plugin/server';
+import {
+  ApmDataAccessPluginSetup,
+  ApmDataAccessPluginStart,
+} from '@kbn/apm-data-access-plugin/server';
+
 import {
   SpacesPluginSetup,
   SpacesPluginStart,
@@ -58,22 +62,14 @@ import {
   CustomIntegrationsPluginStart,
 } from '@kbn/custom-integrations-plugin/server';
 import { APMConfig } from '.';
-import { ApmIndicesConfig } from './routes/settings/apm_indices/get_apm_indices';
-import { APMEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
-import { ApmPluginRequestHandlerContext } from './routes/typings';
 
 export interface APMPluginSetup {
   config$: Observable<APMConfig>;
-  getApmIndices: () => Promise<ApmIndicesConfig>;
-  createApmEventClient: (params: {
-    debug?: boolean;
-    request: KibanaRequest;
-    context: ApmPluginRequestHandlerContext;
-  }) => Promise<APMEventClient>;
 }
 
 export interface APMPluginSetupDependencies {
   // required dependencies
+  apmDataAccess: ApmDataAccessPluginSetup;
   data: DataPluginSetup;
   features: FeaturesPluginSetup;
   licensing: LicensingPluginSetup;
@@ -98,6 +94,7 @@ export interface APMPluginSetupDependencies {
 }
 export interface APMPluginStartDependencies {
   // required dependencies
+  apmDataAccess: ApmDataAccessPluginStart;
   data: DataPluginStart;
   features: FeaturesPluginStart;
   licensing: LicensingPluginStart;
diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx
index c4349ce920e30..807d47fa5a2b9 100644
--- a/x-pack/plugins/apm/server/utils/test_helpers.tsx
+++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx
@@ -6,11 +6,11 @@
  */
 
 import type { ESSearchRequest, ESSearchResponse } from '@kbn/es-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
 import { APMConfig } from '..';
 import { APMEventClient } from '../lib/helpers/create_es_client/create_apm_event_client';
 import { APMInternalESClient } from '../lib/helpers/create_es_client/create_internal_es_client';
 import { ApmAlertsClient } from '../lib/helpers/get_apm_alerts_client';
-import { ApmIndicesConfig } from '../routes/settings/apm_indices/get_apm_indices';
 
 interface Options {
   mockResponse?: (
@@ -30,7 +30,7 @@ export async function inspectSearchParams(
     mockApmEventClient: APMEventClient;
     mockConfig: APMConfig;
     mockInternalESClient: APMInternalESClient;
-    mockIndices: ApmIndicesConfig;
+    mockIndices: APMIndices;
     mockApmAlertsClient: ApmAlertsClient;
   }) => Promise<any>,
   options: Options = {}
@@ -53,7 +53,7 @@ export async function inspectSearchParams(
   let error;
   const mockApmEventClient = { search: spy } as any;
   const indices: {
-    [Property in keyof APMConfig['indices']]: string;
+    [Property in keyof APMIndices]: string;
   } = {
     error: 'myIndex',
     onboarding: 'myIndex',
@@ -61,6 +61,7 @@ export async function inspectSearchParams(
     transaction: 'myIndex',
     metric: 'myIndex',
   };
+
   const mockConfig = new Proxy(
     {},
     {
@@ -73,8 +74,6 @@ export async function inspectSearchParams(
         switch (key) {
           default:
             return 'myIndex';
-          case 'indices':
-            return indices;
           case 'ui':
             return {
               enabled: true,
diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json
index a81771fbd1f6b..1b06fa44a8dd5 100644
--- a/x-pack/plugins/apm/tsconfig.json
+++ b/x-pack/plugins/apm/tsconfig.json
@@ -76,7 +76,6 @@
     "@kbn/babel-register",
     "@kbn/core-saved-objects-migration-server-internal",
     "@kbn/core-elasticsearch-server",
-    "@kbn/core-saved-objects-api-server",
     "@kbn/safer-lodash-set",
     "@kbn/shared-ux-router",
     "@kbn/alerts-as-data-utils",
@@ -96,7 +95,8 @@
     "@kbn/logs-shared-plugin",
     "@kbn/unified-field-list",
     "@kbn/discover-plugin",
-    "@kbn/observability-ai-assistant-plugin"
+    "@kbn/observability-ai-assistant-plugin",
+    "@kbn/apm-data-access-plugin"
   ],
   "exclude": ["target/**/*"]
 }
diff --git a/x-pack/plugins/apm_data_access/common/index.ts b/x-pack/plugins/apm_data_access/common/index.ts
new file mode 100644
index 0000000000000..19d4963c3cec5
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/common/index.ts
@@ -0,0 +1,9 @@
+/*
+ * 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.
+ */
+
+export const PLUGIN_ID = 'apmDataAccess';
+export const PLUGIN_NAME = 'apmDataAccess';
diff --git a/x-pack/plugins/apm_data_access/jest.config.js b/x-pack/plugins/apm_data_access/jest.config.js
new file mode 100644
index 0000000000000..8fb297afcc48e
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/jest.config.js
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ */
+
+const path = require('path');
+
+module.exports = {
+  preset: '@kbn/test',
+  rootDir: path.resolve(__dirname, '../../..'),
+  roots: ['<rootDir>/x-pack/plugins/apm_data_access'],
+};
diff --git a/x-pack/plugins/apm_data_access/kibana.jsonc b/x-pack/plugins/apm_data_access/kibana.jsonc
new file mode 100644
index 0000000000000..d0ee0befda101
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/kibana.jsonc
@@ -0,0 +1,14 @@
+{
+  "type": "plugin",
+  "id": "@kbn/apm-data-access-plugin",
+  "owner": "@elastic/apm-ui",
+  "plugin": {
+    "id": "apmDataAccess",
+    "server": true,
+    "browser": false,
+    "configPath": ["xpack", "apm_data_access"],
+    "requiredPlugins": ["data"],
+    "optionalPlugins": [],
+    "requiredBundles": []
+  }
+}
diff --git a/x-pack/plugins/apm_data_access/server/index.ts b/x-pack/plugins/apm_data_access/server/index.ts
new file mode 100644
index 0000000000000..4d7ae2b1eb6c3
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/index.ts
@@ -0,0 +1,80 @@
+/*
+ * 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 { schema, TypeOf } from '@kbn/config-schema';
+import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
+import { ApmDataAccessPlugin } from './plugin';
+
+const configSchema = schema.object({
+  indices: schema.object({
+    transaction: schema.string({ defaultValue: 'traces-apm*,apm-*' }), // TODO: remove apm-* pattern in 9.0
+    span: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
+    error: schema.string({ defaultValue: 'logs-apm*,apm-*' }),
+    metric: schema.string({ defaultValue: 'metrics-apm*,apm-*' }),
+    onboarding: schema.string({ defaultValue: 'apm-*' }), // Unused: to be deleted
+  }),
+});
+
+// plugin config
+export const config: PluginConfigDescriptor<APMDataAccessConfig> = {
+  deprecations: ({ renameFromRoot, unused, deprecate }) => [
+    // deprecations
+    unused('indices.sourcemap', { level: 'warning' }),
+    deprecate('indices.onboarding', 'a future version', {
+      level: 'warning',
+      message: `Configuring "xpack.apm.indices.onboarding" is deprecated and will be removed in a future version. Please remove this setting.`,
+    }),
+
+    // deprecations due to removal of apm_oss plugin
+    renameFromRoot('apm_oss.transactionIndices', 'xpack.apm.indices.transaction', {
+      level: 'warning',
+    }),
+    renameFromRoot('apm_oss.spanIndices', 'xpack.apm.indices.span', {
+      level: 'warning',
+    }),
+    renameFromRoot('apm_oss.errorIndices', 'xpack.apm.indices.error', {
+      level: 'warning',
+    }),
+    renameFromRoot('apm_oss.metricsIndices', 'xpack.apm.indices.metric', {
+      level: 'warning',
+    }),
+    renameFromRoot('apm_oss.onboardingIndices', 'xpack.apm.indices.onboarding', {
+      level: 'warning',
+    }),
+
+    // rename from apm to apm_data_access plugin
+    renameFromRoot('xpack.apm.indices.transaction', 'xpack.apm_data_access.indices.transaction', {
+      level: 'warning',
+      silent: true,
+    }),
+    renameFromRoot('xpack.apm.indices.span', 'xpack.apm_data_access.indices.span', {
+      level: 'warning',
+    }),
+    renameFromRoot('xpack.apm.indices.error', 'xpack.apm_data_access.indices.error', {
+      level: 'warning',
+    }),
+    renameFromRoot('xpack.apm.indices.metric', 'xpack.apm_data_access.indices.metric', {
+      level: 'warning',
+    }),
+    renameFromRoot('xpack.apm.indices.sourcemap', 'xpack.apm_data_access.indices.sourcemap', {
+      level: 'warning',
+    }),
+    renameFromRoot('xpack.apm.indices.onboarding', 'xpack.apm_data_access.indices.onboarding', {
+      level: 'warning',
+    }),
+  ],
+
+  schema: configSchema,
+};
+export type APMDataAccessConfig = TypeOf<typeof configSchema>;
+export type APMIndices = APMDataAccessConfig['indices'];
+
+export function plugin(initializerContext: PluginInitializerContext) {
+  return new ApmDataAccessPlugin(initializerContext);
+}
+
+export type { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types';
diff --git a/x-pack/plugins/apm_data_access/server/plugin.ts b/x-pack/plugins/apm_data_access/server/plugin.ts
new file mode 100644
index 0000000000000..bba13bc6fea36
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/plugin.ts
@@ -0,0 +1,59 @@
+/*
+ * 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 {
+  PluginInitializerContext,
+  CoreSetup,
+  CoreStart,
+  Plugin,
+  SavedObjectsClientContract,
+} from '@kbn/core/server';
+import { APMDataAccessConfig } from '.';
+import { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types';
+import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware';
+import {
+  apmIndicesSavedObjectDefinition,
+  getApmIndicesSavedObject,
+} from './saved_objects/apm_indices';
+
+export class ApmDataAccessPlugin
+  implements Plugin<ApmDataAccessPluginSetup, ApmDataAccessPluginStart>
+{
+  constructor(private readonly initContext: PluginInitializerContext) {
+    this.initContext = initContext;
+  }
+
+  public setup(core: CoreSetup): ApmDataAccessPluginSetup {
+    // retrieve APM indices from config
+    const apmDataAccessConfig = this.initContext.config.get<APMDataAccessConfig>();
+    const apmIndicesFromConfigFile = apmDataAccessConfig.indices;
+
+    // register saved object
+    core.savedObjects.registerType(apmIndicesSavedObjectDefinition);
+
+    // expose
+    return {
+      apmIndicesFromConfigFile,
+      getApmIndices: async (savedObjectsClient: SavedObjectsClientContract) => {
+        const apmIndicesFromSavedObject = await getApmIndicesSavedObject(savedObjectsClient);
+        return { ...apmIndicesFromConfigFile, ...apmIndicesFromSavedObject };
+      },
+    };
+  }
+
+  public start(core: CoreStart) {
+    const logger = this.initContext.logger.get();
+    // TODO: remove in 9.0
+    migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger }).catch((e) => {
+      logger.error('Failed to run migration making APM indices space aware');
+      logger.error(e);
+    });
+    return {};
+  }
+
+  public stop() {}
+}
diff --git a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts b/x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
similarity index 66%
rename from x-pack/plugins/apm/server/saved_objects/apm_indices.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
index 9a7ab40dfee1a..7ab90ef0a605c 100644
--- a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
@@ -8,9 +8,14 @@
 import { SavedObjectsType } from '@kbn/core/server';
 import { i18n } from '@kbn/i18n';
 import { schema } from '@kbn/config-schema';
+import { SavedObjectsErrorHelpers } from '@kbn/core/server';
+import { SavedObjectsClientContract } from '@kbn/core/server';
 import { updateApmOssIndexPaths } from './migrations/update_apm_oss_index_paths';
 
-export interface APMIndices {
+export const APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE = 'apm-indices';
+export const APM_INDEX_SETTINGS_SAVED_OBJECT_ID = 'apm-indices';
+
+export interface APMIndicesSavedObjectBody {
   apmIndices?: {
     error?: string;
     onboarding?: string;
@@ -21,8 +26,8 @@ export interface APMIndices {
   isSpaceAware?: boolean;
 }
 
-export const apmIndices: SavedObjectsType = {
-  name: 'apm-indices',
+export const apmIndicesSavedObjectDefinition: SavedObjectsType = {
+  name: APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
   hidden: false,
   namespaceType: 'single',
   mappings: {
@@ -33,7 +38,7 @@ export const apmIndices: SavedObjectsType = {
     importableAndExportable: true,
     icon: 'apmApp',
     getTitle: () =>
-      i18n.translate('xpack.apm.apmSettings.index', {
+      i18n.translate('xpack.apmDataAccess.apmSettings.index', {
         defaultMessage: 'APM Settings - Index',
       }),
   },
@@ -67,3 +72,20 @@ export const apmIndices: SavedObjectsType = {
     },
   },
 };
+
+export async function getApmIndicesSavedObject(savedObjectsClient: SavedObjectsClientContract) {
+  try {
+    const apmIndicesSavedObject = await savedObjectsClient.get<Partial<APMIndicesSavedObjectBody>>(
+      APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+      APM_INDEX_SETTINGS_SAVED_OBJECT_ID
+    );
+    return apmIndicesSavedObject.attributes.apmIndices;
+  } catch (error) {
+    // swallow error if saved object does not exist
+    if (SavedObjectsErrorHelpers.isNotFoundError(error)) {
+      return {};
+    }
+
+    throw error;
+  }
+}
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
similarity index 99%
rename from x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
index 4f794d48c3056..8b87b52dee166 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
@@ -8,7 +8,7 @@ import type { CoreStart, Logger } from '@kbn/core/server';
 import {
   APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
   APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-} from '../../../common/apm_saved_object_constants';
+} from '../apm_indices';
 import { migrateLegacyAPMIndicesToSpaceAware } from './migrate_legacy_apm_indices_to_space_aware';
 
 const loggerMock = {
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
similarity index 78%
rename from x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
index 8098318ce61e6..6e1b989146e04 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
@@ -4,22 +4,19 @@
  * 2.0; you may not use this file except in compliance with the Elastic License
  * 2.0.
  */
-import type {
-  CoreStart,
-  Logger,
-  ISavedObjectsRepository,
-} from '@kbn/core/server';
+import type { CoreStart, Logger, ISavedObjectsRepository } from '@kbn/core/server';
 import { SavedObjectsErrorHelpers } from '@kbn/core/server';
+import type { APMIndices } from '../..';
+
 import {
+  APMIndicesSavedObjectBody,
   APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
   APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-} from '../../../common/apm_saved_object_constants';
-import { ApmIndicesConfig } from '../../routes/settings/apm_indices/get_apm_indices';
-import { APMIndices } from '../apm_indices';
+} from '../apm_indices';
 
 async function fetchLegacyAPMIndices(repository: ISavedObjectsRepository) {
   try {
-    const apmIndices = await repository.get<Partial<APMIndices>>(
+    const apmIndices = await repository.get<Partial<APMIndicesSavedObjectBody>>(
       APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
       APM_INDEX_SETTINGS_SAVED_OBJECT_ID
     );
@@ -66,15 +63,17 @@ export async function migrateLegacyAPMIndicesToSpaceAware({
     };
 
     // Calls create first to update the default space setting isSpaceAware to true
-    await repository.create<
-      Partial<ApmIndicesConfig & { isSpaceAware: boolean }>
-    >(APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE, savedObjectAttributes, {
-      id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
-      overwrite: true,
-    });
+    await repository.create<Partial<APMIndices & { isSpaceAware: boolean }>>(
+      APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+      savedObjectAttributes,
+      {
+        id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+        overwrite: true,
+      }
+    );
 
     // Create new APM indices space aware for all spaces available
-    await repository.bulkCreate<Partial<APMIndices>>(
+    await repository.bulkCreate<Partial<APMIndicesSavedObjectBody>>(
       spaces.saved_objects
         // Skip default space since it was already updated
         .filter(({ id: spaceId }) => spaceId !== 'default')
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
similarity index 91%
rename from x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
index 1d129eda16e6d..da0f7904a487a 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
@@ -22,9 +22,7 @@ type DeprecatedApmIndicesSavedObjectAttributes = Partial<{
   [Property in DeprecatedApmIndexConfigPaths]: string;
 }>;
 
-export function updateApmOssIndexPaths(
-  attributes: DeprecatedApmIndicesSavedObjectAttributes
-) {
+export function updateApmOssIndexPaths(attributes: DeprecatedApmIndicesSavedObjectAttributes) {
   return apmIndexConfigs.reduce((attrs, [configPath, deprecatedConfigPath]) => {
     const indexConfig: string | undefined = attributes[deprecatedConfigPath];
     if (indexConfig) {
diff --git a/x-pack/plugins/apm_data_access/server/types.ts b/x-pack/plugins/apm_data_access/server/types.ts
new file mode 100644
index 0000000000000..39c21c8aa0016
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/types.ts
@@ -0,0 +1,16 @@
+/*
+ * 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 { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
+import { APMIndices } from '.';
+
+export interface ApmDataAccessPluginSetup {
+  apmIndicesFromConfigFile: APMIndices;
+  getApmIndices: (soClient: SavedObjectsClientContract) => Promise<APMIndices>;
+}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface ApmDataAccessPluginStart {}
diff --git a/x-pack/plugins/apm_data_access/tsconfig.json b/x-pack/plugins/apm_data_access/tsconfig.json
new file mode 100644
index 0000000000000..3a40428cab960
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/tsconfig.json
@@ -0,0 +1,14 @@
+{
+  "extends": "../../../tsconfig.base.json",
+  "compilerOptions": {
+    "outDir": "target/types"
+  },
+  "include": ["../../../typings/**/*", "common/**/*", "server/**/*", "jest.config.js"],
+  "exclude": ["target/**/*"],
+  "kbn_references": [
+    "@kbn/config-schema",
+    "@kbn/core",
+    "@kbn/i18n",
+    "@kbn/core-saved-objects-api-server",
+  ]
+}
diff --git a/x-pack/plugins/security_solution/public/cases/links.ts b/x-pack/plugins/security_solution/public/cases/links.ts
index 59916790fb9f7..54d20b42d553a 100644
--- a/x-pack/plugins/security_solution/public/cases/links.ts
+++ b/x-pack/plugins/security_solution/public/cases/links.ts
@@ -18,7 +18,7 @@ const casesLinks = getCasesDeepLinks<LinkItem>({
   basePath: CASES_PATH,
   extend: {
     [SecurityPageName.case]: {
-      globalNavPosition: 5,
+      globalNavPosition: 4,
       capabilities: [`${CASES_FEATURE_ID}.${READ_CASES_CAPABILITY}`],
     },
     [SecurityPageName.caseConfigure]: {
diff --git a/x-pack/plugins/security_solution/public/explore/links.ts b/x-pack/plugins/security_solution/public/explore/links.ts
index 279cbe7da6040..a1da1528845ae 100644
--- a/x-pack/plugins/security_solution/public/explore/links.ts
+++ b/x-pack/plugins/security_solution/public/explore/links.ts
@@ -180,7 +180,7 @@ export const exploreLinks: LinkItem = {
   id: SecurityPageName.exploreLanding,
   title: EXPLORE,
   path: EXPLORE_PATH,
-  globalNavPosition: 6,
+  globalNavPosition: 7,
   capabilities: [`${SERVER_APP_ID}.show`],
   globalSearchKeywords: [
     i18n.translate('xpack.securitySolution.appLinks.explore', {
diff --git a/x-pack/plugins/security_solution/public/management/links.ts b/x-pack/plugins/security_solution/public/management/links.ts
index 72884ca71dd7a..309e9a093979b 100644
--- a/x-pack/plugins/security_solution/public/management/links.ts
+++ b/x-pack/plugins/security_solution/public/management/links.ts
@@ -86,7 +86,7 @@ export const links: LinkItem = {
   path: MANAGE_PATH,
   skipUrlState: true,
   hideTimeline: true,
-  globalNavPosition: 8,
+  globalNavPosition: 9,
   capabilities: [`${SERVER_APP_ID}.show`],
   globalSearchKeywords: [
     i18n.translate('xpack.securitySolution.appLinks.manage', {
diff --git a/x-pack/plugins/security_solution/public/rules/links.ts b/x-pack/plugins/security_solution/public/rules/links.ts
index fd32b2804e370..4e6482ab67bbd 100644
--- a/x-pack/plugins/security_solution/public/rules/links.ts
+++ b/x-pack/plugins/security_solution/public/rules/links.ts
@@ -27,6 +27,7 @@ export const links: LinkItem = {
   path: RULES_LANDING_PATH,
   hideTimeline: true,
   skipUrlState: true,
+  globalNavPosition: 8,
   capabilities: [`${SERVER_APP_ID}.show`],
   links: [
     {
diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
index 8b2b8554e36ce..87d49e5f459a3 100644
--- a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
+++ b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
@@ -17,6 +17,6 @@ import type { LinkItem } from '../common/links';
  */
 export const indicatorsLinks: LinkItem = {
   ...getSecuritySolutionLink<SecurityPageName>('indicators'),
-  globalNavPosition: 7,
+  globalNavPosition: 6,
   capabilities: [`${SERVER_APP_ID}.threat-intelligence`],
 };
diff --git a/x-pack/plugins/security_solution/public/timelines/links.ts b/x-pack/plugins/security_solution/public/timelines/links.ts
index e50e151e0c662..bd3b48164d097 100644
--- a/x-pack/plugins/security_solution/public/timelines/links.ts
+++ b/x-pack/plugins/security_solution/public/timelines/links.ts
@@ -14,7 +14,7 @@ export const links: LinkItem = {
   id: SecurityPageName.timelines,
   title: TIMELINES,
   path: TIMELINES_PATH,
-  globalNavPosition: 4,
+  globalNavPosition: 5,
   capabilities: [`${SERVER_APP_ID}.show`],
   globalSearchKeywords: [
     i18n.translate('xpack.securitySolution.appLinks.timelines', {
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 22ee2086a1a33..536325568ccd2 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -7889,7 +7889,6 @@
     "xpack.apm.apmDescription": "Collecte automatiquement les indicateurs et les erreurs de performances détaillés depuis vos applications.",
     "xpack.apm.apmSchema.index": "Schéma du serveur APM - Index",
     "xpack.apm.apmServiceGroups.title": "Groupes de services APM",
-    "xpack.apm.apmSettings.index": "Paramètres APM - Index",
     "xpack.apm.apmSettings.save.error": "Une erreur s'est produite lors de l'enregistrement des paramètres",
     "xpack.apm.apmSettings.saveButton": "Enregistrer les modifications",
     "xpack.apm.appName": "APM",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 84c71c20e176d..0b839aaea88f6 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -7905,7 +7905,6 @@
     "xpack.apm.apmDescription": "アプリケーション内から自動的に詳細なパフォーマンスメトリックやエラーを集めます。",
     "xpack.apm.apmSchema.index": "APMサーバースキーマ - インデックス",
     "xpack.apm.apmServiceGroups.title": "APMサービスグループ",
-    "xpack.apm.apmSettings.index": "APM 設定 - インデックス",
     "xpack.apm.apmSettings.save.error": "設定の保存中にエラーが発生しました",
     "xpack.apm.apmSettings.saveButton": "変更を保存",
     "xpack.apm.appName": "APM",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index c15e2f639c597..3ac0d9aa42fbf 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -7904,7 +7904,6 @@
     "xpack.apm.apmDescription": "自动从您的应用程序内收集深层的性能指标和错误。",
     "xpack.apm.apmSchema.index": "APM Server 架构 - 索引",
     "xpack.apm.apmServiceGroups.title": "APM 服务组",
-    "xpack.apm.apmSettings.index": "APM 设置 - 索引",
     "xpack.apm.apmSettings.save.error": "保存设置时出错",
     "xpack.apm.apmSettings.saveButton": "保存更改",
     "xpack.apm.appName": "APM",
diff --git a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
index 4d4488b674a05..0ba4336b36e0c 100644
--- a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
@@ -17,11 +17,11 @@ import expect from '@kbn/expect';
 import { get } from 'lodash';
 import type { SourceMap } from '@kbn/apm-plugin/server/routes/source_maps/route';
 import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
+import { createEsClientForTesting } from '@kbn/test';
 import {
   APM_AGENT_CONFIGURATION_INDEX,
   APM_SOURCE_MAP_INDEX,
-} from '@kbn/apm-plugin/server/routes/settings/apm_indices/get_apm_indices';
-import { createEsClientForTesting } from '@kbn/test';
+} from '@kbn/apm-plugin/server/routes/settings/apm_indices/apm_system_index_constants';
 import { FtrProviderContext } from '../../common/ftr_provider_context';
 import {
   createAgentPolicy,
diff --git a/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts b/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts
new file mode 100644
index 0000000000000..5aef295ddb324
--- /dev/null
+++ b/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts
@@ -0,0 +1,74 @@
+/*
+ * 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 {
+  APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+  APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+} from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../common/ftr_provider_context';
+
+export default function apmIndicesTests({ getService }: FtrProviderContext) {
+  const registry = getService('registry');
+  const kibanaServer = getService('kibanaServer');
+  const apmApiClient = getService('apmApiClient');
+
+  async function deleteSavedObject() {
+    try {
+      return await kibanaServer.savedObjects.delete({
+        type: APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+        id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+      });
+    } catch (e) {
+      if (e.response.status !== 404) {
+        throw e;
+      }
+    }
+  }
+
+  registry.when('APM Indices', { config: 'basic', archives: [] }, () => {
+    beforeEach(async () => {
+      await deleteSavedObject();
+    });
+    afterEach(async () => {
+      await deleteSavedObject();
+    });
+
+    it('returns APM Indices', async () => {
+      const response = await apmApiClient.readUser({
+        endpoint: 'GET /internal/apm/settings/apm-indices',
+      });
+      expect(response.status).to.be(200);
+      expect(response.body).to.eql({
+        transaction: 'traces-apm*,apm-*',
+        span: 'traces-apm*,apm-*',
+        error: 'logs-apm*,apm-*',
+        metric: 'metrics-apm*,apm-*',
+        onboarding: 'apm-*',
+      });
+    });
+
+    it('updates apm indices', async () => {
+      const INDEX_VALUE = 'foo-*';
+
+      const writeResponse = await apmApiClient.writeUser({
+        endpoint: 'POST /internal/apm/settings/apm-indices/save',
+        params: {
+          body: { transaction: INDEX_VALUE },
+        },
+      });
+      expect(writeResponse.status).to.be(200);
+
+      const readResponse = await apmApiClient.readUser({
+        endpoint: 'GET /internal/apm/settings/apm-indices',
+      });
+
+      expect(readResponse.status).to.be(200);
+      expect(readResponse.body.transaction).to.eql(INDEX_VALUE);
+    });
+  });
+}
diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
index 373ca407f7764..94b023757bf19 100644
--- a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
+++ b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
@@ -15,7 +15,7 @@ const FINDINGS_LATEST_INDEX = 'logs-cloud_security_posture.findings_latest-defau
 
 export function FindingsPageProvider({ getService, getPageObjects }: FtrProviderContext) {
   const testSubjects = getService('testSubjects');
-  const PageObjects = getPageObjects(['common']);
+  const PageObjects = getPageObjects(['common', 'header']);
   const retry = getService('retry');
   const es = getService('es');
   const supertest = getService('supertest');
@@ -92,7 +92,15 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider
     },
 
     async navigateToAction(actionTestSubject: string) {
-      await testSubjects.click(actionTestSubject);
+      return await retry.try(async () => {
+        await testSubjects.click(actionTestSubject);
+        await PageObjects.header.waitUntilLoadingHasFinished();
+        const result = await testSubjects.exists('createPackagePolicy_pageTitle');
+
+        if (!result) {
+          throw new Error('Integration installation page not found');
+        }
+      });
     },
   });
 
diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
index 1df0d3ec11c21..59f2f33ba3976 100644
--- a/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
+++ b/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
@@ -12,8 +12,7 @@ import { FtrProviderContext } from '../ftr_provider_context';
 export default ({ getPageObjects }: FtrProviderContext) => {
   const PageObjects = getPageObjects(['common', 'findings', 'header']);
 
-  // Failing: See https://github.com/elastic/kibana/issues/163950
-  describe.skip('Findings Page onboarding', function () {
+  describe('Findings Page onboarding', function () {
     this.tags(['cloud_security_posture_findings_onboarding']);
     let findings: typeof PageObjects.findings;
     let notInstalledVulnerabilities: typeof findings.notInstalledVulnerabilities;
@@ -34,6 +33,7 @@ export default ({ getPageObjects }: FtrProviderContext) => {
       expect(element).to.not.be(null);
 
       await notInstalledVulnerabilities.navigateToAction('cnvm-not-installed-action');
+
       await PageObjects.common.waitUntilUrlIncludes('add-integration/vuln_mgmt');
     });
 
@@ -44,6 +44,7 @@ export default ({ getPageObjects }: FtrProviderContext) => {
       expect(element).to.not.be(null);
 
       await notInstalledCSP.navigateToAction('cspm-not-installed-action');
+
       await PageObjects.common.waitUntilUrlIncludes('add-integration/cspm');
     });
 
diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json
index efe7ea1f5e8f8..558660c435b8a 100644
--- a/x-pack/test/tsconfig.json
+++ b/x-pack/test/tsconfig.json
@@ -140,5 +140,6 @@
     "@kbn/stack-connectors-plugin",
     "@kbn/aiops-utils",
     "@kbn/stack-alerts-plugin",
+    "@kbn/apm-data-access-plugin",
   ]
 }
diff --git a/yarn.lock b/yarn.lock
index b4e6feab73a58..a97726e56888d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3038,6 +3038,10 @@
   version "0.0.0"
   uid ""
 
+"@kbn/apm-data-access-plugin@link:x-pack/plugins/apm_data_access":
+  version "0.0.0"
+  uid ""
+
 "@kbn/apm-plugin@link:x-pack/plugins/apm":
   version "0.0.0"
   uid ""