Skip to content

Commit df2473e

Browse files
[9.2] [Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch (#241195) (#241337)
# Backport This will backport the following commits from `main` to `9.2`: - [[Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch (#241195)](#241195) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Chris Cowan","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-10-30T17:08:35Z","message":"[Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch (#241195)\n\n## 🍒 Summary\n\nThis PR updates the authorization model for all three metrics experience\nAPI routes to delegate authorization to Elasticsearch instead of using\nKibana's privilege system. The routes now rely on Elasticsearch's native\nindex-level security, following the same pattern used by the data_views\nplugin.\n\nFixes #241159\n\n## 🛠️ Changes\n\n- Changed security configuration in dimensions route (`GET\n/internal/metrics_experience/dimensions`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in fields route (`GET\n/internal/metrics_experience/fields`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in index_pattern route (`GET\n/internal/metrics_experience/index_pattern_metadata/{indexPattern}`)\nfrom `requiredPrivileges: ['read']` to `enabled: false, reason:\n'Authorization provided by Elasticsearch'`\n- All routes now rely on Elasticsearch authorization via\n`elasticsearch.client.asCurrentUser` instead of Kibana authorization\n- This follows the same pattern used by the data_views plugin for\nsimilar data-access routes (see:\n`src/platform/plugins/shared/data_views/server/rest_api_routes/internal/fields_for.ts:250`)\n\n## 🎯 Rationale\n\n- All routes use `elasticsearch.client.asCurrentUser`, which executes\nqueries with the authenticated user's credentials\n- Elasticsearch enforces its own authorization based on the user's index\nprivileges\n- Simplifies the authorization model by delegating to Elasticsearch's\nnative security\n- Consistent with how data-access routes should handle authorization\n\n## 🧪 Testing\n\nUsers with appropriate Elasticsearch index privileges will be able to\naccess the routes, while users without proper privileges will receive\nElasticsearch authorization errors. Authentication is still required at\nthe Kibana level.\n\nCreate a \"role\" under Stack Management called `viewer_custom` with the\nfollowing setup:\n\n<img width=\"1131\" height=\"1003\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/278e1b9d-df2b-4c8b-94ba-29f1a95c61c6\"\n/>\n\nCreate a guest user and assign it the `viewer_custom` role.\n\nIndex data using\n[SimianForge](https://github.com/simianhacker/simian-forge):\n- `./forge --dataset weather --count 20 --interval 10s --backfill now-3m\n--purge` which will create `fieldsense-station-metrics` index\n- `./forge --count 10 --interval 10s --backfill now-1h --purge` which\nwill create `metrics-hostmetricsreceiver.otel-default` and all the\nMetricbeat indices\n\nNavigate to Discover, change to \"ESQL Mode\":\n- `TS metrics-*` should only show the data from\n`metrics-hostmetricsreceiver.otel-default`\n- `TS fieldsense-station-metrics` should not work and display: \n ```\n[esql] > Unexpected error from Elasticsearch: verification_exception -\nFound 1 problem\n line 1:1: Unknown index [fieldsense-station-metrics]\n ```\n\n🤖 This pull request was assisted by Cursor","sha":"8f07998c3db32b7d12669c778d104bfa7e2e64ae","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:obs-ux-infra_services","backport:version","v9.2.0","Feature:Metrics in Discover","v9.3.0","v9.2.1"],"title":"[Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch","number":241195,"url":"https://github.com/elastic/kibana/pull/241195","mergeCommit":{"message":"[Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch (#241195)\n\n## 🍒 Summary\n\nThis PR updates the authorization model for all three metrics experience\nAPI routes to delegate authorization to Elasticsearch instead of using\nKibana's privilege system. The routes now rely on Elasticsearch's native\nindex-level security, following the same pattern used by the data_views\nplugin.\n\nFixes #241159\n\n## 🛠️ Changes\n\n- Changed security configuration in dimensions route (`GET\n/internal/metrics_experience/dimensions`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in fields route (`GET\n/internal/metrics_experience/fields`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in index_pattern route (`GET\n/internal/metrics_experience/index_pattern_metadata/{indexPattern}`)\nfrom `requiredPrivileges: ['read']` to `enabled: false, reason:\n'Authorization provided by Elasticsearch'`\n- All routes now rely on Elasticsearch authorization via\n`elasticsearch.client.asCurrentUser` instead of Kibana authorization\n- This follows the same pattern used by the data_views plugin for\nsimilar data-access routes (see:\n`src/platform/plugins/shared/data_views/server/rest_api_routes/internal/fields_for.ts:250`)\n\n## 🎯 Rationale\n\n- All routes use `elasticsearch.client.asCurrentUser`, which executes\nqueries with the authenticated user's credentials\n- Elasticsearch enforces its own authorization based on the user's index\nprivileges\n- Simplifies the authorization model by delegating to Elasticsearch's\nnative security\n- Consistent with how data-access routes should handle authorization\n\n## 🧪 Testing\n\nUsers with appropriate Elasticsearch index privileges will be able to\naccess the routes, while users without proper privileges will receive\nElasticsearch authorization errors. Authentication is still required at\nthe Kibana level.\n\nCreate a \"role\" under Stack Management called `viewer_custom` with the\nfollowing setup:\n\n<img width=\"1131\" height=\"1003\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/278e1b9d-df2b-4c8b-94ba-29f1a95c61c6\"\n/>\n\nCreate a guest user and assign it the `viewer_custom` role.\n\nIndex data using\n[SimianForge](https://github.com/simianhacker/simian-forge):\n- `./forge --dataset weather --count 20 --interval 10s --backfill now-3m\n--purge` which will create `fieldsense-station-metrics` index\n- `./forge --count 10 --interval 10s --backfill now-1h --purge` which\nwill create `metrics-hostmetricsreceiver.otel-default` and all the\nMetricbeat indices\n\nNavigate to Discover, change to \"ESQL Mode\":\n- `TS metrics-*` should only show the data from\n`metrics-hostmetricsreceiver.otel-default`\n- `TS fieldsense-station-metrics` should not work and display: \n ```\n[esql] > Unexpected error from Elasticsearch: verification_exception -\nFound 1 problem\n line 1:1: Unknown index [fieldsense-station-metrics]\n ```\n\n🤖 This pull request was assisted by Cursor","sha":"8f07998c3db32b7d12669c778d104bfa7e2e64ae"}},"sourceBranch":"main","suggestedTargetBranches":["9.2"],"targetPullRequestStates":[{"branch":"9.2","label":"v9.2.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/241195","number":241195,"mergeCommit":{"message":"[Metrics][Discover] Update Metrics Experience routes to delegate authorization to Elasticsearch (#241195)\n\n## 🍒 Summary\n\nThis PR updates the authorization model for all three metrics experience\nAPI routes to delegate authorization to Elasticsearch instead of using\nKibana's privilege system. The routes now rely on Elasticsearch's native\nindex-level security, following the same pattern used by the data_views\nplugin.\n\nFixes #241159\n\n## 🛠️ Changes\n\n- Changed security configuration in dimensions route (`GET\n/internal/metrics_experience/dimensions`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in fields route (`GET\n/internal/metrics_experience/fields`) from `requiredPrivileges:\n['read']` to `enabled: false, reason: 'Authorization provided by\nElasticsearch'`\n- Changed security configuration in index_pattern route (`GET\n/internal/metrics_experience/index_pattern_metadata/{indexPattern}`)\nfrom `requiredPrivileges: ['read']` to `enabled: false, reason:\n'Authorization provided by Elasticsearch'`\n- All routes now rely on Elasticsearch authorization via\n`elasticsearch.client.asCurrentUser` instead of Kibana authorization\n- This follows the same pattern used by the data_views plugin for\nsimilar data-access routes (see:\n`src/platform/plugins/shared/data_views/server/rest_api_routes/internal/fields_for.ts:250`)\n\n## 🎯 Rationale\n\n- All routes use `elasticsearch.client.asCurrentUser`, which executes\nqueries with the authenticated user's credentials\n- Elasticsearch enforces its own authorization based on the user's index\nprivileges\n- Simplifies the authorization model by delegating to Elasticsearch's\nnative security\n- Consistent with how data-access routes should handle authorization\n\n## 🧪 Testing\n\nUsers with appropriate Elasticsearch index privileges will be able to\naccess the routes, while users without proper privileges will receive\nElasticsearch authorization errors. Authentication is still required at\nthe Kibana level.\n\nCreate a \"role\" under Stack Management called `viewer_custom` with the\nfollowing setup:\n\n<img width=\"1131\" height=\"1003\" alt=\"image\"\nsrc=\"https://github.com/user-attachments/assets/278e1b9d-df2b-4c8b-94ba-29f1a95c61c6\"\n/>\n\nCreate a guest user and assign it the `viewer_custom` role.\n\nIndex data using\n[SimianForge](https://github.com/simianhacker/simian-forge):\n- `./forge --dataset weather --count 20 --interval 10s --backfill now-3m\n--purge` which will create `fieldsense-station-metrics` index\n- `./forge --count 10 --interval 10s --backfill now-1h --purge` which\nwill create `metrics-hostmetricsreceiver.otel-default` and all the\nMetricbeat indices\n\nNavigate to Discover, change to \"ESQL Mode\":\n- `TS metrics-*` should only show the data from\n`metrics-hostmetricsreceiver.otel-default`\n- `TS fieldsense-station-metrics` should not work and display: \n ```\n[esql] > Unexpected error from Elasticsearch: verification_exception -\nFound 1 problem\n line 1:1: Unknown index [fieldsense-station-metrics]\n ```\n\n🤖 This pull request was assisted by Cursor","sha":"8f07998c3db32b7d12669c778d104bfa7e2e64ae"}}]}] BACKPORT--> Co-authored-by: Chris Cowan <[email protected]>
1 parent 2c2f413 commit df2473e

File tree

3 files changed

+3
-3
lines changed

3 files changed

+3
-3
lines changed

src/platform/plugins/shared/metrics_experience/server/routes/dimensions/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { throwNotFoundIfMetricsExperienceDisabled } from '../../lib/utils';
1717

1818
export const getDimensionsRoute = createRoute({
1919
endpoint: 'GET /internal/metrics_experience/dimensions',
20-
security: { authz: { requiredPrivileges: ['read'] } },
20+
security: { authz: { enabled: false, reason: 'Authorization provided by Elasticsearch' } },
2121
params: z.object({
2222
query: z.object({
2323
dimensions: z

src/platform/plugins/shared/metrics_experience/server/routes/fields/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { throwNotFoundIfMetricsExperienceDisabled } from '../../lib/utils';
1717

1818
export const getFieldsRoute = createRoute({
1919
endpoint: 'GET /internal/metrics_experience/fields',
20-
security: { authz: { requiredPrivileges: ['read'] } },
20+
security: { authz: { enabled: false, reason: 'Authorization provided by Elasticsearch' } },
2121
params: z.object({
2222
query: z.object({
2323
index: z.string().default('metrics-*'),

src/platform/plugins/shared/metrics_experience/server/routes/index_pattern/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { throwNotFoundIfMetricsExperienceDisabled } from '../../lib/utils';
1616

1717
export const getIndexPatternMetadataRoute = createRoute({
1818
endpoint: 'GET /internal/metrics_experience/index_pattern_metadata/{indexPattern}',
19-
security: { authz: { requiredPrivileges: ['read'] } },
19+
security: { authz: { enabled: false, reason: 'Authorization provided by Elasticsearch' } },
2020
params: z.object({
2121
path: z.object({
2222
indexPattern: z.string(),

0 commit comments

Comments
 (0)