diff --git a/x-pack/plugins/observability_solution/apm/server/routes/agent_explorer/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/agent_explorer/route.ts
index 6f0fcc7dceb3c..4f93304365744 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/agent_explorer/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/agent_explorer/route.ts
@@ -19,7 +19,7 @@ import {
 
 const agentExplorerRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/get_agents_per_service',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([
       environmentRt,
@@ -62,7 +62,7 @@ const agentExplorerRoute = createApmServerRoute({
 
 const latestAgentVersionsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/get_latest_agent_versions',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources): Promise<AgentLatestVersionsResponse> {
     const { logger, config } = resources;
 
@@ -72,7 +72,7 @@ const latestAgentVersionsRoute = createApmServerRoute({
 
 const agentExplorerInstanceRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/services/{serviceName}/agent_instances',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     path: t.type({ serviceName: t.string }),
     query: t.intersection([environmentRt, kueryRt, rangeRt, probabilityRt]),
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/agent_keys/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/agent_keys/route.ts
index d8c2cd70768c4..11d1131241b30 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/agent_keys/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/agent_keys/route.ts
@@ -17,7 +17,7 @@ import { privilegesTypeRt } from '../../../common/privilege_type';
 
 const agentKeysRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/agent_keys',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
 
   handler: async (resources): Promise<AgentKeysResponse> => {
     const { context } = resources;
@@ -31,8 +31,7 @@ const agentKeysRoute = createApmServerRoute({
 
 const agentKeysPrivilegesRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/agent_keys/privileges',
-  options: { tags: ['access:apm'] },
-
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<AgentKeysPrivilegesResponse> => {
     const {
       plugins: { security },
@@ -55,7 +54,11 @@ const agentKeysPrivilegesRoute = createApmServerRoute({
 
 const invalidateAgentKeyRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/api_key/invalidate',
-  options: { tags: ['access:apm', 'access:apm_settings_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
+  },
   params: t.type({
     body: t.type({ id: t.string }),
   }),
@@ -91,7 +94,12 @@ const invalidateAgentKeyRoute = createApmServerRoute({
 
 const createAgentKeyRoute = createApmServerRoute({
   endpoint: 'POST /api/apm/agent_keys 2023-10-31',
-  options: { tags: ['access:apm', 'access:apm_settings_write', 'oas-tag:APM agent keys'] },
+  options: { tags: ['oas-tag:APM agent keys'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
+  },
   params: t.type({
     body: t.type({
       name: t.string,
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/route.ts
index 3343b7f78f0af..ca74e8c27e38f 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/route.ts
@@ -61,7 +61,7 @@ export type AlertParams = t.TypeOf<typeof alertParamsRt>;
 const transactionErrorRateChartPreview = createApmServerRoute({
   endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview',
   params: t.type({ query: alertParamsRt }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -84,7 +84,7 @@ const transactionErrorRateChartPreview = createApmServerRoute({
 const transactionErrorCountChartPreview = createApmServerRoute({
   endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview',
   params: t.type({ query: alertParamsRt }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -107,7 +107,7 @@ const transactionErrorCountChartPreview = createApmServerRoute({
 const transactionDurationChartPreview = createApmServerRoute({
   endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview',
   params: t.type({ query: alertParamsRt }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
index 3475830146634..aae197e5ade5d 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
@@ -69,7 +69,13 @@ const getRegisterRouteDependencies = () => {
 
 const initApi = (
   routes: Array<
-    ServerRoute<any, t.Any | undefined, APMRouteHandlerResources, any, APMRouteCreateOptions>
+    ServerRoute<
+      any,
+      t.Any | undefined,
+      APMRouteHandlerResources,
+      any,
+      APMRouteCreateOptions | undefined
+    >
   >
 ) => {
   const { mocks, dependencies } = getRegisterRouteDependencies();
@@ -134,7 +140,7 @@ describe('createApi', () => {
     } = initApi([
       {
         endpoint: 'GET /foo',
-        options: { tags: ['access:apm'] },
+        security: { authz: { requiredPrivileges: ['apm'] } },
         handler: async () => ({}),
       },
       {
@@ -142,28 +148,22 @@ describe('createApi', () => {
         params: t.type({
           body: t.string,
         }),
-        options: { tags: ['access:apm'] },
+        security: { authz: { requiredPrivileges: ['apm'] } },
         handler: async () => ({}),
       },
       {
         endpoint: 'PUT /baz',
-        options: {
-          tags: ['access:apm', 'access:apm_write'],
-        },
+        security: { authz: { requiredPrivileges: ['apm', 'apm_write'] } },
         handler: async () => ({}),
       },
       {
         endpoint: 'GET /qux',
-        options: {
-          tags: ['access:apm', 'access:apm_write'],
-        },
+        security: { authz: { requiredPrivileges: ['apm', 'apm_write'] } },
         handler: async () => ({}),
       },
       {
         endpoint: 'GET /fez',
-        options: {
-          tags: ['access:apm', 'access:apm_settings_write'],
-        },
+        security: { authz: { requiredPrivileges: ['apm', 'apm_settings_write'] } },
         handler: async () => ({}),
       },
     ]);
@@ -175,41 +175,36 @@ describe('createApi', () => {
     expect(put).toHaveBeenCalledTimes(1);
 
     expect(get.mock.calls[0][0]).toEqual({
-      options: {
-        tags: ['access:apm'],
-      },
+      options: {},
+      security: { authz: { requiredPrivileges: ['apm'] } },
       path: '/foo',
       validate: expect.anything(),
     });
 
     expect(get.mock.calls[1][0]).toEqual({
-      options: {
-        tags: ['access:apm', 'access:apm_write'],
-      },
+      options: {},
+      security: { authz: { requiredPrivileges: ['apm', 'apm_write'] } },
       path: '/qux',
       validate: expect.anything(),
     });
 
     expect(get.mock.calls[2][0]).toEqual({
-      options: {
-        tags: ['access:apm', 'access:apm_settings_write'],
-      },
+      options: {},
+      security: { authz: { requiredPrivileges: ['apm', 'apm_settings_write'] } },
       path: '/fez',
       validate: expect.anything(),
     });
 
     expect(post.mock.calls[0][0]).toEqual({
-      options: {
-        tags: ['access:apm'],
-      },
+      options: {},
+      security: { authz: { requiredPrivileges: ['apm'] } },
       path: '/bar',
       validate: expect.anything(),
     });
 
     expect(put.mock.calls[0][0]).toEqual({
-      options: {
-        tags: ['access:apm', 'access:apm_write'],
-      },
+      options: {},
+      security: { authz: { requiredPrivileges: ['apm', 'apm_write'] } },
       path: '/baz',
       validate: expect.anything(),
     });
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts
index 5fc89e00fcc8b..70f22e5fe5dbc 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/route.ts
@@ -19,8 +19,10 @@ import { getApmTimeseries, getApmTimeseriesRt, type ApmTimeseries } from './get_
 
 const getApmTimeSeriesRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/assistant/get_apm_timeseries',
-  options: {
-    tags: ['access:apm', 'access:ai_assistant'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'ai_assistant'],
+    },
   },
   params: t.type({
     body: getApmTimeseriesRt,
@@ -51,9 +53,7 @@ const getDownstreamDependenciesRoute = createApmServerRoute({
   params: t.type({
     query: downstreamDependenciesRouteRt,
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ content: APMDownstreamDependency[] }> => {
     const {
       params,
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/correlations/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/correlations/route.ts
index 06ba8b33d1bb0..658ad91bca835 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/correlations/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/correlations/route.ts
@@ -51,7 +51,7 @@ const fieldCandidatesTransactionsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<DurationFieldCandidatesResponse> => {
     const { context } = resources;
     const { license } = await context.licensing;
@@ -104,7 +104,7 @@ const fieldValueStatsTransactionsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TopValuesStats> => {
     const { context } = resources;
     const { license } = await context.licensing;
@@ -172,7 +172,7 @@ const fieldValuePairsTransactionsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<FieldValuePairsResponse> => {
     const { context } = resources;
     const { license } = await context.licensing;
@@ -240,7 +240,7 @@ const significantCorrelationsTransactionsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<SignificantCorrelationsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const {
@@ -299,7 +299,7 @@ const pValuesTransactionsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<PValuesResponse> => {
     const apmEventClient = await getApmEventClient(resources);
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts
index 750bacb4ba455..7d062d58f0b1a 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts
@@ -33,7 +33,11 @@ const serviceDashboardSaveRoute = createApmServerRoute({
       serviceEnvironmentFilterEnabled: t.boolean,
     }),
   }),
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async (resources): Promise<SavedApmCustomDashboard> => {
     const { context, params } = resources;
     const { customDashboardId } = params.query;
@@ -62,9 +66,7 @@ const serviceDashboardsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ serviceDashboards: SavedApmCustomDashboard[] }> => {
     const { context, params, request } = resources;
     const coreContext = await context.core;
@@ -116,7 +118,11 @@ const serviceDashboardDeleteRoute = createApmServerRoute({
       customDashboardId: t.string,
     }),
   }),
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async (resources): Promise<void> => {
     const { context, params } = resources;
     const { customDashboardId } = params.query;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/data_view/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/data_view/route.ts
index d4e6b0a7492e9..23318949b0811 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/data_view/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/data_view/route.ts
@@ -13,7 +13,7 @@ import { getApmEventClient } from '../../lib/helpers/get_apm_event_client';
 
 const staticDataViewRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/data_view/static',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): CreateDataViewResponse => {
     const { context, plugins, request, logger } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -49,7 +49,7 @@ const staticDataViewRoute = createApmServerRoute({
 
 const dataViewTitleRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/data_view/index_pattern',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async ({ getApmIndices }): Promise<{ apmDataViewIndexPattern: string }> => {
     const apmIndicies = await getApmIndices();
     const apmDataViewIndexPattern = getApmDataViewIndexPattern(apmIndicies);
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/debug_telemetry/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/debug_telemetry/route.ts
index c3ab67150f39c..3e4e1889321ba 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/debug_telemetry/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/debug_telemetry/route.ts
@@ -14,8 +14,10 @@ import {
 } from '../../../common/apm_saved_object_constants';
 export const debugTelemetryRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/debug-telemetry',
-  options: {
-    tags: ['access:apm', 'access:apm_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
   },
   handler: async (resources): Promise<APMTelemetry> => {
     const { plugins, context } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/dependencies/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/dependencies/route.ts
index 4459a127ea13e..0ff845e067bd0 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/dependencies/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/dependencies/route.ts
@@ -47,9 +47,7 @@ const topDependenciesRoute = createApmServerRoute({
       query: offsetRt,
     }),
   ]),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TopDependenciesResponse> => {
     const {
       request,
@@ -89,9 +87,7 @@ const upstreamServicesForDependencyRoute = createApmServerRoute({
       query: t.intersection([environmentRt, offsetRt, kueryRt]),
     }),
   ]),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<UpstreamServicesForDependencyResponse> => {
     const {
       request,
@@ -126,9 +122,7 @@ const dependencyMetadataRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([t.type({ dependencyName: t.string }), rangeRt]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -165,9 +159,7 @@ const dependencyLatencyChartsRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<LatencyChartsDependencyResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -211,9 +203,7 @@ const dependencyThroughputChartsRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ThroughputChartsForDependencyResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -257,9 +247,7 @@ const dependencyFailedTransactionRateChartsRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -295,9 +283,7 @@ const dependencyFailedTransactionRateChartsRoute = createApmServerRoute({
 
 const dependencyOperationsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/dependencies/operations',
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([
       rangeRt,
@@ -354,9 +340,7 @@ const dependencyLatencyDistributionChartsRoute = createApmServerRoute({
       environmentRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<DependencyLatencyDistributionResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -378,9 +362,7 @@ const dependencyLatencyDistributionChartsRoute = createApmServerRoute({
 
 const topDependencySpansRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/dependencies/operations/spans',
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([
       rangeRt,
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/diagnostics/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/diagnostics/route.ts
index fcd41df55afc7..fdeba801f8a6d 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/diagnostics/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/diagnostics/route.ts
@@ -80,7 +80,7 @@ export type DiagnosticsBundle = Promise<{
 
 const getDiagnosticsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/diagnostics',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.partial({
     query: t.partial({
       kuery: t.string,
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts
index 218de180cbc00..ab89f9417ec88 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts
@@ -18,7 +18,7 @@ const serviceEntitiesSummaryRoute = createApmServerRoute({
     path: t.type({ serviceName: t.string }),
     query: environmentRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources) {
     const { context, params, request } = resources;
     const coreContext = await context.core;
@@ -44,7 +44,7 @@ const servicesEntitiesRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources) {
     const { context, params, request } = resources;
     const coreContext = await context.core;
@@ -77,7 +77,7 @@ const serviceLogRateTimeseriesRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources) {
     const { context, params, plugins } = resources;
     const [coreContext, logsDataAccessStart] = await Promise.all([
@@ -111,7 +111,7 @@ const serviceLogErrorRateTimeseriesRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources) {
     const { context, params, plugins } = resources;
     const [coreContext, logsDataAccessStart] = await Promise.all([
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/environments/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/environments/route.ts
index 6eafe5c7b62fe..23d9b03e9c48e 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/environments/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/environments/route.ts
@@ -24,7 +24,7 @@ const environmentsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/errors/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/errors/route.ts
index 62d9d883ba896..95a5f68f9cce6 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/errors/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/errors/route.ts
@@ -51,7 +51,7 @@ const errorsMainStatisticsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorGroupMainStatisticsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -90,7 +90,7 @@ const errorsMainStatisticsByTransactionNameRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorGroupMainStatisticsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -136,7 +136,7 @@ const errorsDetailedStatisticsRoute = createApmServerRoute({
     ]),
     body: t.type({ groupIds: jsonRt.pipe(t.array(t.string)) }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorGroupPeriodsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -170,7 +170,7 @@ const errorGroupsSamplesRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorGroupSampleIdsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -199,7 +199,7 @@ const errorGroupSampleDetailsRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorSampleDetailsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -240,7 +240,7 @@ const errorDistributionRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ErrorDistributionResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -276,7 +276,7 @@ const topErroneousTransactionsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TopErroneousTransactionsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/event_metadata/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/event_metadata/route.ts
index cb1ff01654c30..0ded2b3824542 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/event_metadata/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/event_metadata/route.ts
@@ -14,7 +14,7 @@ import { rangeRt } from '../default_api_types';
 
 const eventMetadataRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/event_metadata/{processorEvent}/{id}',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     path: t.type({
       processorEvent: processorEventRt,
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/fallback_to_transactions/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/fallback_to_transactions/route.ts
index d7e20e847753d..ec94240f82df5 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/fallback_to_transactions/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/fallback_to_transactions/route.ts
@@ -16,7 +16,7 @@ const fallbackToTransactionsRoute = createApmServerRoute({
   params: t.partial({
     query: t.intersection([kueryRt, t.partial(rangeRt.props)]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ fallbackToTransactions: boolean }> => {
     const apmEventClient = await getApmEventClient(resources);
     const {
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/fleet/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/fleet/route.ts
index 05b74b3fc9c42..fa98472228e7c 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/fleet/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/fleet/route.ts
@@ -65,7 +65,11 @@ const fleetAgentsRoute = createApmServerRoute({
 
 const saveApmServerSchemaRoute = createApmServerRoute({
   endpoint: 'POST /api/apm/fleet/apm_server_schema 2023-10-31',
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   params: t.type({
     body: t.type({
       schema: t.record(t.string, t.unknown),
@@ -88,7 +92,7 @@ const saveApmServerSchemaRoute = createApmServerRoute({
 
 const getUnsupportedApmServerSchemaRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/fleet/apm_server_schema/unsupported',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ unsupported: UnsupportedApmServerSchema }> => {
     throwNotFoundIfFleetMigrationNotAvailable(resources.featureFlags);
     const { context } = resources;
@@ -101,7 +105,7 @@ const getUnsupportedApmServerSchemaRoute = createApmServerRoute({
 
 const getMigrationCheckRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/fleet/migration_check',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<RunMigrationCheckResponse> => {
     const { core, plugins, context, config, request } = resources;
     throwNotFoundIfFleetMigrationNotAvailable(resources.featureFlags);
@@ -128,7 +132,11 @@ const getMigrationCheckRoute = createApmServerRoute({
 
 const createCloudApmPackagePolicyRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/fleet/cloud_apm_package_policy',
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts
index 94b7d40b84c2d..0348a6a32f0eb 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts
@@ -13,7 +13,7 @@ import { hasEntitiesData } from './has_historical_entities_data';
 
 const hasDataRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/has_data',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ hasData: boolean }> => {
     const apmEventClient = await getApmEventClient(resources);
     const hasData = await hasHistoricalAgentData(apmEventClient);
@@ -23,7 +23,7 @@ const hasDataRoute = createApmServerRoute({
 
 const hasEntitiesRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/has_entities',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ hasData: boolean }> => {
     const { context, request, logger } = resources;
     const coreContext = await context.core;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/infrastructure/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/infrastructure/route.ts
index bcb818a329e85..3a0f4efeab42c 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/infrastructure/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/infrastructure/route.ts
@@ -20,7 +20,7 @@ const infrastructureRoute = createApmServerRoute({
     }),
     query: t.intersection([kueryRt, rangeRt, environmentRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/latency_distribution/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/latency_distribution/route.ts
index c489301aebd81..704eaf393702e 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/latency_distribution/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/latency_distribution/route.ts
@@ -47,7 +47,7 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<OverallLatencyDistributionResponse> => {
     const apmEventClient = await getApmEventClient(resources);
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/metrics/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/metrics/route.ts
index 950c5c18a4302..63fcd8ad87e67 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/metrics/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/metrics/route.ts
@@ -32,7 +32,7 @@ const metricsChartsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -67,7 +67,7 @@ const serviceMetricsJvm = createApmServerRoute({
     }),
     query: t.intersection([kueryRt, rangeRt, environmentRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ serviceNodes: ServiceNodesResponse }> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/metrics/serverless/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/metrics/serverless/route.ts
index ba57e09869000..0432409344fe4 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/metrics/serverless/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/metrics/serverless/route.ts
@@ -46,7 +46,7 @@ const serverlessMetricsChartsRoute = createApmServerRoute({
       t.intersection([transactionDataSourceRt, t.type({ bucketSizeInSeconds: toNumberRt })]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -93,7 +93,7 @@ const serverlessMetricsActiveInstancesRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt, t.partial({ serverlessId: t.string })]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -132,7 +132,7 @@ const serverlessMetricsFunctionsOverviewRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -164,7 +164,7 @@ const serverlessMetricsSummaryRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt, t.partial({ serverlessId: t.string })]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServerlessSummaryResponse> => {
     const { params, context } = resources;
     const {
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/mobile/crashes/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/mobile/crashes/route.ts
index 7a474585da9d1..a8dbc788836c6 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/mobile/crashes/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/mobile/crashes/route.ts
@@ -36,7 +36,7 @@ const mobileCrashDistributionRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<CrashDistributionResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -71,7 +71,7 @@ const mobileCrashMainStatisticsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ errorGroups: MobileCrashGroupMainStatisticsResponse }> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -110,7 +110,7 @@ const mobileCrashDetailedStatisticsRoute = createApmServerRoute({
     ]),
     body: t.type({ groupIds: jsonRt.pipe(t.array(t.string)) }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileCrashesGroupPeriodsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/mobile/errors/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/mobile/errors/route.ts
index b00ad9c69fa42..e6d5628a0c0ed 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/mobile/errors/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/mobile/errors/route.ts
@@ -39,7 +39,7 @@ const mobileMobileHttpRatesRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, kueryRt, rangeRt, offsetRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileHttpErrorsTimeseries> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -76,7 +76,7 @@ const mobileErrorsDetailedStatisticsRoute = createApmServerRoute({
     ]),
     body: t.type({ groupIds: jsonRt.pipe(t.array(t.string)) }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileErrorGroupPeriodsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -117,7 +117,7 @@ const mobileErrorTermsByFieldRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -158,7 +158,7 @@ const mobileErrorsMainStatisticsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ errorGroups: MobileErrorGroupMainStatisticsResponse }> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/mobile/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/mobile/route.ts
index 39b527e6a81eb..d1c964e8a2f6d 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/mobile/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/mobile/route.ts
@@ -48,7 +48,7 @@ const mobileFiltersRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -87,7 +87,7 @@ const mobileChartsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -131,7 +131,7 @@ const mobileStatsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobilePeriodStats> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -168,7 +168,7 @@ const mobileLocationStatsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileLocationStats> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -207,7 +207,7 @@ const sessionsChartRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<SessionsTimeseries> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -246,7 +246,7 @@ const httpRequestsChartRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<HttpRequestsTimeseries> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -284,7 +284,7 @@ const mobileTermsByFieldRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -324,9 +324,7 @@ const mobileMainStatisticsByField = createApmServerRoute({
       }),
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileMainStatisticsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -362,9 +360,7 @@ const mobileDetailedStatisticsByField = createApmServerRoute({
       }),
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MobileDetailedStatisticsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/observability_overview/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/observability_overview/route.ts
index 3858fafe7dcdd..9d61c885a6361 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/observability_overview/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/observability_overview/route.ts
@@ -19,7 +19,7 @@ import { getHasData, HasDataResponse } from './has_data';
 
 const observabilityOverviewHasDataRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/observability_overview/has_data',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<HasDataResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     return await getHasData({
@@ -34,7 +34,7 @@ const observabilityOverviewRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([rangeRt, t.type({ bucketSize: toNumberRt, intervalString: t.string })]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ObservabilityOverviewResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { bucketSize, intervalString, start, end } = resources.params.query;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/profiling/hosts/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/profiling/hosts/route.ts
index 3ddd2782f1085..c9e14198a42d6 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/profiling/hosts/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/profiling/hosts/route.ts
@@ -28,7 +28,7 @@ const profilingHostsFlamegraphRoute = createApmServerRoute({
     path: t.type({ serviceName: t.string }),
     query: t.intersection([rangeRt, environmentRt, serviceTransactionDataSourceRt, kueryRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<
@@ -92,7 +92,7 @@ const profilingHostsFunctionsRoute = createApmServerRoute({
       kueryRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/profiling/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/profiling/route.ts
index 0f9475f663742..677db02c8f747 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/profiling/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/profiling/route.ts
@@ -33,7 +33,7 @@ const servicesFlamegraphRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<BaseFlameGraph | undefined> => {
     const { context, plugins, params } = resources;
     const core = await context.core;
@@ -87,7 +87,7 @@ const servicesFunctionsRoute = createApmServerRoute({
       kueryRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TopNFunctions | undefined> => {
     const { context, plugins, params } = resources;
     const core = await context.core;
@@ -136,7 +136,7 @@ const servicesFunctionsRoute = createApmServerRoute({
 
 const profilingStatusRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/profiling/status',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ initialized: boolean }> => {
     const { context, plugins, logger } = resources;
     const [esClient, profilingDataAccessStart] = await Promise.all([
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/service_groups/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/service_groups/route.ts
index 3711eb809e936..9ffc365bb4d86 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/service_groups/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/service_groups/route.ts
@@ -25,9 +25,7 @@ import { getApmAlertsClient } from '../../lib/helpers/get_apm_alerts_client';
 
 const serviceGroupsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/service-groups',
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ serviceGroups: SavedServiceGroup[] }> => {
     const { context } = resources;
     const {
@@ -47,9 +45,7 @@ const serviceGroupRoute = createApmServerRoute({
       serviceGroup: t.string,
     }),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ serviceGroup: SavedServiceGroup }> => {
     const { context, params } = resources;
     const {
@@ -79,7 +75,11 @@ const serviceGroupSaveRoute = createApmServerRoute({
       color: t.union([t.string, t.undefined]),
     }),
   }),
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async (resources): Promise<SavedServiceGroup> => {
     const { context, params } = resources;
     const { serviceGroupId } = params.query;
@@ -106,7 +106,11 @@ const serviceGroupDeleteRoute = createApmServerRoute({
       serviceGroupId: t.string,
     }),
   }),
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async (resources): Promise<void> => {
     const { context, params } = resources;
     const { serviceGroupId } = params.query;
@@ -123,9 +127,7 @@ const serviceGroupServicesRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([rangeRt, t.partial(kueryRt.props)]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ items: LookupServicesResponse }> => {
     const { params, context } = resources;
     const { kuery = '', start, end } = params.query;
@@ -149,9 +151,7 @@ const serviceGroupServicesRoute = createApmServerRoute({
 type ServiceGroupCounts = Record<string, { services: number; alerts: number }>;
 const serviceGroupCountsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/service-group/counts',
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceGroupCounts> => {
     const { context, logger, plugins, request } = resources;
     const {
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/service_map/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/service_map/route.ts
index 2524e7a23f9b7..3436874ac5bdc 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/service_map/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/service_map/route.ts
@@ -42,7 +42,7 @@ const serviceMapRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TransformServiceMapResponse> => {
     const { config, context, params, logger } = resources;
     if (!config.serviceMapEnabled) {
@@ -111,7 +111,7 @@ const serviceMapServiceNodeRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, rangeRt, offsetRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceMapServiceNodeInfoResponse> => {
     const { config, context, params } = resources;
 
@@ -154,7 +154,7 @@ const serviceMapDependencyNodeRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([t.type({ dependencyName: t.string }), environmentRt, rangeRt, offsetRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceMapServiceDependencyInfoResponse> => {
     const { config, context, params } = resources;
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts
index da2a506e3ae3f..d6c3b5b73e3d8 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts
@@ -104,7 +104,7 @@ const servicesRoute = createApmServerRoute({
       ]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources): Promise<ServicesItemsResponse> {
     const {
       context,
@@ -172,7 +172,7 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({
     ]),
     body: t.type({ serviceNames: jsonRt.pipe(t.array(t.string)) }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceTransactionDetailedStatPeriodsResponse> => {
     const {
       params,
@@ -225,7 +225,7 @@ const serviceMetadataDetailsRoute = createApmServerRoute({
     path: t.type({ serviceName: t.string }),
     query: t.intersection([rangeRt, environmentRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceMetadataDetails> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -262,7 +262,7 @@ const serviceMetadataIconsRoute = createApmServerRoute({
     path: t.type({ serviceName: t.string }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceMetadataIcons> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params, config } = resources;
@@ -295,7 +295,7 @@ const serviceAgentRoute = createApmServerRoute({
     }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceAgentResponse> => {
     const { context, request } = resources;
     const coreContext = await context.core;
@@ -339,7 +339,7 @@ const serviceTransactionTypesRoute = createApmServerRoute({
     }),
     query: t.intersection([rangeRt, serviceTransactionDataSourceRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceTransactionTypesResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -366,7 +366,7 @@ const serviceNodeMetadataRoute = createApmServerRoute({
     }),
     query: t.intersection([kueryRt, rangeRt, environmentRt, serviceTransactionDataSourceRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceNodeMetadataResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -395,7 +395,12 @@ const serviceAnnotationsRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, rangeRt]),
   }),
-  options: { tags: ['access:apm', 'oas-tag:APM annotations'] },
+  options: { tags: ['oas-tag:APM annotations'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm'],
+    },
+  },
   handler: async (resources): Promise<ServiceAnnotationResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params, plugins, context, request, logger, config } = resources;
@@ -439,7 +444,12 @@ const serviceAnnotationsRoute = createApmServerRoute({
 const serviceAnnotationsCreateRoute = createApmServerRoute({
   endpoint: 'POST /api/apm/services/{serviceName}/annotation 2023-10-31',
   options: {
-    tags: ['access:apm', 'access:apm_write', 'oas-tag:APM annotations'],
+    tags: ['oas-tag:APM annotations'],
+  },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
   },
   params: t.type({
     path: t.type({
@@ -523,7 +533,7 @@ const serviceThroughputRoute = createApmServerRoute({
       t.intersection([environmentRt, kueryRt, rangeRt, offsetRt, serviceTransactionDataSourceRt]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -605,7 +615,7 @@ const serviceInstancesMainStatisticsRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -678,7 +688,7 @@ const serviceInstancesDetailedStatisticsRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceInstancesDetailedStatisticsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params, config } = resources;
@@ -730,7 +740,7 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({
     }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<
@@ -780,9 +790,7 @@ export const serviceDependenciesRoute = createApmServerRoute({
       offsetRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   async handler(resources): Promise<{ serviceDependencies: ServiceDependenciesResponse }> {
     const {
       params,
@@ -821,9 +829,7 @@ export const serviceDependenciesBreakdownRoute = createApmServerRoute({
     }),
     query: t.intersection([environmentRt, rangeRt, kueryRt]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -867,9 +873,7 @@ const serviceAnomalyChartsRoute = createApmServerRoute({
     }),
     query: t.intersection([rangeRt, environmentRt, t.type({ transactionType: t.string })]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -921,7 +925,7 @@ const serviceAlertsRoute = createApmServerRoute({
     }),
     query: t.intersection([rangeRt, environmentRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceAlertsResponse[number]> => {
     const { params } = resources;
     const {
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts
index aaf8fb2c48681..bda0f5aba15a9 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts
@@ -39,7 +39,7 @@ function throwNotFoundIfAgentConfigNotAvailable(featureFlags: ApmFeatureFlags):
 // get list of configurations
 const agentConfigurationRoute = createApmServerRoute({
   endpoint: 'GET /api/apm/settings/agent-configuration 2023-10-31',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -68,7 +68,7 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({
   params: t.partial({
     query: serviceRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<AgentConfiguration> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
@@ -98,8 +98,10 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({
 // delete configuration
 const deleteAgentConfigurationRoute = createApmServerRoute({
   endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31',
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
   },
   params: t.type({
     body: t.type({
@@ -154,8 +156,10 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
 // create/update configuration
 const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
   endpoint: 'PUT /api/apm/settings/agent-configuration 2023-10-31',
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
   },
   params: t.intersection([
     t.partial({ query: t.partial({ overwrite: toBooleanRt }) }),
@@ -224,7 +228,12 @@ const agentConfigurationSearchRoute = createApmServerRoute({
   params: t.type({
     body: searchParamsRt,
   }),
-  options: { tags: ['access:apm'], disableTelemetry: true },
+  options: { disableTelemetry: true },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm'],
+    },
+  },
   handler: async (
     resources
   ): Promise<SearchHit<AgentConfiguration, undefined, undefined> | null> => {
@@ -286,7 +295,7 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
   params: t.partial({
     query: t.partial({ serviceName: t.string }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -327,7 +336,7 @@ const agentConfigurationAgentNameRoute = createApmServerRoute({
   params: t.type({
     query: t.type({ serviceName: t.string }),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ agentName: string | undefined }> => {
     throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/anomaly_detection/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/anomaly_detection/route.ts
index 00ceee9451f46..921b86bc57f16 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/settings/anomaly_detection/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/anomaly_detection/route.ts
@@ -26,8 +26,10 @@ import { ApmMlJob } from '../../../../common/anomaly_detection/apm_ml_job';
 // get ML anomaly detection jobs for each environment
 const anomalyDetectionJobsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/anomaly-detection/jobs',
-  options: {
-    tags: ['access:apm', 'access:ml:canGetJobs'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'ml:canGetJobs'],
+    },
   },
   handler: async (
     resources
@@ -59,8 +61,10 @@ const anomalyDetectionJobsRoute = createApmServerRoute({
 // create new ML anomaly detection jobs for each given environment
 const createAnomalyDetectionJobsRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/settings/anomaly-detection/jobs',
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write', 'access:ml:canCreateJob'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write', 'ml:canCreateJob'],
+    },
   },
   params: t.type({
     body: t.type({
@@ -102,7 +106,7 @@ const createAnomalyDetectionJobsRoute = createApmServerRoute({
 // get all available environments to create anomaly detection jobs for
 const anomalyDetectionEnvironmentsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/anomaly-detection/environments',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ environments: string[] }> => {
     const apmEventClient = await getApmEventClient(resources);
     const coreContext = await resources.context.core;
@@ -126,14 +130,16 @@ const anomalyDetectionEnvironmentsRoute = createApmServerRoute({
 
 const anomalyDetectionUpdateToV3Route = createApmServerRoute({
   endpoint: 'POST /internal/apm/settings/anomaly-detection/update_to_v3',
-  options: {
-    tags: [
-      'access:apm',
-      'access:apm_settings_write',
-      'access:ml:canCreateJob',
-      'access:ml:canGetJobs',
-      'access:ml:canCloseJob',
-    ],
+  security: {
+    authz: {
+      requiredPrivileges: [
+        'apm',
+        'apm_settings_write',
+        'ml:canCreateJob',
+        'ml:canGetJobs',
+        'ml:canCloseJob',
+      ],
+    },
   },
   handler: async (resources): Promise<{ update: boolean }> => {
     const { getApmIndices } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/apm_indices/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/apm_indices/route.ts
index 5d8ac9f04e740..63bf2a145d6a0 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/settings/apm_indices/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/apm_indices/route.ts
@@ -15,7 +15,7 @@ import { getApmIndexSettings, ApmIndexSettingsResponse } from './get_apm_indices
 // get list of apm indices and values
 const apmIndexSettingsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/apm-index-settings',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -29,7 +29,7 @@ const apmIndexSettingsRoute = createApmServerRoute({
 // get apm indices configuration object
 const apmIndicesRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/apm-indices',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<APMIndices> => {
     return await resources.getApmIndices();
   },
@@ -42,8 +42,10 @@ type SaveApmIndicesBodySchema = {
 // save ui indices
 const saveApmIndicesRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/settings/apm-indices/save',
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
   },
   params: t.type({
     body: t.partial({
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/route.ts
index 306e23a679765..20bdd11b3f45c 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/custom_link/route.ts
@@ -25,7 +25,7 @@ import { CustomLink } from '../../../../common/custom_link/custom_link_types';
 
 const customLinkTransactionRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/custom_links/transaction',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.partial({
     query: filterOptionsRt,
   }),
@@ -41,7 +41,7 @@ const customLinkTransactionRoute = createApmServerRoute({
 
 const listCustomLinksRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/custom_links',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.partial({
     query: filterOptionsRt,
   }),
@@ -75,7 +75,11 @@ const createCustomLinkRoute = createApmServerRoute({
   params: t.type({
     body: payloadRt,
   }),
-  options: { tags: ['access:apm', 'access:apm_settings_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
+  },
   handler: async (resources): Promise<void> => {
     const { context, params } = resources;
     const licensingContext = await context.licensing;
@@ -104,8 +108,10 @@ const updateCustomLinkRoute = createApmServerRoute({
     }),
     body: payloadRt,
   }),
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
   },
   handler: async (resources): Promise<void> => {
     const { params, context } = resources;
@@ -135,8 +141,10 @@ const deleteCustomLinkRoute = createApmServerRoute({
       id: t.string,
     }),
   }),
-  options: {
-    tags: ['access:apm', 'access:apm_settings_write'],
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_settings_write'],
+    },
   },
   handler: async (resources): Promise<{ result: string }> => {
     const { context, params } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/labs/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/labs/route.ts
index 608fe27106cac..28e8e5ef7eceb 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/settings/labs/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/labs/route.ts
@@ -10,7 +10,7 @@ import { createApmServerRoute } from '../../apm_routes/create_apm_server_route';
 
 const getLabsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/settings/labs',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (): Promise<{ labsItems: string[] }> => {
     const labsItems = Object.entries(uiSettings)
       .filter(([key, value]): boolean | undefined => value.showInLabs)
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/source_maps/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/source_maps/route.ts
index bc92c06416204..6e51002dfc81a 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/source_maps/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/source_maps/route.ts
@@ -49,7 +49,7 @@ function throwNotImplementedIfSourceMapNotAvailable(featureFlags: ApmFeatureFlag
 
 const listSourceMapRoute = createApmServerRoute({
   endpoint: 'GET /api/apm/sourcemaps 2023-10-31',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.partial({
     query: t.partial({
       page: toNumberRt,
@@ -85,9 +85,13 @@ const listSourceMapRoute = createApmServerRoute({
 const uploadSourceMapRoute = createApmServerRoute({
   endpoint: 'POST /api/apm/sourcemaps 2023-10-31',
   options: {
-    tags: ['access:apm', 'access:apm_write'],
     body: { accepts: ['multipart/form-data'] },
   },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   params: t.type({
     body: t.type({
       service_name: t.string,
@@ -159,7 +163,11 @@ const uploadSourceMapRoute = createApmServerRoute({
 
 const deleteSourceMapRoute = createApmServerRoute({
   endpoint: 'DELETE /api/apm/sourcemaps/{id} 2023-10-31',
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   params: t.type({
     path: t.type({
       id: t.string,
@@ -192,7 +200,11 @@ const deleteSourceMapRoute = createApmServerRoute({
 
 const migrateFleetArtifactsSourceMapRoute = createApmServerRoute({
   endpoint: 'POST /internal/apm/sourcemaps/migrate_fleet_artifacts',
-  options: { tags: ['access:apm', 'access:apm_write'] },
+  security: {
+    authz: {
+      requiredPrivileges: ['apm', 'apm_write'],
+    },
+  },
   handler: async ({ plugins, core, logger, featureFlags }): Promise<void> => {
     throwNotImplementedIfSourceMapNotAvailable(featureFlags);
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/span_links/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/span_links/route.ts
index 95e038f8b0184..6a3531e4fa443 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/span_links/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/span_links/route.ts
@@ -23,7 +23,7 @@ const linkedParentsRoute = createApmServerRoute({
     }),
     query: t.intersection([kueryRt, rangeRt, t.type({ processorEvent: processorEventRt })]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -63,7 +63,7 @@ const linkedChildrenRoute = createApmServerRoute({
     }),
     query: t.intersection([kueryRt, rangeRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/storage_explorer/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/storage_explorer/route.ts
index 6592e86297046..75f1e5168ac87 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/storage_explorer/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/storage_explorer/route.ts
@@ -34,7 +34,7 @@ import { isCrossClusterSearch } from './is_cross_cluster_search';
 
 const storageExplorerRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_explorer',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([indexLifecyclePhaseRt, probabilityRt, environmentRt, kueryRt, rangeRt]),
   }),
@@ -86,7 +86,7 @@ const storageExplorerRoute = createApmServerRoute({
 
 const storageExplorerServiceDetailsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/services/{serviceName}/storage_details',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     path: t.type({
       serviceName: t.string,
@@ -127,7 +127,7 @@ const storageExplorerServiceDetailsRoute = createApmServerRoute({
 
 const storageChartRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_chart',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([indexLifecyclePhaseRt, probabilityRt, environmentRt, kueryRt, rangeRt]),
   }),
@@ -177,7 +177,7 @@ const storageChartRoute = createApmServerRoute({
 
 const storageExplorerPrivilegesRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_explorer/privileges',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
 
   handler: async (resources): Promise<{ hasPrivileges: boolean }> => {
     const {
@@ -201,7 +201,7 @@ const storageExplorerPrivilegesRoute = createApmServerRoute({
 
 const storageExplorerSummaryStatsRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_explorer_summary_stats',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([indexLifecyclePhaseRt, probabilityRt, environmentRt, kueryRt, rangeRt]),
   }),
@@ -245,7 +245,7 @@ const storageExplorerSummaryStatsRoute = createApmServerRoute({
 
 const storageExplorerIsCrossClusterSearchRoute = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_explorer/is_cross_cluster_search',
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ isCrossClusterSearch: boolean }> => {
     const apmEventClient = await getApmEventClient(resources);
     return { isCrossClusterSearch: isCrossClusterSearch(apmEventClient) };
@@ -254,9 +254,7 @@ const storageExplorerIsCrossClusterSearchRoute = createApmServerRoute({
 
 const storageExplorerGetServices = createApmServerRoute({
   endpoint: 'GET /internal/apm/storage_explorer/get_services',
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   params: t.type({
     query: t.intersection([indexLifecyclePhaseRt, environmentRt, kueryRt, rangeRt]),
   }),
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/suggestions/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/suggestions/route.ts
index 40b49390bd8ff..0ab43cab30826 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/suggestions/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/suggestions/route.ts
@@ -26,7 +26,7 @@ const suggestionsRoute = createApmServerRoute({
       t.partial({ serviceName: t.string }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ terms: string[] }> => {
     const apmEventClient = await getApmEventClient(resources);
     const { context, params, config } = resources;
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/time_range_metadata/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/time_range_metadata/route.ts
index bf91af259249e..dcd5fa39e97f2 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/time_range_metadata/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/time_range_metadata/route.ts
@@ -26,9 +26,7 @@ export const timeRangeMetadataRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TimeRangeMetadata> => {
     const apmEventClient = await getApmEventClient(resources);
     const apmDataAccessServices = await getApmDataAccessServices({ apmEventClient, ...resources });
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/traces/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/traces/route.ts
index 0814bcdc5738f..804562c038051 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/traces/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/traces/route.ts
@@ -35,7 +35,7 @@ const tracesRoute = createApmServerRoute({
   params: t.type({
     query: t.intersection([environmentRt, kueryRt, rangeRt, probabilityRt]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TopTracesPrimaryStatsResponse> => {
     const {
       config,
@@ -83,7 +83,7 @@ const tracesByIdRoute = createApmServerRoute({
       t.partial({ maxTraceItems: toNumberRt }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -127,7 +127,7 @@ const rootTransactionByTraceIdRoute = createApmServerRoute({
     }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -154,7 +154,7 @@ const transactionByIdRoute = createApmServerRoute({
     }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -190,7 +190,7 @@ const transactionByNameRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -227,9 +227,7 @@ const findTracesRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
@@ -264,9 +262,7 @@ const aggregatedCriticalPathRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<{ criticalPath: CriticalPathResponse | null }> => {
     const {
       params: {
@@ -297,7 +293,7 @@ const transactionFromTraceByIdRoute = createApmServerRoute({
     }),
     query: rangeRt,
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<Transaction | undefined> => {
     const { params } = resources;
     const {
@@ -328,7 +324,7 @@ const spanFromTraceByIdRoute = createApmServerRoute({
       t.union([t.partial({ parentTransactionId: t.string }), t.undefined]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (
     resources
   ): Promise<{
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/transactions/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/transactions/route.ts
index 816879d7cb40a..51ada72e38588 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/transactions/route.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/transactions/route.ts
@@ -75,9 +75,7 @@ const transactionGroupsMainStatisticsRoute = createApmServerRoute({
       transactionDataSourceRt,
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<MergedServiceTransactionGroupsResponse> => {
     const { params } = resources;
     const apmEventClient = await getApmEventClient(resources);
@@ -164,9 +162,7 @@ const transactionGroupsDetailedStatisticsRoute = createApmServerRoute({
       }),
     ]),
   }),
-  options: {
-    tags: ['access:apm'],
-  },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ServiceTransactionGroupDetailedStatisticsResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -226,7 +222,7 @@ const transactionLatencyChartsRoute = createApmServerRoute({
       serviceTransactionDataSourceRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TransactionLatencyResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params, logger } = resources;
@@ -295,7 +291,7 @@ const transactionTraceSamplesRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TransactionTraceSamplesResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params } = resources;
@@ -344,7 +340,7 @@ const transactionChartsBreakdownRoute = createApmServerRoute({
       rangeRt,
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<TransactionBreakdownResponse> => {
     const apmEventClient = await getApmEventClient(resources);
     const { params, config } = resources;
@@ -378,7 +374,7 @@ const transactionChartsErrorRateRoute = createApmServerRoute({
       t.intersection([environmentRt, kueryRt, rangeRt, offsetRt, serviceTransactionDataSourceRt]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<FailedTransactionRateResponse> => {
     const apmEventClient = await getApmEventClient(resources);
 
@@ -427,7 +423,7 @@ const transactionChartsColdstartRateRoute = createApmServerRoute({
       t.intersection([environmentRt, kueryRt, rangeRt, offsetRt]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ColdstartRateResponse> => {
     const apmEventClient = await getApmEventClient(resources);
 
@@ -469,7 +465,7 @@ const transactionChartsColdstartRateByTransactionNameRoute = createApmServerRout
       t.intersection([environmentRt, kueryRt, rangeRt, offsetRt]),
     ]),
   }),
-  options: { tags: ['access:apm'] },
+  security: { authz: { requiredPrivileges: ['apm'] } },
   handler: async (resources): Promise<ColdstartRateResponse> => {
     const apmEventClient = await getApmEventClient(resources);
 
diff --git a/x-pack/plugins/observability_solution/apm/server/routes/typings.ts b/x-pack/plugins/observability_solution/apm/server/routes/typings.ts
index de5aeb6031d1c..830810af60cb5 100644
--- a/x-pack/plugins/observability_solution/apm/server/routes/typings.ts
+++ b/x-pack/plugins/observability_solution/apm/server/routes/typings.ts
@@ -45,17 +45,7 @@ export type MinimalApmPluginRequestHandlerContext = Omit<
 };
 
 export interface APMRouteCreateOptions {
-  tags: Array<
-    | 'access:apm'
-    | 'access:apm_write'
-    | 'access:apm_settings_write'
-    | 'access:ml:canGetJobs'
-    | 'access:ml:canCreateJob'
-    | 'access:ml:canCloseJob'
-    | 'access:ai_assistant'
-    | 'oas-tag:APM agent keys'
-    | 'oas-tag:APM annotations'
-  >;
+  tags?: Array<'oas-tag:APM agent keys' | 'oas-tag:APM annotations'>;
   disableTelemetry?: boolean;
 }
 
diff --git a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts
index 06be441facd25..f8b370dc18860 100644
--- a/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/settings/anomaly_detection/no_access_user.spec.ts
@@ -38,7 +38,9 @@ export default function apiTest({ getService }: FtrProviderContext) {
           const err = await expectToReject<ApmApiError>(() => getJobs());
 
           expect(err.res.status).to.be(403);
-          expect(err.res.body.message).eql('Forbidden');
+          expect(err.res.body.message).eql(
+            'API [GET /internal/apm/settings/anomaly-detection/jobs] is unauthorized for user, this action is granted by the Kibana privileges [apm,ml:canGetJobs]'
+          );
         });
       });
 
@@ -49,7 +51,9 @@ export default function apiTest({ getService }: FtrProviderContext) {
           );
 
           expect(err.res.status).to.be(403);
-          expect(err.res.body.message).eql('Forbidden');
+          expect(err.res.body.message).eql(
+            'API [POST /internal/apm/settings/anomaly-detection/jobs] is unauthorized for user, this action is granted by the Kibana privileges [apm,apm_settings_write,ml:canCreateJob]'
+          );
         });
       });
     });