[Entity Analytics] Parameterise refresh on resolution bulk writes#268467
Conversation
Replace the hardcoded `refresh: true` in `bulkUpdateEntityDocs` with a configurable `refresh` option (default `'wait_for'`). The previous value required the `indices:admin/refresh/unpromotable` action, which the serverless `platform_engineer` role does not have on `.entities.v2.latest.*`, causing 403s on `/resolution/link` and `/resolution/unlink`. Callers: - UI flyout routes: default `'wait_for'` so the immediate refetch sees the new state. - CSV upload (`processRow`): `refresh: false` — `'wait_for'` adds ~1s per row, exceeding the HTTP socket timeout on 200-row uploads. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (matches existing cross-upload "latest wins" semantics). - Automated resolution maintainer: `refresh: false` — buckets are pre-collected in memory; nothing within the same task run reads back the write, so the wait is dead time. Both `'wait_for'` and `false` only require `write` privilege. Fixes #266752
|
/ci |
|
Pinging @elastic/contextual-security-apps (Team:Cloud Security) |
Flaky Test Runner Stats🎉 All tests passed! - kibana-flaky-test-suite-runner#12242[✅] x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/entity_resolution/trial_license_complete_tier/configs/ess.config.ts: 25/25 tests passed. |
seanrathier
left a comment
There was a problem hiding this comment.
Approving context apps team ownership
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]
History
|
|
Starting backport for target branches: 9.4 |
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…astic#268467) ## Summary Fixes the 403 returned by `POST /api/security/entity_store/resolution/link` and `/unlink` on serverless with `platform_engineer` role (caught in e2e tests). Root cause: `bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which requires the `indices:admin/refresh/unpromotable` action — not granted to `platform_engineer` on `.entities.v2.latest.*`. This PR replaces the hardcoded `refresh: true` with a configurable `refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`. Both `'wait_for'` and `false` only require `write` privilege. Caller settings: | Caller | Setting | Why | | --- | --- | --- | | UI flyout routes (`/resolution/link`, `/resolution/unlink`) | `'wait_for'` (default) | UI immediately refetches the resolution group; without read-your-writes guarantee the refetch might get stale state | | CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in sequential CSV processing; 200-row uploads were exceeding the HTTP socket timeout. With `false`, 200 rows complete in ~2s. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (though this matches existing "latest wins" semantics) | | Automated resolution maintainer | `false` | Buckets are pre-collected in memory; nothing within the same task run reads back the write, so the refresh wait is dead time | Fixes elastic#266752 Related: elastic#266589 (Cypress e2e that surfaced the bug) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks - **Stale read for ~1s after CSV upload / maintainer write.** Severity: low. Mitigation: the CSV per-row response is built from in-process state, not a re-read; the maintainer doesn't read back its own writes within a run. Subsequent reads from a different request will see the new state after the next natural index refresh (<1s). - **"Last write wins" within a single CSV upload.** Severity: low. Mitigation: matches the broader "latest wins" approach already accepted. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…astic#268467) ## Summary Fixes the 403 returned by `POST /api/security/entity_store/resolution/link` and `/unlink` on serverless with `platform_engineer` role (caught in e2e tests). Root cause: `bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which requires the `indices:admin/refresh/unpromotable` action — not granted to `platform_engineer` on `.entities.v2.latest.*`. This PR replaces the hardcoded `refresh: true` with a configurable `refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`. Both `'wait_for'` and `false` only require `write` privilege. Caller settings: | Caller | Setting | Why | | --- | --- | --- | | UI flyout routes (`/resolution/link`, `/resolution/unlink`) | `'wait_for'` (default) | UI immediately refetches the resolution group; without read-your-writes guarantee the refetch might get stale state | | CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in sequential CSV processing; 200-row uploads were exceeding the HTTP socket timeout. With `false`, 200 rows complete in ~2s. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (though this matches existing "latest wins" semantics) | | Automated resolution maintainer | `false` | Buckets are pre-collected in memory; nothing within the same task run reads back the write, so the refresh wait is dead time | Fixes elastic#266752 Related: elastic#266589 (Cypress e2e that surfaced the bug) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks - **Stale read for ~1s after CSV upload / maintainer write.** Severity: low. Mitigation: the CSV per-row response is built from in-process state, not a re-read; the maintainer doesn't read back its own writes within a run. Subsequent reads from a different request will see the new state after the next natural index refresh (<1s). - **"Last write wins" within a single CSV upload.** Severity: low. Mitigation: matches the broader "latest wins" approach already accepted. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…astic#268467) ## Summary Fixes the 403 returned by `POST /api/security/entity_store/resolution/link` and `/unlink` on serverless with `platform_engineer` role (caught in e2e tests). Root cause: `bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which requires the `indices:admin/refresh/unpromotable` action — not granted to `platform_engineer` on `.entities.v2.latest.*`. This PR replaces the hardcoded `refresh: true` with a configurable `refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`. Both `'wait_for'` and `false` only require `write` privilege. Caller settings: | Caller | Setting | Why | | --- | --- | --- | | UI flyout routes (`/resolution/link`, `/resolution/unlink`) | `'wait_for'` (default) | UI immediately refetches the resolution group; without read-your-writes guarantee the refetch might get stale state | | CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in sequential CSV processing; 200-row uploads were exceeding the HTTP socket timeout. With `false`, 200 rows complete in ~2s. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (though this matches existing "latest wins" semantics) | | Automated resolution maintainer | `false` | Buckets are pre-collected in memory; nothing within the same task run reads back the write, so the refresh wait is dead time | Fixes elastic#266752 Related: elastic#266589 (Cypress e2e that surfaced the bug) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks - **Stale read for ~1s after CSV upload / maintainer write.** Severity: low. Mitigation: the CSV per-row response is built from in-process state, not a re-read; the maintainer doesn't read back its own writes within a run. Subsequent reads from a different request will see the new state after the next natural index refresh (<1s). - **"Last write wins" within a single CSV upload.** Severity: low. Mitigation: matches the broader "latest wins" approach already accepted. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
|
Looks like this PR has a backport PR but it still hasn't been merged. Please merge it ASAP to keep the branches relatively in sync. |
1 similar comment
|
Looks like this PR has a backport PR but it still hasn't been merged. Please merge it ASAP to keep the branches relatively in sync. |
…es (#268467) (#269149) # Backport This will backport the following commits from `main` to `9.4`: - [[Entity Analytics] Parameterise refresh on resolution bulk writes (#268467)](#268467) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Maxim Kholod","email":"maxim.kholod@elastic.co"},"sourceCommit":{"committedDate":"2026-05-13T15:36:47Z","message":"[Entity Analytics] Parameterise refresh on resolution bulk writes (#268467)\n\n## Summary\n\nFixes the 403 returned by `POST\n/api/security/entity_store/resolution/link` and `/unlink` on serverless\nwith `platform_engineer` role (caught in e2e tests). Root cause:\n`bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which\nrequires the `indices:admin/refresh/unpromotable` action — not granted\nto `platform_engineer` on `.entities.v2.latest.*`.\n\nThis PR replaces the hardcoded `refresh: true` with a configurable\n`refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`.\nBoth `'wait_for'` and `false` only require `write` privilege.\n\nCaller settings:\n\n| Caller | Setting | Why |\n| --- | --- | --- |\n| UI flyout routes (`/resolution/link`, `/resolution/unlink`) |\n`'wait_for'` (default) | UI immediately refetches the resolution group;\nwithout read-your-writes guarantee the refetch might get stale state |\n| CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in\nsequential CSV processing; 200-row uploads were exceeding the HTTP\nsocket timeout. With `false`, 200 rows complete in ~2s. Trade-off:\nwithin a single upload, two rows resolving the same alias to different\ntargets silently take the last writer (though this matches existing\n\"latest wins\" semantics) |\n| Automated resolution maintainer | `false` | Buckets are pre-collected\nin memory; nothing within the same task run reads back the write, so the\nrefresh wait is dead time |\n\nFixes #266752\nRelated: #266589 (Cypress e2e that surfaced the bug)\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\n- **Stale read for ~1s after CSV upload / maintainer write.** Severity:\nlow. Mitigation: the CSV per-row response is built from in-process\nstate, not a re-read; the maintainer doesn't read back its own writes\nwithin a run. Subsequent reads from a different request will see the new\nstate after the next natural index refresh (<1s).\n- **\"Last write wins\" within a single CSV upload.** Severity: low.\nMitigation: matches the broader \"latest wins\" approach already accepted.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"fe6e6a7001895d67172f58076946910e349537bf","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Cloud Security","backport:version","v9.5.0","v9.4.1"],"title":"[Entity Analytics] Parameterise refresh on resolution bulk writes","number":268467,"url":"https://github.com/elastic/kibana/pull/268467","mergeCommit":{"message":"[Entity Analytics] Parameterise refresh on resolution bulk writes (#268467)\n\n## Summary\n\nFixes the 403 returned by `POST\n/api/security/entity_store/resolution/link` and `/unlink` on serverless\nwith `platform_engineer` role (caught in e2e tests). Root cause:\n`bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which\nrequires the `indices:admin/refresh/unpromotable` action — not granted\nto `platform_engineer` on `.entities.v2.latest.*`.\n\nThis PR replaces the hardcoded `refresh: true` with a configurable\n`refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`.\nBoth `'wait_for'` and `false` only require `write` privilege.\n\nCaller settings:\n\n| Caller | Setting | Why |\n| --- | --- | --- |\n| UI flyout routes (`/resolution/link`, `/resolution/unlink`) |\n`'wait_for'` (default) | UI immediately refetches the resolution group;\nwithout read-your-writes guarantee the refetch might get stale state |\n| CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in\nsequential CSV processing; 200-row uploads were exceeding the HTTP\nsocket timeout. With `false`, 200 rows complete in ~2s. Trade-off:\nwithin a single upload, two rows resolving the same alias to different\ntargets silently take the last writer (though this matches existing\n\"latest wins\" semantics) |\n| Automated resolution maintainer | `false` | Buckets are pre-collected\nin memory; nothing within the same task run reads back the write, so the\nrefresh wait is dead time |\n\nFixes #266752\nRelated: #266589 (Cypress e2e that surfaced the bug)\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\n- **Stale read for ~1s after CSV upload / maintainer write.** Severity:\nlow. Mitigation: the CSV per-row response is built from in-process\nstate, not a re-read; the maintainer doesn't read back its own writes\nwithin a run. Subsequent reads from a different request will see the new\nstate after the next natural index refresh (<1s).\n- **\"Last write wins\" within a single CSV upload.** Severity: low.\nMitigation: matches the broader \"latest wins\" approach already accepted.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"fe6e6a7001895d67172f58076946910e349537bf"}},"sourceBranch":"main","suggestedTargetBranches":["9.4"],"targetPullRequestStates":[{"branch":"main","label":"v9.5.0","branchLabelMappingKey":"^v9.5.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/268467","number":268467,"mergeCommit":{"message":"[Entity Analytics] Parameterise refresh on resolution bulk writes (#268467)\n\n## Summary\n\nFixes the 403 returned by `POST\n/api/security/entity_store/resolution/link` and `/unlink` on serverless\nwith `platform_engineer` role (caught in e2e tests). Root cause:\n`bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which\nrequires the `indices:admin/refresh/unpromotable` action — not granted\nto `platform_engineer` on `.entities.v2.latest.*`.\n\nThis PR replaces the hardcoded `refresh: true` with a configurable\n`refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`.\nBoth `'wait_for'` and `false` only require `write` privilege.\n\nCaller settings:\n\n| Caller | Setting | Why |\n| --- | --- | --- |\n| UI flyout routes (`/resolution/link`, `/resolution/unlink`) |\n`'wait_for'` (default) | UI immediately refetches the resolution group;\nwithout read-your-writes guarantee the refetch might get stale state |\n| CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in\nsequential CSV processing; 200-row uploads were exceeding the HTTP\nsocket timeout. With `false`, 200 rows complete in ~2s. Trade-off:\nwithin a single upload, two rows resolving the same alias to different\ntargets silently take the last writer (though this matches existing\n\"latest wins\" semantics) |\n| Automated resolution maintainer | `false` | Buckets are pre-collected\nin memory; nothing within the same task run reads back the write, so the\nrefresh wait is dead time |\n\nFixes #266752\nRelated: #266589 (Cypress e2e that surfaced the bug)\n\n### Checklist\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.\n\n### Identify risks\n\n- **Stale read for ~1s after CSV upload / maintainer write.** Severity:\nlow. Mitigation: the CSV per-row response is built from in-process\nstate, not a re-read; the maintainer doesn't read back its own writes\nwithin a run. Subsequent reads from a different request will see the new\nstate after the next natural index refresh (<1s).\n- **\"Last write wins\" within a single CSV upload.** Severity: low.\nMitigation: matches the broader \"latest wins\" approach already accepted.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"fe6e6a7001895d67172f58076946910e349537bf"}},{"branch":"9.4","label":"v9.4.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> --------- Co-authored-by: Maxim Kholod <maxim.kholod@elastic.co>
…68467) ## Summary Fixes the 403 returned by `POST /api/security/entity_store/resolution/link` and `/unlink` on serverless with `platform_engineer` role (caught in e2e tests). Root cause: `bulkUpdateEntityDocs` called `esClient.bulk({ refresh: true })`, which requires the `indices:admin/refresh/unpromotable` action — not granted to `platform_engineer` on `.entities.v2.latest.*`. This PR replaces the hardcoded `refresh: true` with a configurable `refresh` option on `bulkUpdateEntityDocs`, defaulting to `'wait_for'`. Both `'wait_for'` and `false` only require `write` privilege. Caller settings: | Caller | Setting | Why | | --- | --- | --- | | UI flyout routes (`/resolution/link`, `/resolution/unlink`) | `'wait_for'` (default) | UI immediately refetches the resolution group; without read-your-writes guarantee the refetch might get stale state | | CSV upload (`processRow`) | `false` | `'wait_for'` adds ~1s per row in sequential CSV processing; 200-row uploads were exceeding the HTTP socket timeout. With `false`, 200 rows complete in ~2s. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (though this matches existing "latest wins" semantics) | | Automated resolution maintainer | `false` | Buckets are pre-collected in memory; nothing within the same task run reads back the write, so the refresh wait is dead time | Fixes #266752 Related: #266589 (Cypress e2e that surfaced the bug) ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks - **Stale read for ~1s after CSV upload / maintainer write.** Severity: low. Mitigation: the CSV per-row response is built from in-process state, not a re-read; the maintainer doesn't read back its own writes within a run. Subsequent reads from a different request will see the new state after the next natural index refresh (<1s). - **"Last write wins" within a single CSV upload.** Severity: low. Mitigation: matches the broader "latest wins" approach already accepted. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…ution public methods (#269308) ## Summary Refactor on top of #268467 which introduced a `refresh` option on `ResolutionClient.linkEntities`/`unlinkEntities`. **What changed:** - Replaces ES-vocabulary `refresh` with domain-named `awaitVisibility` (default `false`) on the API - Two-layer naming convention: the infra layer (`bulkUpdateEntityDocs`) keeps ES vocabulary with a corrected default of `false`; the domain layer exposes `awaitVisibility` and translates internally - UI route handlers (`link`, `unlink`) pass `{ awaitVisibility: true }` to get read-your-writes semantics after a user-triggered operation - Background maintainer drop the now-redundant explicit `{ refresh: false }` — the new default covers it **Why:** `refresh` leaks Elasticsearch vocabulary into the domain layer and requires callers to know what `'wait_for'` means. `awaitVisibility` is self-documenting and hides the translation detail. ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Low risk — pure internal rename refactor within the `entity_store` plugin. - No public API surface changed (all call sites are plugin-internal) - No behavior change: same Elasticsearch semantics, same effective defaults - No deployment-mode divergence (stateful/serverless unaffected)
…ution public methods (elastic#269308) ## Summary Refactor on top of elastic#268467 which introduced a `refresh` option on `ResolutionClient.linkEntities`/`unlinkEntities`. **What changed:** - Replaces ES-vocabulary `refresh` with domain-named `awaitVisibility` (default `false`) on the API - Two-layer naming convention: the infra layer (`bulkUpdateEntityDocs`) keeps ES vocabulary with a corrected default of `false`; the domain layer exposes `awaitVisibility` and translates internally - UI route handlers (`link`, `unlink`) pass `{ awaitVisibility: true }` to get read-your-writes semantics after a user-triggered operation - Background maintainer drop the now-redundant explicit `{ refresh: false }` — the new default covers it **Why:** `refresh` leaks Elasticsearch vocabulary into the domain layer and requires callers to know what `'wait_for'` means. `awaitVisibility` is self-documenting and hides the translation detail. ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Low risk — pure internal rename refactor within the `entity_store` plugin. - No public API surface changed (all call sites are plugin-internal) - No behavior change: same Elasticsearch semantics, same effective defaults - No deployment-mode divergence (stateful/serverless unaffected)
…solution flyout Cypress suite (#271764) ## Summary The `resolution_section.cy.ts` suite (entity flyout manual resolution) was shipped with only `@ess` because serverless runs were returning HTTP 403 on the `link`/`unlink` calls — `esClient.bulk({ refresh: true })` requires the `indices:admin/refresh/unpromotable` ES privilege, which the built-in serverless roles (`platform_engineer`, `editor`, `soc_manager`) do not have. That root cause was fixed in #268467 by switching the link/unlink route handlers to `refresh: 'wait_for'`. Issue #266752 has been closed. This PR is the follow-up: remove the blocking comment and re-add `@serverless` to the describe tags so the suite runs in both environments again. Related: #266752 ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [x] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels.
… on resolution flyout Cypress suite (#271764) (#271946) # Backport This will backport the following commits from `main` to `9.4`: - [[Security Solution][Entity Analytics] Re-enable @serverless tag on resolution flyout Cypress suite (#271764)](#271764) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Maxim Kholod","email":"maxim.kholod@elastic.co"},"sourceCommit":{"committedDate":"2026-05-29T15:15:09Z","message":"[Security Solution][Entity Analytics] Re-enable @serverless tag on resolution flyout Cypress suite (#271764)\n\n## Summary\n\nThe `resolution_section.cy.ts` suite (entity flyout manual resolution)\nwas shipped with only `@ess` because serverless runs were returning HTTP\n403 on the `link`/`unlink` calls — `esClient.bulk({ refresh: true })`\nrequires the `indices:admin/refresh/unpromotable` ES privilege, which\nthe built-in serverless roles (`platform_engineer`, `editor`,\n`soc_manager`) do not have.\n\nThat root cause was fixed in #268467 by switching the link/unlink route\nhandlers to `refresh: 'wait_for'`. Issue #266752 has been closed.\n\nThis PR is the follow-up: remove the blocking comment and re-add\n`@serverless` to the describe tags so the suite runs in both\nenvironments again.\n\nRelated: #266752\n\n### Checklist\n\nCheck the PR satisfies following conditions.\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.","sha":"cff3a34359d5385b2867e721ded5461f0aa1687b","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Cloud Security","backport:version","v9.4.0","v9.5.0"],"title":"[Security Solution][Entity Analytics] Re-enable @serverless tag on resolution flyout Cypress suite","number":271764,"url":"https://github.com/elastic/kibana/pull/271764","mergeCommit":{"message":"[Security Solution][Entity Analytics] Re-enable @serverless tag on resolution flyout Cypress suite (#271764)\n\n## Summary\n\nThe `resolution_section.cy.ts` suite (entity flyout manual resolution)\nwas shipped with only `@ess` because serverless runs were returning HTTP\n403 on the `link`/`unlink` calls — `esClient.bulk({ refresh: true })`\nrequires the `indices:admin/refresh/unpromotable` ES privilege, which\nthe built-in serverless roles (`platform_engineer`, `editor`,\n`soc_manager`) do not have.\n\nThat root cause was fixed in #268467 by switching the link/unlink route\nhandlers to `refresh: 'wait_for'`. Issue #266752 has been closed.\n\nThis PR is the follow-up: remove the blocking comment and re-add\n`@serverless` to the describe tags so the suite runs in both\nenvironments again.\n\nRelated: #266752\n\n### Checklist\n\nCheck the PR satisfies following conditions.\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.","sha":"cff3a34359d5385b2867e721ded5461f0aa1687b"}},"sourceBranch":"main","suggestedTargetBranches":["9.4"],"targetPullRequestStates":[{"branch":"9.4","label":"v9.4.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.5.0","branchLabelMappingKey":"^v9.5.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/271764","number":271764,"mergeCommit":{"message":"[Security Solution][Entity Analytics] Re-enable @serverless tag on resolution flyout Cypress suite (#271764)\n\n## Summary\n\nThe `resolution_section.cy.ts` suite (entity flyout manual resolution)\nwas shipped with only `@ess` because serverless runs were returning HTTP\n403 on the `link`/`unlink` calls — `esClient.bulk({ refresh: true })`\nrequires the `indices:admin/refresh/unpromotable` ES privilege, which\nthe built-in serverless roles (`platform_engineer`, `editor`,\n`soc_manager`) do not have.\n\nThat root cause was fixed in #268467 by switching the link/unlink route\nhandlers to `refresh: 'wait_for'`. Issue #266752 has been closed.\n\nThis PR is the follow-up: remove the blocking comment and re-add\n`@serverless` to the describe tags so the suite runs in both\nenvironments again.\n\nRelated: #266752\n\n### Checklist\n\nCheck the PR satisfies following conditions.\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] Any text added follows [EUI's writing\nguidelines](https://elastic.github.io/eui/#/guidelines/writing), uses\nsentence case text and includes [i18n\nsupport](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] If a plugin configuration key changed, check if it needs to be\nallowlisted in the cloud and added to the [docker\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\n- [x] This was checked for breaking HTTP API changes, and any breaking\nchanges have been approved by the breaking-change committee. The\n`release_note:breaking` label should be applied in these situations.\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n- [x] Review the [backport\nguidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)\nand apply applicable `backport:*` labels.","sha":"cff3a34359d5385b2867e721ded5461f0aa1687b"}}]}] BACKPORT--> Co-authored-by: Maxim Kholod <maxim.kholod@elastic.co>
Summary
Fixes the 403 returned by
POST /api/security/entity_store/resolution/linkand/unlinkon serverless withplatform_engineerrole (caught in e2e tests). Root cause:bulkUpdateEntityDocscalledesClient.bulk({ refresh: true }), which requires theindices:admin/refresh/unpromotableaction — not granted toplatform_engineeron.entities.v2.latest.*.This PR replaces the hardcoded
refresh: truewith a configurablerefreshoption onbulkUpdateEntityDocs, defaulting to'wait_for'. Both'wait_for'andfalseonly requirewriteprivilege.Caller settings:
/resolution/link,/resolution/unlink)'wait_for'(default)processRow)false'wait_for'adds ~1s per row in sequential CSV processing; 200-row uploads were exceeding the HTTP socket timeout. Withfalse, 200 rows complete in ~2s. Trade-off: within a single upload, two rows resolving the same alias to different targets silently take the last writer (though this matches existing "latest wins" semantics)falseFixes #266752
Related: #266589 (Cypress e2e that surfaced the bug)
Checklist
release_note:breakinglabel should be applied in these situations.release_note:*label is applied per the guidelinesbackport:*labels.Identify risks