Add API Key Management and Enable Index Sync via Scheduled Task#225551
Add API Key Management and Enable Index Sync via Scheduled Task#225551CAWilson94 merged 40 commits intoelastic:mainfrom
Conversation
…client; attempt internal user WIP so client
tiansivive
left a comment
There was a problem hiding this comment.
Thanks everyone for the collab! I left some comments
...y/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/auth/api_key.ts
Outdated
Show resolved
Hide resolved
...y/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/auth/api_key.ts
Outdated
Show resolved
Hide resolved
...y/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/auth/api_key.ts
Show resolved
Hide resolved
...solution/server/lib/entity_analytics/privilege_monitoring/tasks/privilege_monitoring_task.ts
Outdated
Show resolved
Hide resolved
...rity/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts
Outdated
Show resolved
Hide resolved
|
Pinging @elastic/security-solution (Team: SecuritySolution) |
|
Pinging @elastic/security-entity-analytics (Team:Entity Analytics) |
… src/core/server/integration_tests/ci_checks'
x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts
Show resolved
Hide resolved
… src/core/server/integration_tests/ci_checks'
@rudolf Thanks! Updated them now :D |
jeramysoucy
left a comment
There was a problem hiding this comment.
Thanks for all the updates and for your patience on this one! Last question for you is if you've considered adding any unit or integration tests for the new functionality/types. I saw the updated authorization api integration tests, but I didn't see any unit or integration tests for the other changes (I may be looking in wrong place).
Hey, thanks to you too for all the direction and help here! Really appreciate it all 🚀 Yes there is a separate ticket out for this here - #225680. The plan will be pull this down and merge it in and cover it along with this larger refactor and testing. @jeramysoucy |
jeramysoucy
left a comment
There was a problem hiding this comment.
Approving with note that test coverage to be implemented in #225680
If further changes are made, please re-request a review before merging.
rudolf
left a comment
There was a problem hiding this comment.
Approving for Core changes related to registering new SO type.
💚 Build Succeeded
Metrics [docs]Public APIs missing comments
Unknown metric groupsAPI count
References to deprecated APIs
History
|
|
Hey, sorry @jeramysoucy, I told you the wrong ticket earlier - this will be the issue to watch https://github.com/elastic/security-team/issues/12251?issue=elastic%7Csecurity-team%7C12887 |
…tic#225551) ## Summary This PR adds in API key management and runs plain index sync on task execution. Thanks to @jaredburgettelastic for the below changes 🚀 : ### Key Changes Tasks now call plainIndexSync to sync index users at specified intervals — this is the main functionality change. The following updates support it: - Added support for scoped API key usage via getClientfromApiKey in the getApiKeyManager - Using createInternalRepository for API key generation, to allow for internal kibana user to create saved object client. - API keys now store a snapshot of the user’s privileges by passing {} to role_descriptors. - Updated the find method in MonitoringEntitySourceDescriptorClient to use a namespace-scoped saved objects client. ##⚠️ Important Note You must fully restart Elasticsearch and Kibana after pulling these changes to regenerate the API key with the updated privileges. While taking a privilege snapshot is known to be problematic (e.g., privileges can get out of sync if updated later), it’s a known issue and consistent with the current behavior in the Entity Store. @tiansivive raised 🚀 # How to Test: Steps Taken from [elastic#221610](elastic#221610) - Pull branch into local machine - Security experimental flag enable: 'privilegeMonitoringEnabled' - Start up ElasticSearch and Kibana **1. Optional - create the default index, this should just skip if you don't make it.** ``` POST entity_analytics.privileged_monitoring/_doc { "user": { "name": "default name" } } ``` **2. Create test index/ indicies** ``` PUT /tatooine- { "mappings": { "properties": { "user": { "properties": { "name": { "type": "keyword", "fields": { "text": { "type": "text" } } } } } } } } ``` ``` POST tatooine-/_bulk { "index": {} } { "user": { "name": "Luke Skywalker" } } { "index": {} } { "user": { "name": "Leia Organa" } } { "index": {} } { "user": { "name": "Han Solo" } } { "index": {} } { "user": { "name": "Chewbacca" } } { "index": {} } { "user": { "name": "Obi-Wan Kenobi" } } { "index": {} } { "user": { "name": "Yoda" } } { "index": {} } { "user": { "name": "R2-D2" } } { "index": {} } { "user": { "name": "C-3PO" } } { "index": {} } { "user": { "name": "Darth Vader" } } ``` **3. Register Monitoring Entity Source Saved Objects** ``` POST kbn:/api/entity_analytics/monitoring/entity_source { "type": "index", "name": "StarWars", "managed": true, "indexPattern": "tatooine-", "enabled": true, "matchers": [ { "fields": ["user.role"], "values": ["admin"] } ], "filter": {} } ``` **- OPTIONAL: You can check what is in the monitoring entity_source SO:** ``` GET kbn:/api/entity_analytics/monitoring/entity_source/list ``` **4. Initialise monitoring engine:** ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` **5. Verify Users in Monitoring Index** - Check the list of synced user, should include: - - The created users - - The default user (if you created it) ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` **e.g. output:** ``` [ { "id": "FkMJoZcB7muj1aiwb_eQ", "user": { "name": "C-3PO", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, { "id": "F0MJoZcB7muj1aiwb_eQ", "user": { "name": "Chewbacca", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, // ... more here ``` ## Testing: Removing Stale Users The engine should soft delete users from the internal index if they no longer appear in the synced sources - e.g. label as monitoring.privileged_users: "not_monitored" **Example:** - Delete users in index: ``` POST tatooine-/_delete_by_query { "query": { "terms": { "user.name": ["Chewbacca", "Han Solo"] } } } ``` - re-run engine init ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` -Fetch the updated user list: ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` You should now only see both Chewbacca and Han Solo are no longer privileged: ``` // .. { "id": "GUMJoZcB7muj1aiwb_eQ", "user": { "name": "Han Solo" "is_privileged": false }, "labels": { "sources": [], "source_indices": [], } } ] ``` ## Recurring Sync Current interval is 10m, change this interval to 30s / shorter interval for testing - ` x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts` under 'INTERVAL'. Should be able to add some more indicies/ delete some users from current indicies and see results from the same users list above, on index sync as well as this log "[Privilege Monitoring] Running privilege monitoring task" running every x chosen INTERVAL occurrence. --------- Co-authored-by: jaredburgettelastic <jared.burgett@elastic.co> Co-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>
|
Starting backport for target branches: 9.1 https://github.com/elastic/kibana/actions/runs/16119924237 |
…tic#225551) ## Summary This PR adds in API key management and runs plain index sync on task execution. Thanks to @jaredburgettelastic for the below changes 🚀 : ### Key Changes Tasks now call plainIndexSync to sync index users at specified intervals — this is the main functionality change. The following updates support it: - Added support for scoped API key usage via getClientfromApiKey in the getApiKeyManager - Using createInternalRepository for API key generation, to allow for internal kibana user to create saved object client. - API keys now store a snapshot of the user’s privileges by passing {} to role_descriptors. - Updated the find method in MonitoringEntitySourceDescriptorClient to use a namespace-scoped saved objects client. ##⚠️ Important Note You must fully restart Elasticsearch and Kibana after pulling these changes to regenerate the API key with the updated privileges. While taking a privilege snapshot is known to be problematic (e.g., privileges can get out of sync if updated later), it’s a known issue and consistent with the current behavior in the Entity Store. @tiansivive raised 🚀 # How to Test: Steps Taken from [elastic#221610](elastic#221610) - Pull branch into local machine - Security experimental flag enable: 'privilegeMonitoringEnabled' - Start up ElasticSearch and Kibana **1. Optional - create the default index, this should just skip if you don't make it.** ``` POST entity_analytics.privileged_monitoring/_doc { "user": { "name": "default name" } } ``` **2. Create test index/ indicies** ``` PUT /tatooine- { "mappings": { "properties": { "user": { "properties": { "name": { "type": "keyword", "fields": { "text": { "type": "text" } } } } } } } } ``` ``` POST tatooine-/_bulk { "index": {} } { "user": { "name": "Luke Skywalker" } } { "index": {} } { "user": { "name": "Leia Organa" } } { "index": {} } { "user": { "name": "Han Solo" } } { "index": {} } { "user": { "name": "Chewbacca" } } { "index": {} } { "user": { "name": "Obi-Wan Kenobi" } } { "index": {} } { "user": { "name": "Yoda" } } { "index": {} } { "user": { "name": "R2-D2" } } { "index": {} } { "user": { "name": "C-3PO" } } { "index": {} } { "user": { "name": "Darth Vader" } } ``` **3. Register Monitoring Entity Source Saved Objects** ``` POST kbn:/api/entity_analytics/monitoring/entity_source { "type": "index", "name": "StarWars", "managed": true, "indexPattern": "tatooine-", "enabled": true, "matchers": [ { "fields": ["user.role"], "values": ["admin"] } ], "filter": {} } ``` **- OPTIONAL: You can check what is in the monitoring entity_source SO:** ``` GET kbn:/api/entity_analytics/monitoring/entity_source/list ``` **4. Initialise monitoring engine:** ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` **5. Verify Users in Monitoring Index** - Check the list of synced user, should include: - - The created users - - The default user (if you created it) ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` **e.g. output:** ``` [ { "id": "FkMJoZcB7muj1aiwb_eQ", "user": { "name": "C-3PO", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, { "id": "F0MJoZcB7muj1aiwb_eQ", "user": { "name": "Chewbacca", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, // ... more here ``` ## Testing: Removing Stale Users The engine should soft delete users from the internal index if they no longer appear in the synced sources - e.g. label as monitoring.privileged_users: "not_monitored" **Example:** - Delete users in index: ``` POST tatooine-/_delete_by_query { "query": { "terms": { "user.name": ["Chewbacca", "Han Solo"] } } } ``` - re-run engine init ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` -Fetch the updated user list: ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` You should now only see both Chewbacca and Han Solo are no longer privileged: ``` // .. { "id": "GUMJoZcB7muj1aiwb_eQ", "user": { "name": "Han Solo" "is_privileged": false }, "labels": { "sources": [], "source_indices": [], } } ] ``` ## Recurring Sync Current interval is 10m, change this interval to 30s / shorter interval for testing - ` x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts` under 'INTERVAL'. Should be able to add some more indicies/ delete some users from current indicies and see results from the same users list above, on index sync as well as this log "[Privilege Monitoring] Running privilege monitoring task" running every x chosen INTERVAL occurrence. --------- Co-authored-by: jaredburgettelastic <jared.burgett@elastic.co> Co-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co> (cherry picked from commit 441d2a5)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…#225551) (#226834) # Backport This will backport the following commits from `main` to `9.1`: - [Add API Key Management and Enable Index Sync via Scheduled Task (#225551)](#225551) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Charlotte Alexandra Wilson","email":"CAWilson94@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-07-04T14:10:24Z","message":"Add API Key Management and Enable Index Sync via Scheduled Task (#225551)\n\n## Summary \nThis PR adds in API key management and runs plain index sync on task\nexecution. Thanks to @jaredburgettelastic for the below changes 🚀 :\n### Key Changes \nTasks now call plainIndexSync to sync index users at specified intervals\n— this is the main functionality change. The following updates support\nit:\n- Added support for scoped API key usage via getClientfromApiKey in the\ngetApiKeyManager\n- Using createInternalRepository for API key generation, to allow for\ninternal kibana user to create saved object client.\n- API keys now store a snapshot of the user’s privileges by passing {}\nto role_descriptors.\n- Updated the find method in MonitoringEntitySourceDescriptorClient to\nuse a namespace-scoped saved objects client.\n\n##⚠️ Important Note \nYou must fully restart Elasticsearch and Kibana after pulling these\nchanges to regenerate the API key with the updated privileges.\n\nWhile taking a privilege snapshot is known to be problematic (e.g.,\nprivileges can get out of sync if updated later), it’s a known issue and\nconsistent with the current behavior in the Entity Store. @tiansivive\nraised 🚀\n\n# How to Test:\nSteps Taken from\n[#221610](https://github.com/elastic/kibana/pull/221610)\n- Pull branch into local machine\n- Security experimental flag enable: 'privilegeMonitoringEnabled'\n- Start up ElasticSearch and Kibana\n\n**1. Optional - create the default index, this should just skip if you\ndon't make it.**\n\n```\nPOST entity_analytics.privileged_monitoring/_doc\n{\n \"user\": {\n \"name\": \"default name\"\n }\n}\n```\n\n**2. Create test index/ indicies**\n\n```\nPUT /tatooine-\n{\n \"mappings\": {\n \"properties\": {\n \"user\": {\n \"properties\": {\n \"name\": {\n \"type\": \"keyword\",\n \"fields\": {\n \"text\": {\n \"type\": \"text\"\n }\n }\n }\n }\n }\n }\n }\n}\n\n```\n```\nPOST tatooine-/_bulk\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Luke Skywalker\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Leia Organa\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Han Solo\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Chewbacca\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Obi-Wan Kenobi\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Yoda\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"R2-D2\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"C-3PO\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Darth Vader\" } }\n\n``` \n**3. Register Monitoring Entity Source Saved Objects**\n```\nPOST kbn:/api/entity_analytics/monitoring/entity_source\n{\n \"type\": \"index\",\n \"name\": \"StarWars\",\n \"managed\": true,\n \"indexPattern\": \"tatooine-\",\n \"enabled\": true,\n \"matchers\": [\n {\n \"fields\": [\"user.role\"],\n \"values\": [\"admin\"]\n }\n ],\n \"filter\": {}\n}\n\n``` \n**- OPTIONAL: You can check what is in the monitoring entity_source\nSO:**\n\n``` \nGET kbn:/api/entity_analytics/monitoring/entity_source/list\n``` \n**4. Initialise monitoring engine:** \n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init {}\n``` \n\n**5. Verify Users in Monitoring Index**\n- Check the list of synced user, should include: \n- - The created users\n- - The default user (if you created it)\n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n``` \n\n**e.g. output:**\n\n```\n[\n {\n \"id\": \"FkMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"C-3PO\",\n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ],\n }\n },\n {\n \"id\": \"F0MJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Chewbacca\", \n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ], \n }\n },\n// ... more here \n\n```\n\n## Testing: Removing Stale Users\nThe engine should soft delete users from the internal index if they no\nlonger appear in the synced sources - e.g. label as\nmonitoring.privileged_users: \"not_monitored\"\n**Example:**\n\n- Delete users in index: \n```\nPOST tatooine-/_delete_by_query\n{\n \"query\": {\n \"terms\": {\n \"user.name\": [\"Chewbacca\", \"Han Solo\"]\n }\n }\n}\n\n```\n- re-run engine init\n\n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init\n{}\n```\n-Fetch the updated user list: \n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n```\nYou should now only see both Chewbacca and Han Solo are no longer\nprivileged:\n```\n// ..\n{\n \"id\": \"GUMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Han Solo\"\n \"is_privileged\": false \n },\n \"labels\": {\n \"sources\": [],\n \"source_indices\": [],\n }\n }\n]\n```\n\n## Recurring Sync \nCurrent interval is 10m, change this interval to 30s / shorter interval\nfor testing -\n`\nx-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts`\nunder 'INTERVAL'.\n\nShould be able to add some more indicies/ delete some users from current\nindicies and see results from the same users list above, on index sync\nas well as this log \"[Privilege Monitoring] Running privilege monitoring\ntask\" running every x chosen INTERVAL occurrence.\n\n---------\n\nCo-authored-by: jaredburgettelastic <jared.burgett@elastic.co>\nCo-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co>\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>","sha":"441d2a51a4c249706794e2bffa5ed8f64a14b6b9","branchLabelMapping":{"^v9.2.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team: SecuritySolution","Theme: entity_analytics","Team:Entity Analytics","backport:version","v9.1.0","v9.2.0"],"title":"Add API Key Management and Enable Index Sync via Scheduled Task","number":225551,"url":"https://github.com/elastic/kibana/pull/225551","mergeCommit":{"message":"Add API Key Management and Enable Index Sync via Scheduled Task (#225551)\n\n## Summary \nThis PR adds in API key management and runs plain index sync on task\nexecution. Thanks to @jaredburgettelastic for the below changes 🚀 :\n### Key Changes \nTasks now call plainIndexSync to sync index users at specified intervals\n— this is the main functionality change. The following updates support\nit:\n- Added support for scoped API key usage via getClientfromApiKey in the\ngetApiKeyManager\n- Using createInternalRepository for API key generation, to allow for\ninternal kibana user to create saved object client.\n- API keys now store a snapshot of the user’s privileges by passing {}\nto role_descriptors.\n- Updated the find method in MonitoringEntitySourceDescriptorClient to\nuse a namespace-scoped saved objects client.\n\n##⚠️ Important Note \nYou must fully restart Elasticsearch and Kibana after pulling these\nchanges to regenerate the API key with the updated privileges.\n\nWhile taking a privilege snapshot is known to be problematic (e.g.,\nprivileges can get out of sync if updated later), it’s a known issue and\nconsistent with the current behavior in the Entity Store. @tiansivive\nraised 🚀\n\n# How to Test:\nSteps Taken from\n[#221610](https://github.com/elastic/kibana/pull/221610)\n- Pull branch into local machine\n- Security experimental flag enable: 'privilegeMonitoringEnabled'\n- Start up ElasticSearch and Kibana\n\n**1. Optional - create the default index, this should just skip if you\ndon't make it.**\n\n```\nPOST entity_analytics.privileged_monitoring/_doc\n{\n \"user\": {\n \"name\": \"default name\"\n }\n}\n```\n\n**2. Create test index/ indicies**\n\n```\nPUT /tatooine-\n{\n \"mappings\": {\n \"properties\": {\n \"user\": {\n \"properties\": {\n \"name\": {\n \"type\": \"keyword\",\n \"fields\": {\n \"text\": {\n \"type\": \"text\"\n }\n }\n }\n }\n }\n }\n }\n}\n\n```\n```\nPOST tatooine-/_bulk\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Luke Skywalker\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Leia Organa\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Han Solo\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Chewbacca\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Obi-Wan Kenobi\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Yoda\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"R2-D2\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"C-3PO\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Darth Vader\" } }\n\n``` \n**3. Register Monitoring Entity Source Saved Objects**\n```\nPOST kbn:/api/entity_analytics/monitoring/entity_source\n{\n \"type\": \"index\",\n \"name\": \"StarWars\",\n \"managed\": true,\n \"indexPattern\": \"tatooine-\",\n \"enabled\": true,\n \"matchers\": [\n {\n \"fields\": [\"user.role\"],\n \"values\": [\"admin\"]\n }\n ],\n \"filter\": {}\n}\n\n``` \n**- OPTIONAL: You can check what is in the monitoring entity_source\nSO:**\n\n``` \nGET kbn:/api/entity_analytics/monitoring/entity_source/list\n``` \n**4. Initialise monitoring engine:** \n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init {}\n``` \n\n**5. Verify Users in Monitoring Index**\n- Check the list of synced user, should include: \n- - The created users\n- - The default user (if you created it)\n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n``` \n\n**e.g. output:**\n\n```\n[\n {\n \"id\": \"FkMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"C-3PO\",\n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ],\n }\n },\n {\n \"id\": \"F0MJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Chewbacca\", \n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ], \n }\n },\n// ... more here \n\n```\n\n## Testing: Removing Stale Users\nThe engine should soft delete users from the internal index if they no\nlonger appear in the synced sources - e.g. label as\nmonitoring.privileged_users: \"not_monitored\"\n**Example:**\n\n- Delete users in index: \n```\nPOST tatooine-/_delete_by_query\n{\n \"query\": {\n \"terms\": {\n \"user.name\": [\"Chewbacca\", \"Han Solo\"]\n }\n }\n}\n\n```\n- re-run engine init\n\n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init\n{}\n```\n-Fetch the updated user list: \n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n```\nYou should now only see both Chewbacca and Han Solo are no longer\nprivileged:\n```\n// ..\n{\n \"id\": \"GUMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Han Solo\"\n \"is_privileged\": false \n },\n \"labels\": {\n \"sources\": [],\n \"source_indices\": [],\n }\n }\n]\n```\n\n## Recurring Sync \nCurrent interval is 10m, change this interval to 30s / shorter interval\nfor testing -\n`\nx-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts`\nunder 'INTERVAL'.\n\nShould be able to add some more indicies/ delete some users from current\nindicies and see results from the same users list above, on index sync\nas well as this log \"[Privilege Monitoring] Running privilege monitoring\ntask\" running every x chosen INTERVAL occurrence.\n\n---------\n\nCo-authored-by: jaredburgettelastic <jared.burgett@elastic.co>\nCo-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co>\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>","sha":"441d2a51a4c249706794e2bffa5ed8f64a14b6b9"}},"sourceBranch":"main","suggestedTargetBranches":["9.1"],"targetPullRequestStates":[{"branch":"9.1","label":"v9.1.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.2.0","branchLabelMappingKey":"^v9.2.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/225551","number":225551,"mergeCommit":{"message":"Add API Key Management and Enable Index Sync via Scheduled Task (#225551)\n\n## Summary \nThis PR adds in API key management and runs plain index sync on task\nexecution. Thanks to @jaredburgettelastic for the below changes 🚀 :\n### Key Changes \nTasks now call plainIndexSync to sync index users at specified intervals\n— this is the main functionality change. The following updates support\nit:\n- Added support for scoped API key usage via getClientfromApiKey in the\ngetApiKeyManager\n- Using createInternalRepository for API key generation, to allow for\ninternal kibana user to create saved object client.\n- API keys now store a snapshot of the user’s privileges by passing {}\nto role_descriptors.\n- Updated the find method in MonitoringEntitySourceDescriptorClient to\nuse a namespace-scoped saved objects client.\n\n##⚠️ Important Note \nYou must fully restart Elasticsearch and Kibana after pulling these\nchanges to regenerate the API key with the updated privileges.\n\nWhile taking a privilege snapshot is known to be problematic (e.g.,\nprivileges can get out of sync if updated later), it’s a known issue and\nconsistent with the current behavior in the Entity Store. @tiansivive\nraised 🚀\n\n# How to Test:\nSteps Taken from\n[#221610](https://github.com/elastic/kibana/pull/221610)\n- Pull branch into local machine\n- Security experimental flag enable: 'privilegeMonitoringEnabled'\n- Start up ElasticSearch and Kibana\n\n**1. Optional - create the default index, this should just skip if you\ndon't make it.**\n\n```\nPOST entity_analytics.privileged_monitoring/_doc\n{\n \"user\": {\n \"name\": \"default name\"\n }\n}\n```\n\n**2. Create test index/ indicies**\n\n```\nPUT /tatooine-\n{\n \"mappings\": {\n \"properties\": {\n \"user\": {\n \"properties\": {\n \"name\": {\n \"type\": \"keyword\",\n \"fields\": {\n \"text\": {\n \"type\": \"text\"\n }\n }\n }\n }\n }\n }\n }\n}\n\n```\n```\nPOST tatooine-/_bulk\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Luke Skywalker\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Leia Organa\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Han Solo\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Chewbacca\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Obi-Wan Kenobi\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Yoda\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"R2-D2\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"C-3PO\" } }\n{ \"index\": {} }\n{ \"user\": { \"name\": \"Darth Vader\" } }\n\n``` \n**3. Register Monitoring Entity Source Saved Objects**\n```\nPOST kbn:/api/entity_analytics/monitoring/entity_source\n{\n \"type\": \"index\",\n \"name\": \"StarWars\",\n \"managed\": true,\n \"indexPattern\": \"tatooine-\",\n \"enabled\": true,\n \"matchers\": [\n {\n \"fields\": [\"user.role\"],\n \"values\": [\"admin\"]\n }\n ],\n \"filter\": {}\n}\n\n``` \n**- OPTIONAL: You can check what is in the monitoring entity_source\nSO:**\n\n``` \nGET kbn:/api/entity_analytics/monitoring/entity_source/list\n``` \n**4. Initialise monitoring engine:** \n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init {}\n``` \n\n**5. Verify Users in Monitoring Index**\n- Check the list of synced user, should include: \n- - The created users\n- - The default user (if you created it)\n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n``` \n\n**e.g. output:**\n\n```\n[\n {\n \"id\": \"FkMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"C-3PO\",\n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ],\n }\n },\n {\n \"id\": \"F0MJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Chewbacca\", \n \"is_privileged\": true\n },\n \"labels\": {\n \"sources\": [\n \"index\"\n ],\n \"source_indices\": [\n \"tatooine-\"\n ], \n }\n },\n// ... more here \n\n```\n\n## Testing: Removing Stale Users\nThe engine should soft delete users from the internal index if they no\nlonger appear in the synced sources - e.g. label as\nmonitoring.privileged_users: \"not_monitored\"\n**Example:**\n\n- Delete users in index: \n```\nPOST tatooine-/_delete_by_query\n{\n \"query\": {\n \"terms\": {\n \"user.name\": [\"Chewbacca\", \"Han Solo\"]\n }\n }\n}\n\n```\n- re-run engine init\n\n```\nPOST kbn:/api/entity_analytics/monitoring/engine/init\n{}\n```\n-Fetch the updated user list: \n\n```\nGET kbn:/api/entity_analytics/monitoring/users/list\n```\nYou should now only see both Chewbacca and Han Solo are no longer\nprivileged:\n```\n// ..\n{\n \"id\": \"GUMJoZcB7muj1aiwb_eQ\",\n \"user\": {\n \"name\": \"Han Solo\"\n \"is_privileged\": false \n },\n \"labels\": {\n \"sources\": [],\n \"source_indices\": [],\n }\n }\n]\n```\n\n## Recurring Sync \nCurrent interval is 10m, change this interval to 30s / shorter interval\nfor testing -\n`\nx-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts`\nunder 'INTERVAL'.\n\nShould be able to add some more indicies/ delete some users from current\nindicies and see results from the same users list above, on index sync\nas well as this log \"[Privilege Monitoring] Running privilege monitoring\ntask\" running every x chosen INTERVAL occurrence.\n\n---------\n\nCo-authored-by: jaredburgettelastic <jared.burgett@elastic.co>\nCo-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co>\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>","sha":"441d2a51a4c249706794e2bffa5ed8f64a14b6b9"}}]}] BACKPORT--> Co-authored-by: Charlotte Alexandra Wilson <CAWilson94@users.noreply.github.com> Co-authored-by: jaredburgettelastic <jared.burgett@elastic.co> Co-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co> Co-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>
…tic#225551) ## Summary This PR adds in API key management and runs plain index sync on task execution. Thanks to @jaredburgettelastic for the below changes 🚀 : ### Key Changes Tasks now call plainIndexSync to sync index users at specified intervals — this is the main functionality change. The following updates support it: - Added support for scoped API key usage via getClientfromApiKey in the getApiKeyManager - Using createInternalRepository for API key generation, to allow for internal kibana user to create saved object client. - API keys now store a snapshot of the user’s privileges by passing {} to role_descriptors. - Updated the find method in MonitoringEntitySourceDescriptorClient to use a namespace-scoped saved objects client. ##⚠️ Important Note You must fully restart Elasticsearch and Kibana after pulling these changes to regenerate the API key with the updated privileges. While taking a privilege snapshot is known to be problematic (e.g., privileges can get out of sync if updated later), it’s a known issue and consistent with the current behavior in the Entity Store. @tiansivive raised 🚀 # How to Test: Steps Taken from [elastic#221610](elastic#221610) - Pull branch into local machine - Security experimental flag enable: 'privilegeMonitoringEnabled' - Start up ElasticSearch and Kibana **1. Optional - create the default index, this should just skip if you don't make it.** ``` POST entity_analytics.privileged_monitoring/_doc { "user": { "name": "default name" } } ``` **2. Create test index/ indicies** ``` PUT /tatooine- { "mappings": { "properties": { "user": { "properties": { "name": { "type": "keyword", "fields": { "text": { "type": "text" } } } } } } } } ``` ``` POST tatooine-/_bulk { "index": {} } { "user": { "name": "Luke Skywalker" } } { "index": {} } { "user": { "name": "Leia Organa" } } { "index": {} } { "user": { "name": "Han Solo" } } { "index": {} } { "user": { "name": "Chewbacca" } } { "index": {} } { "user": { "name": "Obi-Wan Kenobi" } } { "index": {} } { "user": { "name": "Yoda" } } { "index": {} } { "user": { "name": "R2-D2" } } { "index": {} } { "user": { "name": "C-3PO" } } { "index": {} } { "user": { "name": "Darth Vader" } } ``` **3. Register Monitoring Entity Source Saved Objects** ``` POST kbn:/api/entity_analytics/monitoring/entity_source { "type": "index", "name": "StarWars", "managed": true, "indexPattern": "tatooine-", "enabled": true, "matchers": [ { "fields": ["user.role"], "values": ["admin"] } ], "filter": {} } ``` **- OPTIONAL: You can check what is in the monitoring entity_source SO:** ``` GET kbn:/api/entity_analytics/monitoring/entity_source/list ``` **4. Initialise monitoring engine:** ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` **5. Verify Users in Monitoring Index** - Check the list of synced user, should include: - - The created users - - The default user (if you created it) ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` **e.g. output:** ``` [ { "id": "FkMJoZcB7muj1aiwb_eQ", "user": { "name": "C-3PO", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, { "id": "F0MJoZcB7muj1aiwb_eQ", "user": { "name": "Chewbacca", "is_privileged": true }, "labels": { "sources": [ "index" ], "source_indices": [ "tatooine-" ], } }, // ... more here ``` ## Testing: Removing Stale Users The engine should soft delete users from the internal index if they no longer appear in the synced sources - e.g. label as monitoring.privileged_users: "not_monitored" **Example:** - Delete users in index: ``` POST tatooine-/_delete_by_query { "query": { "terms": { "user.name": ["Chewbacca", "Han Solo"] } } } ``` - re-run engine init ``` POST kbn:/api/entity_analytics/monitoring/engine/init {} ``` -Fetch the updated user list: ``` GET kbn:/api/entity_analytics/monitoring/users/list ``` You should now only see both Chewbacca and Han Solo are no longer privileged: ``` // .. { "id": "GUMJoZcB7muj1aiwb_eQ", "user": { "name": "Han Solo" "is_privileged": false }, "labels": { "sources": [], "source_indices": [], } } ] ``` ## Recurring Sync Current interval is 10m, change this interval to 30s / shorter interval for testing - ` x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.ts` under 'INTERVAL'. Should be able to add some more indicies/ delete some users from current indicies and see results from the same users list above, on index sync as well as this log "[Privilege Monitoring] Running privilege monitoring task" running every x chosen INTERVAL occurrence. --------- Co-authored-by: jaredburgettelastic <jared.burgett@elastic.co> Co-authored-by: Tiago Vila Verde <tiago.vilaverde@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jeramy Soucy <jeramy.soucy@elastic.co>
Summary
This PR adds in API key management and runs plain index sync on task execution. Thanks to @jaredburgettelastic for the below changes 🚀 :
Key Changes
Tasks now call plainIndexSync to sync index users at specified intervals — this is the main functionality change. The following updates support it:
Further work, Testing and Review
Testing updates upcoming in #225783
Note: Any other further updates @jeramysoucy should be notified for review (same for testing updates above)
You must fully restart Elasticsearch and Kibana after pulling these changes to regenerate the API key with the updated privileges.
While taking a privilege snapshot is known to be problematic (e.g., privileges can get out of sync if updated later), it’s a known issue and consistent with the current behavior in the Entity Store. @tiansivive raised 🚀
How to Test:
Steps Taken from #221610
1. Optional - create the default index, this should just skip if you don't make it.
2. Create test index/ indicies
3. Register Monitoring Entity Source Saved Objects
- OPTIONAL: You can check what is in the monitoring entity_source SO:
4. Initialise monitoring engine:
5. Verify Users in Monitoring Index
e.g. output:
Testing: Removing Stale Users
The engine should soft delete users from the internal index if they no longer appear in the synced sources - e.g. label as monitoring.privileged_users: "not_monitored"
Example:
-Fetch the updated user list:
You should now only see both Chewbacca and Han Solo are no longer privileged:
Recurring Sync
Current interval is 10m, change this interval to 30s / shorter interval for testing -
x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/constants.tsunder 'INTERVAL'.Should be able to add some more indicies/ delete some users from current indicies and see results from the same users list above, on index sync as well as this log "[Privilege Monitoring] Running privilege monitoring task" running every x chosen INTERVAL occurrence.