From 958deed9383c62084edb0396649c802d9af552bf Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Fri, 17 Oct 2025 16:03:54 -0500 Subject: [PATCH 01/85] Introduces Rules feature and subsequent app changes This does not include changes to existing roles, nor the role migration machinery. --- config/serverless.security.search_ai_lake.yml | 88 +- config/serverless.security.yml | 169 +- .../serverless_resources/security_roles.json | 450 +- .../translations/translations/de-DE.json | 1 - .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - .../shared/fleet/common/constants/authz.ts | 2 +- .../apis/features/features/features.ts | 3 +- .../apis/security/privileges.ts | 33 + .../apis/security/privileges.ts | 35 + .../tests/features/deprecated_features.ts | 3 + .../common/suites/create.agnostic.ts | 3 +- .../common/suites/get.agnostic.ts | 3 +- .../common/suites/get_all.agnostic.ts | 3 +- .../spaces_only/telemetry/telemetry.ts | 2 + .../components/data_table/index.tsx | 4 +- .../data-table/store/data_table/model.ts | 2 +- .../packages/features/product_features.ts | 2 + .../packages/features/src/constants.ts | 34 + .../features/src/product_features_keys.ts | 27 +- .../packages/features/src/rules/index.ts | 18 + .../features/src/rules/kibana_features.ts | 136 + .../src/rules/product_feature_config.ts | 36 + .../packages/features/src/rules/types.ts | 11 + .../packages/features/src/security/index.ts | 14 + .../src/security/product_feature_config.ts | 23 +- .../security/v1_features/kibana_features.ts | 66 +- .../v1_features/kibana_sub_features.ts | 28 +- .../security/v2_features/kibana_features.ts | 75 +- .../v2_features/kibana_sub_features.ts | 32 +- .../security/v3_features/kibana_features.ts | 74 +- .../v3_features/kibana_sub_features.ts | 34 +- .../security/v4_features/kibana_features.ts | 78 +- .../v4_features/kibana_sub_features.ts | 27 + .../security/v5_features/kibana_features.ts | 78 + .../v5_features/kibana_sub_features.ts | 89 + .../security/packages/features/src/types.ts | 3 + .../elastic_assistant/common/constants.ts | 2 +- .../scripts/create_and_login_users.js | 1 + .../routes/create_endpoint_list_item_route.ts | 3 +- .../routes/create_endpoint_list_route.ts | 3 +- .../create_exception_list_item_route.ts | 3 +- .../routes/create_exception_list_route.ts | 3 +- .../routes/delete_endpoint_list_item_route.ts | 3 +- .../delete_exception_list_item_route.ts | 3 +- .../routes/delete_exception_list_route.ts | 3 +- .../routes/duplicate_exception_list_route.ts | 3 +- .../routes/export_exception_list_route.ts | 3 +- .../routes/find_endpoint_list_item_route.ts | 3 +- .../routes/find_exception_list_item_route.ts | 3 +- .../routes/find_exception_list_route.ts | 3 +- .../server/routes/import_exceptions_route.ts | 3 +- .../internal/create_exceptions_list_route.ts | 3 +- .../internal/find_lists_by_size_route.ts | 3 +- .../server/routes/list/create_list_route.ts | 3 +- .../server/routes/list/delete_list_route.ts | 3 +- .../routes/list/import_list_item_route.ts | 3 +- .../server/routes/list/patch_list_route.ts | 3 +- .../server/routes/list/read_list_route.ts | 3 +- .../server/routes/list/update_list_route.ts | 3 +- .../list_index/create_list_index_route.ts | 3 +- .../list_index/delete_list_index_route.ts | 3 +- .../list_index/export_list_item_route.ts | 3 +- .../routes/list_index/find_list_route.ts | 3 +- .../list_index/read_list_index_route.ts | 3 +- .../list_item/create_list_item_route.ts | 3 +- .../list_item/delete_list_item_route.ts | 3 +- .../routes/list_item/find_list_item_route.ts | 3 +- .../routes/list_item/patch_list_item_route.ts | 3 +- .../routes/list_item/read_list_item_route.ts | 3 +- .../list_item/update_list_item_route.ts | 3 +- .../read_list_privileges_route.ts | 3 +- .../routes/read_endpoint_list_item_route.ts | 3 +- .../routes/read_exception_list_item_route.ts | 3 +- .../routes/read_exception_list_route.ts | 3 +- .../routes/summary_exception_list_route.ts | 3 +- .../routes/update_endpoint_list_item_route.ts | 3 +- .../update_exception_list_item_route.ts | 3 +- .../routes/update_exception_list_route.ts | 3 +- .../security/plugins/lists/tsconfig.json | 3 +- .../security_solution/common/constants.ts | 4 +- .../app/home/global_header/index.test.tsx | 4 + .../public/app/home/global_header/index.tsx | 4 +- .../public/asset_inventory/links.ts | 3 +- .../public/attack_discovery/links.test.ts | 4 +- .../public/attack_discovery/links.ts | 6 +- .../attack_discovery/pages/index.test.tsx | 3 +- .../pages/results/history/index.test.tsx | 37 +- .../public/cloud_security_posture/links.ts | 4 +- .../common/components/events_viewer/index.tsx | 2 +- .../header_actions/actions.test.tsx | 3 +- .../user_privileges_context.tsx | 34 +- .../hooks/use_missing_privileges.test.tsx | 130 +- .../common/hooks/use_missing_privileges.ts | 17 +- .../common/lib/kibana/kibana_react.mock.ts | 4 + .../common/utils/privileges/index.test.ts | 30 - .../public/common/utils/privileges/index.ts | 10 +- .../public/configurations/links.ts | 7 +- .../promotion_rules/promotion_rules_table.tsx | 8 +- .../public/dashboards/links.ts | 3 +- .../detection_engine/common/translations.ts | 6 +- .../pages/rule_creation/index.tsx | 16 +- .../pages/rule_editing/index.tsx | 16 +- .../pages/rule_details/index.tsx | 16 +- .../all_exception_items_table/index.tsx | 8 +- .../components/rule_backfills_info/index.tsx | 12 +- .../rule_gaps/components/rule_gaps/index.tsx | 10 +- .../rule_snooze_badge/rule_snooze_badge.tsx | 8 +- .../pre_packaged_rules/load_empty_prompt.tsx | 6 +- .../add_prebuilt_rules_header_buttons.tsx | 11 +- .../add_prebuilt_rules_table.test.tsx | 73 +- .../add_prebuilt_rules_table_context.tsx | 28 +- .../add_prebuilt_rules_utils.ts | 6 +- .../use_add_prebuilt_rules_table_columns.tsx | 10 +- .../feature_tour/rules_feature_tour.tsx | 6 +- .../rules_table/rules_table_toolbar.tsx | 6 +- .../components/rules_table/rules_tables.tsx | 14 +- .../upgrade_prebuilt_rules_table_buttons.tsx | 11 +- ...e_upgrade_prebuilt_rules_table_columns.tsx | 12 +- .../technique_panel_popover.test.tsx | 15 +- .../technique_panel_popover.tsx | 13 +- .../pages/rule_management/index.tsx | 22 +- .../components/alerts_table/index.tsx | 2 +- .../alert_context_menu.test.tsx | 2 +- .../use_add_bulk_to_timeline.tsx | 2 +- .../use_add_exception_actions.test.tsx | 25 +- .../use_add_exception_actions.tsx | 6 +- .../components/user_info/__mocks__/index.tsx | 2 - .../components/user_info/index.test.tsx | 2 - .../detections/components/user_info/index.tsx | 44 - .../alerts/use_alerts_privileges.test.tsx | 35 +- .../alerts/use_alerts_privileges.tsx | 20 +- .../lists/use_lists_privileges.tsx | 8 +- .../public/detections/links.ts | 14 +- .../detections/pages/alerts/alerts.test.tsx | 21 +- .../public/detections/pages/alerts/alerts.tsx | 8 +- .../hooks/use_list_detail_view/index.ts | 8 +- .../exceptions/pages/shared_lists/index.tsx | 10 +- .../pages/shared_lists/shared_lists.test.tsx | 26 +- .../explore/hosts/pages/details/index.tsx | 2 +- .../security_solution/public/explore/links.ts | 9 +- .../explore/network/pages/details/index.tsx | 2 +- .../explore/users/pages/details/index.tsx | 2 +- .../components/status_popover_button.test.tsx | 6 +- .../components/take_action_dropdown.test.tsx | 5 +- .../use_highlighted_fields_privilege.test.tsx | 18 +- .../use_highlighted_fields_privilege.tsx | 28 +- .../public/helpers_access.ts | 8 +- .../management/cypress/common/constants.ts | 3 +- .../public/management/links.ts | 3 +- .../security_solution/public/notes/links.ts | 10 +- .../integrations_external_detections/index.ts | 4 +- .../cards/knowledge_source/index.ts | 4 +- .../onboarding_header_configs.ts | 9 +- .../public/onboarding/config.ts | 11 +- .../public/onboarding/links.ts | 8 +- .../public/overview/links.ts | 7 +- .../pages/detection_response.test.tsx | 8 +- .../overview/pages/detection_response.tsx | 2 +- .../public/overview/pages/overview.tsx | 2 +- .../security_solution/public/reports/links.ts | 14 +- .../public/reports/pages/ai_value.test.tsx | 12 +- .../public/reports/pages/ai_value.tsx | 2 +- .../security_solution/public/rules/links.ts | 14 +- .../security_solution/public/rules/routes.tsx | 48 +- .../common/service/capabilities.ts | 11 +- .../public/siem_migrations/links.ts | 11 +- .../containers/local_storage/index.tsx | 2 +- .../public/timelines/links.ts | 12 +- .../public/use_readonly_header.ts | 8 +- .../api/get_all_integrations/route.ts | 3 +- .../api/get_installed_integrations/route.ts | 3 +- .../bootstrap_prebuilt_rules.ts | 3 +- .../bootstrap_prebuilt_rules_handler.ts | 4 +- .../get_prebuilt_rule_base_version_route.ts | 3 +- ...ebuilt_rules_and_timelines_status_route.ts | 3 +- .../get_prebuilt_rules_status_route.ts | 3 +- ...tall_prebuilt_rules_and_timelines_route.ts | 3 +- .../perform_rule_installation_route.ts | 3 +- .../perform_rule_upgrade_route.ts | 3 +- .../revert_prebuilt_rule_route.ts | 3 +- .../review_rule_installation_route.ts | 3 +- .../review_rule_upgrade_route.ts | 3 +- .../routes/index/create_index_route.ts | 3 +- .../routes/index/delete_index_route.ts | 3 +- .../routes/index/read_index_route.ts | 3 +- .../privileges/read_privileges_route.ts | 3 +- .../signals/open_close_signals_route.ts | 3 +- .../routes/signals/query_signals_route.ts | 3 +- .../signals/set_alert_assignees_route.ts | 4 +- .../routes/signals/set_alert_tags_route.ts | 3 +- .../users/suggest_user_profiles_route.ts | 3 +- .../api/create_rule_exceptions/route.ts | 3 +- .../api/find_exception_references/route.ts | 3 +- .../api/rules/bulk_actions/route.ts | 3 +- .../api/rules/coverage_overview/route.ts | 3 +- .../api/rules/create_rule/route.ts | 3 +- .../api/rules/delete_rule/route.ts | 3 +- .../api/rules/export_rules/route.ts | 3 +- .../api/rules/filters/route.ts | 3 +- .../api/rules/find_rules/route.ts | 3 +- .../api/rules/import_rules/route.ts | 3 +- .../api/rules/patch_rule/route.ts | 3 +- .../api/rules/read_rule/route.ts | 3 +- .../api/rules/update_rule/route.ts | 3 +- .../api/tags/read_tags/route.ts | 3 +- .../get_cluster_health_route.ts | 5 +- .../get_rule_health/get_rule_health_route.ts | 3 +- .../get_space_health_route.ts | 5 +- .../setup/setup_health_route.ts | 3 +- .../get_rule_execution_events_route.ts | 3 +- .../get_rule_execution_results_route.ts | 3 +- .../rule_preview/api/preview_rules/route.ts | 3 +- .../lib/product_features_service/mocks.ts | 10 + .../product_features_service.test.ts | 2 + .../product_features_service.ts | 18 +- .../security_saved_objects.ts | 48 +- .../security_solution/server/saved_objects.ts | 11 - .../security_solution_ess/common/constants.ts | 3 +- .../routes/helper/user_roles_utilites.ts | 6 +- .../document_level_security.ts | 3 + .../e2e/ai4dsoc/capabilities/access.cy.ts | 10 +- .../install_update_authorization.cy.ts | 7 +- .../cypress/tasks/privileges.ts | 12 +- .../platform_security/authorization.ts | 3717 +++++++++++++---- .../test/session_view/basic/tests/index.ts | 3 +- 227 files changed, 4842 insertions(+), 2120 deletions(-) create mode 100644 x-pack/solutions/security/packages/features/src/rules/index.ts create mode 100644 x-pack/solutions/security/packages/features/src/rules/kibana_features.ts create mode 100644 x-pack/solutions/security/packages/features/src/rules/product_feature_config.ts create mode 100644 x-pack/solutions/security/packages/features/src/rules/types.ts create mode 100644 x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts create mode 100644 x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts delete mode 100644 x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.test.ts diff --git a/config/serverless.security.search_ai_lake.yml b/config/serverless.security.search_ai_lake.yml index bab6e64a97554..7dd59c7f06a5f 100644 --- a/config/serverless.security.search_ai_lake.yml +++ b/config/serverless.security.search_ai_lake.yml @@ -28,68 +28,84 @@ xpack.features.overrides: siemV2.description: null siemV3.description: null siemV4.description: null + siemV5.description: null securitySolutionSiemMigrations.hidden: true ## Fine-tune the security solution essentials feature privileges. These feature privilege overrides are set individually for each project type. Also, refer to `serverless.yml` for the project-agnostic overrides. + siemV5: + privileges: + all.composedOf: + ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten + ## We do not need to compose 4 from maps and visualizations because these functionalities are disabled in this tier + - feature: 'discover_v2' + privileges: ['all'] + ## We need limited access to fleet (v1) in order to use integrations + - feature: 'fleet' + privileges: ['all'] + read.composedOf: + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'fleet' + privileges: ['read'] siemV4: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV4 from maps and visualizations because these functionalities are disabled in this tier - - feature: "discover_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] ## We need limited access to fleet (v1) in order to use integrations - - feature: "fleet" - privileges: [ "all" ] + - feature: 'fleet' + privileges: ['all'] read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "fleet" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'fleet' + privileges: ['read'] siemV3: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV3 from maps and visualizations because these functionalities are disabled in this tier - - feature: "discover_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] ## We need limited access to fleet (v1) in order to use integrations - - feature: "fleet" - privileges: [ "all" ] + - feature: 'fleet' + privileges: ['all'] read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "fleet" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'fleet' + privileges: ['read'] siemV2: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV2 from maps and visualizations because these functionalities are disabled in this tier - - feature: "discover_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] ## We need limited access to fleet (v1) in order to use integrations - - feature: "fleet" - privileges: [ "all" ] + - feature: 'fleet' + privileges: ['all'] read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "fleet" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'fleet' + privileges: ['read'] siem: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV2 from maps and visualizations because these functionalities are disabled in this tier - - feature: "discover_v2" - privileges: [ "all" ] - - feature: "savedQueryManagement" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'savedQueryManagement' + privileges: ['all'] read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "savedQueryManagement" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'savedQueryManagement' + privileges: ['read'] # Custom integrations/fleet settings xpack.fleet.agentless.isDefault: true @@ -105,8 +121,8 @@ xpack.actions.preconfigured: actionTypeId: .inference exposeConfig: true config: - provider: "elastic" - taskType: "chat_completion" - inferenceId: ".rainbow-sprinkles-elastic" + provider: 'elastic' + taskType: 'chat_completion' + inferenceId: '.rainbow-sprinkles-elastic' providerConfig: - model_id: "rainbow-sprinkles" + model_id: 'rainbow-sprinkles' diff --git a/config/serverless.security.yml b/config/serverless.security.yml index 435a328834998..c857baaec04ea 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -22,38 +22,63 @@ xpack.features.overrides: maps_v2.hidden: true ### agent builder feature is moved from Analytics category to the Security one the bottom agentBuilder: - category: "security" + category: 'security' order: 1101 ### Machine Learning feature is moved from Analytics category to the Security one as the last item. ml: - category: "security" + category: 'security' order: 1103 ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. + siemV5: + privileges: + ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and + ### Visualize features. + all.composedOf: + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'dashboard_v2' + privileges: ['all'] + - feature: 'visualize_v2' + privileges: ['all'] + - feature: 'maps_v2' + privileges: ['all'] + # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and + # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, + ### Dashboard, and Visualize apps. + read.composedOf: + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'dashboard_v2' + privileges: ['read'] + - feature: 'visualize_v2' + privileges: ['read'] + - feature: 'maps_v2' + privileges: ['read'] siemV4: privileges: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: "discover_v2" - privileges: [ "all" ] - - feature: "dashboard_v2" - privileges: [ "all" ] - - feature: "visualize_v2" - privileges: [ "all" ] - - feature: "maps_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'dashboard_v2' + privileges: ['all'] + - feature: 'visualize_v2' + privileges: ['all'] + - feature: 'maps_v2' + privileges: ['all'] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "dashboard_v2" - privileges: [ "read" ] - - feature: "visualize_v2" - privileges: [ "read" ] - - feature: "maps_v2" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'dashboard_v2' + privileges: ['read'] + - feature: 'visualize_v2' + privileges: ['read'] + - feature: 'maps_v2' + privileges: ['read'] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siemV3: @@ -61,26 +86,26 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: "discover_v2" - privileges: [ "all" ] - - feature: "dashboard_v2" - privileges: [ "all" ] - - feature: "visualize_v2" - privileges: [ "all" ] - - feature: "maps_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'dashboard_v2' + privileges: ['all'] + - feature: 'visualize_v2' + privileges: ['all'] + - feature: 'maps_v2' + privileges: ['all'] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "dashboard_v2" - privileges: [ "read" ] - - feature: "visualize_v2" - privileges: [ "read" ] - - feature: "maps_v2" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'dashboard_v2' + privileges: ['read'] + - feature: 'visualize_v2' + privileges: ['read'] + - feature: 'maps_v2' + privileges: ['read'] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siemV2: @@ -88,26 +113,26 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: "discover_v2" - privileges: [ "all" ] - - feature: "dashboard_v2" - privileges: [ "all" ] - - feature: "visualize_v2" - privileges: [ "all" ] - - feature: "maps_v2" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'dashboard_v2' + privileges: ['all'] + - feature: 'visualize_v2' + privileges: ['all'] + - feature: 'maps_v2' + privileges: ['all'] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "dashboard_v2" - privileges: [ "read" ] - - feature: "visualize_v2" - privileges: [ "read" ] - - feature: "maps_v2" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'dashboard_v2' + privileges: ['read'] + - feature: 'visualize_v2' + privileges: ['read'] + - feature: 'maps_v2' + privileges: ['read'] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siem: @@ -115,30 +140,30 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: "discover_v2" - privileges: [ "all" ] - - feature: "dashboard_v2" - privileges: [ "all" ] - - feature: "visualize_v2" - privileges: [ "all" ] - - feature: "maps_v2" - privileges: [ "all" ] - - feature: "savedQueryManagement" - privileges: [ "all" ] + - feature: 'discover_v2' + privileges: ['all'] + - feature: 'dashboard_v2' + privileges: ['all'] + - feature: 'visualize_v2' + privileges: ['all'] + - feature: 'maps_v2' + privileges: ['all'] + - feature: 'savedQueryManagement' + privileges: ['all'] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: "discover_v2" - privileges: [ "read" ] - - feature: "dashboard_v2" - privileges: [ "read" ] - - feature: "visualize_v2" - privileges: [ "read" ] - - feature: "maps_v2" - privileges: [ "read" ] - - feature: "savedQueryManagement" - privileges: [ "read" ] + - feature: 'discover_v2' + privileges: ['read'] + - feature: 'dashboard_v2' + privileges: ['read'] + - feature: 'visualize_v2' + privileges: ['read'] + - feature: 'maps_v2' + privileges: ['read'] + - feature: 'savedQueryManagement' + privileges: ['read'] ## Cloud settings xpack.cloud.serverless.project_type: security @@ -153,8 +178,8 @@ xpack.securitySolutionServerless.productTypes: ] xpack.securitySolution.offeringSettings: { - ILMEnabled: false, # Index Lifecycle Management (ILM) functionalities disabled, not supported by serverless Elasticsearch -} + ILMEnabled: false, # Index Lifecycle Management (ILM) functionalities disabled, not supported by serverless Elasticsearch + } newsfeed.enabled: true diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index 76a3b250530b6..015a132c147f1 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -5,15 +5,8 @@ "cluster": [], "indices": [ { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { "names": [ @@ -31,9 +24,7 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -41,38 +32,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV3": [ - "read", - "read_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "read" - ], - "securitySolutionTimeline": [ - "read" - ], - "securitySolutionNotes": [ - "read" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "read" - ] + "ml": ["read"], + "siemV3": ["read", "read_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["read"], + "builtInAlerts": ["read"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -83,15 +53,8 @@ "cluster": [], "indices": [ { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { "names": [ @@ -111,9 +74,7 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -121,38 +82,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV3": [ - "read", - "read_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "read" - ], - "securitySolutionTimeline": [ - "read" - ], - "securitySolutionNotes": [ - "read" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "read" - ] + "ml": ["read"], + "siemV3": ["read", "read_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["read"], + "builtInAlerts": ["read"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -175,31 +115,15 @@ "logstash-*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { - "names": [ - ".lists*", - ".items*" - ], - "privileges": [ - "read", - "write" - ] + "names": [".lists*", ".items*"], + "privileges": ["read", "write"] }, { "names": [ @@ -213,9 +137,7 @@ ".entities.v1.updates.security_*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -223,9 +145,7 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], + "ml": ["read"], "siemV3": [ "all", "read_alerts", @@ -241,49 +161,21 @@ "actions_log_management_all", "file_operations_all" ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ], - "osquery": [ - "all" - ], - "discover_v2": [ - "all" - ], - "dashboard_v2": [ - "all" - ], - "maps_v2": [ - "all" - ], - "visualize_v2": [ - "all" - ], - "savedQueryManagement": [ - "all" - ] + "securitySolutionCasesV2": ["all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"], + "osquery": ["all"], + "discover_v2": ["all"], + "dashboard_v2": ["all"], + "maps_v2": ["all"], + "visualize_v2": ["all"], + "savedQueryManagement": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -307,10 +199,7 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { "names": [ @@ -321,12 +210,7 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "read", - "write", - "maintenance", - "view_index_metadata" - ] + "privileges": ["read", "write", "maintenance", "view_index_metadata"] }, { "names": [ @@ -335,9 +219,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -345,39 +227,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV3": [ - "all", - "read_alerts", - "crud_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ] + "ml": ["read"], + "siemV3": ["all", "read_alerts", "crud_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -401,10 +261,7 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { "names": [ @@ -415,11 +272,7 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "read", - "write", - "manage" - ] + "privileges": ["read", "write", "manage"] }, { "names": [ @@ -428,9 +281,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -438,39 +289,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV3": [ - "all", - "read_alerts", - "crud_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "all" - ], - "builtInAlerts": [ - "all" - ] + "ml": ["read"], + "siemV3": ["all", "read_alerts", "crud_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["all"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -478,9 +307,7 @@ "detections_admin": { "name": "detections_admin", "elasticsearch": { - "cluster": [ - "manage" - ], + "cluster": ["manage"], "indices": [ { "names": [ @@ -502,11 +329,7 @@ "winlogbeat-*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "manage", - "write", - "read" - ] + "privileges": ["manage", "write", "read"] }, { "names": [ @@ -515,9 +338,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -525,42 +346,19 @@ "kibana": [ { "feature": { - "ml": [ - "all" - ], - "siemV3": [ - "all", - "read_alerts", - "crud_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ], - "dev_tools": [ - "all" - ] + "ml": ["all"], + "siemV3": ["all", "read_alerts", "crud_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "securitySolutionRulesV1": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"], + "dev_tools": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -568,18 +366,11 @@ "platform_engineer": { "name": "platform_engineer", "elasticsearch": { - "cluster": [ - "manage" - ], + "cluster": ["manage"], "indices": [ { - "names": [ - ".lists*", - ".items*" - ], - "privileges": [ - "all" - ] + "names": [".lists*", ".items*"], + "privileges": ["all"] }, { "names": [ @@ -596,9 +387,7 @@ ".fleet-actions*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "all" - ] + "privileges": ["all"] }, { "names": [ @@ -609,17 +398,11 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "all" - ] + "privileges": ["all"] }, { - "names": [ - ".entity_analytics.monitoring*" - ], - "privileges": [ - "read" - ] + "names": [".entity_analytics.monitoring*"], + "privileges": ["read"] } ], "run_as": [] @@ -627,39 +410,18 @@ "kibana": [ { "feature": { - "ml": [ - "all" - ], - "siemV3": [ - "all", - "read_alerts", - "crud_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "all" - ], - "builtInAlerts": [ - "all" - ] + "ml": ["all"], + "siemV3": ["all", "read_alerts", "crud_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "securitySolutionRulesV1": ["all"], + "actions": ["all"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index 5b86c863e2308..1f7e941bfacb9 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -35326,7 +35326,6 @@ "xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription": "Regel-Einstellungen bearbeiten", "xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription": "Regel exportieren", "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaActionsFeaturePrivileges": "Sie verfügen nicht über Kibana Actions-Berechtigungen", - "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaSecurityPrivileges": "Sie haben keine Berechtigungen für Kibana Security", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunDescription": "Manuelle Ausführung", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunTooltip": "Manuelles Ausführen nur für aktivierte Regeln verfügbar", "xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle": "Massenaktionen", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 172954d980ee5..496cdf46b988a 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -35522,7 +35522,6 @@ "xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription": "Modifier les paramètres de règles", "xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription": "Exporter la règle", "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaActionsFeaturePrivileges": "Vous ne disposez pas des privilèges d'actions Kibana", - "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaSecurityPrivileges": "Vous ne disposez pas des privilèges pour la sécurité de Kibana", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunDescription": "Exécution manuelle", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunTooltip": "Exécution manuelle disponible uniquement pour les règles activées", "xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle": "Actions groupées", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 3968def81f2c0..8f3b38bd8f204 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -35561,7 +35561,6 @@ "xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription": "ルール設定の編集", "xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription": "ルールのエクスポート", "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaActionsFeaturePrivileges": "Kibana アクション特権がありません", - "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaSecurityPrivileges": "Kibanaセキュリティ権限がありません", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunDescription": "手動実行", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunTooltip": "手動実行は有効なルールでのみ使用できます", "xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle": "一斉アクション", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 19a368bb25a55..f8993a30dcc44 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -35547,7 +35547,6 @@ "xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription": "编辑规则设置", "xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription": "导出规则", "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaActionsFeaturePrivileges": "您没有 Kibana 操作权限", - "xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaSecurityPrivileges": "您没有 Kibana 安全权限", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunDescription": "手动运行", "xpack.securitySolution.detectionEngine.rules.allRules.actions.manualRuleRunTooltip": "手动运行仅适用于已启用的规则", "xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle": "批处理操作", diff --git a/x-pack/platform/plugins/shared/fleet/common/constants/authz.ts b/x-pack/platform/plugins/shared/fleet/common/constants/authz.ts index 8dc675eb277a5..40a01a211fe5b 100644 --- a/x-pack/platform/plugins/shared/fleet/common/constants/authz.ts +++ b/x-pack/platform/plugins/shared/fleet/common/constants/authz.ts @@ -8,7 +8,7 @@ import { deepFreeze } from '@kbn/std'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; -export const SECURITY_SOLUTION_APP_ID = 'siemV4'; +export const SECURITY_SOLUTION_APP_ID = 'siemV5'; export interface PrivilegeMapObject { appId: string; diff --git a/x-pack/platform/test/api_integration/apis/features/features/features.ts b/x-pack/platform/test/api_integration/apis/features/features/features.ts index 21484fb3cdcf6..3cb3c9569c6dd 100644 --- a/x-pack/platform/test/api_integration/apis/features/features/features.ts +++ b/x-pack/platform/test/api_integration/apis/features/features/features.ts @@ -133,7 +133,7 @@ export default function ({ getService }: FtrProviderContext) { 'searchSynonyms', 'searchQueryRules', 'searchPlayground', - 'siemV4', + 'siemV5', 'slo', 'streams', 'securitySolutionAssistant', @@ -141,6 +141,7 @@ export default function ({ getService }: FtrProviderContext) { 'securitySolutionCasesV3', 'securitySolutionTimeline', 'securitySolutionNotes', + 'securitySolutionRulesV1', 'securitySolutionSiemMigrations', 'workflowsManagement', 'fleet', diff --git a/x-pack/platform/test/api_integration/apis/security/privileges.ts b/x-pack/platform/test/api_integration/apis/security/privileges.ts index 2ebcae323d2ae..522e4a5bf7a36 100644 --- a/x-pack/platform/test/api_integration/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration/apis/security/privileges.ts @@ -239,6 +239,38 @@ export default function ({ getService }: FtrProviderContext) { 'execute_operations_all', 'scan_operations_all', ], + siemV5: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'endpoint_list_all', + 'endpoint_list_read', + 'workflow_insights_all', + 'workflow_insights_read', + 'global_artifact_management_all', + 'trusted_applications_all', + 'trusted_applications_read', + 'trusted_devices_all', + 'trusted_devices_read', + 'host_isolation_exceptions_all', + 'host_isolation_exceptions_read', + 'blocklist_all', + 'blocklist_read', + 'event_filters_all', + 'event_filters_read', + 'endpoint_exceptions_all', + 'endpoint_exceptions_read', + 'policy_management_all', + 'policy_management_read', + 'actions_log_management_all', + 'actions_log_management_read', + 'host_isolation_all', + 'process_operations_all', + 'file_operations_all', + 'execute_operations_all', + 'scan_operations_all', + ], uptime: [ 'all', 'read', @@ -294,6 +326,7 @@ export default function ({ getService }: FtrProviderContext) { securitySolutionTimeline: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionNotes: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionSiemMigrations: ['all', 'read', 'minimal_all', 'minimal_read'], + securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], infrastructure: ['all', 'read', 'minimal_all', 'minimal_read'], logs: ['all', 'read', 'minimal_all', 'minimal_read'], dataQuality: ['all', 'read', 'minimal_all', 'minimal_read', 'manage_rules', 'manage_alerts'], diff --git a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts index 07ca6d30f5c43..87cad44f1a2fe 100644 --- a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts @@ -59,6 +59,8 @@ export default function ({ getService }: FtrProviderContext) { siemV2: ['all', 'read', 'minimal_all', 'minimal_read'], siemV3: ['all', 'read', 'minimal_all', 'minimal_read'], siemV4: ['all', 'read', 'minimal_all', 'minimal_read'], + siemV5: ['all', 'read', 'minimal_all', 'minimal_read'], + securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionAssistant: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionAttackDiscovery: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionCases: ['all', 'read', 'minimal_all', 'minimal_read'], @@ -350,6 +352,38 @@ export default function ({ getService }: FtrProviderContext) { 'workflow_insights_all', 'workflow_insights_read', ], + siemV5: [ + 'actions_log_management_all', + 'actions_log_management_read', + 'all', + 'global_artifact_management_all', + 'blocklist_all', + 'blocklist_read', + 'endpoint_exceptions_all', + 'endpoint_exceptions_read', + 'endpoint_list_all', + 'endpoint_list_read', + 'event_filters_all', + 'event_filters_read', + 'host_isolation_all', + 'host_isolation_exceptions_all', + 'host_isolation_exceptions_read', + 'minimal_all', + 'minimal_read', + 'policy_management_all', + 'policy_management_read', + 'process_operations_all', + 'read', + 'trusted_applications_all', + 'trusted_applications_read', + 'file_operations_all', + 'execute_operations_all', + 'scan_operations_all', + 'trusted_devices_all', + 'trusted_devices_read', + 'workflow_insights_all', + 'workflow_insights_read', + ], uptime: [ 'all', 'can_manage_private_locations', @@ -358,6 +392,7 @@ export default function ({ getService }: FtrProviderContext) { 'minimal_all', 'minimal_read', ], + securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionAssistant: [ 'all', 'read', diff --git a/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts b/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts index ec3a9ce19f154..815fb9a2ee050 100644 --- a/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts +++ b/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts @@ -192,6 +192,7 @@ export default function ({ getService }: FtrProviderContext) { "siem", "siemV2", "siemV3", + "siemV4", "visualize", ] `); @@ -220,6 +221,8 @@ export default function ({ getService }: FtrProviderContext) { 'maps', 'siem', 'siemV2', + 'siemV3', + 'siemV4', ]); for (const feature of features) { if ( diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts index dd8264da5f4ed..3f5d3f95b3adc 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts @@ -92,9 +92,10 @@ export function createTestSuiteFactory({ getService }: DeploymentAgnosticFtrProv 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', + 'securitySolutionRulesV1', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', - 'siemV4', + 'siemV5', 'slo', 'uptime', ], diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts index 8d94004cb5fcf..46e2c26b41f94 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts @@ -94,9 +94,10 @@ export function getTestSuiteFactory(context: DeploymentAgnosticFtrProviderContex 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', + 'securitySolutionRulesV1', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', - 'siemV4', + 'siemV5', 'slo', 'uptime', ], diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts index a023551134174..8e5fb26511f7c 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts @@ -84,9 +84,10 @@ const ALL_SPACE_RESULTS: Space[] = [ 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', + 'securitySolutionRulesV1', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', - 'siemV4', + 'siemV5', 'slo', 'uptime', ], diff --git a/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts b/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts index d799c74b3d38e..177da91c4fc2c 100644 --- a/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts +++ b/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts @@ -97,6 +97,8 @@ export default function ({ getService }: FtrProviderContext) { siemV2: 0, siemV3: 0, siemV4: 0, + siemV5: 0, + securitySolutionRulesV1: 0, securitySolutionCases: 0, securitySolutionCasesV2: 0, securitySolutionCasesV3: 0, diff --git a/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx b/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx index 9c3836d64b8de..2f106d01fcb19 100644 --- a/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx +++ b/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx @@ -271,10 +271,10 @@ export const DataTableComponent = React.memo( direction: 'asc' | 'desc'; }> = useMemo( () => - sort.map((x) => ({ + sort?.map((x) => ({ id: x.columnId, direction: mapSortDirectionToDirection(x.sortDirection), - })), + })) ?? [], [sort] ); diff --git a/x-pack/solutions/security/packages/data-table/store/data_table/model.ts b/x-pack/solutions/security/packages/data-table/store/data_table/model.ts index bcddfe864d4f1..c70cf88d7448e 100644 --- a/x-pack/solutions/security/packages/data-table/store/data_table/model.ts +++ b/x-pack/solutions/security/packages/data-table/store/data_table/model.ts @@ -21,7 +21,7 @@ export interface DataTableModelSettings { /** When true, shows checkboxes enabling selection. Selected events store in selectedEventIds **/ showCheckboxes: boolean; /** Specifies which column the data table is sorted on, and the direction (ascending / descending) */ - sort: SortColumnTable[]; + sort: SortColumnTable[]; // TODO this was made optional in the initial commit; why? title: string; unit?: (n: number) => string | React.ReactNode; } diff --git a/x-pack/solutions/security/packages/features/product_features.ts b/x-pack/solutions/security/packages/features/product_features.ts index c830fdbb3d456..93aaa24bda52e 100644 --- a/x-pack/solutions/security/packages/features/product_features.ts +++ b/x-pack/solutions/security/packages/features/product_features.ts @@ -11,9 +11,11 @@ export { getSecurityV2Feature, getSecurityV3Feature, getSecurityV4Feature, + getSecurityV5Feature, } from './src/security'; export { getAssistantFeature } from './src/assistant'; export { getAttackDiscoveryFeature } from './src/attack_discovery'; export { getTimelineFeature } from './src/timeline'; export { getNotesFeature } from './src/notes'; export { getSiemMigrationsFeature } from './src/siem_migrations'; +export { getRulesFeature } from './src/rules'; diff --git a/x-pack/solutions/security/packages/features/src/constants.ts b/x-pack/solutions/security/packages/features/src/constants.ts index 782054a3157c5..e5ea639b2dcef 100644 --- a/x-pack/solutions/security/packages/features/src/constants.ts +++ b/x-pack/solutions/security/packages/features/src/constants.ts @@ -15,6 +15,14 @@ export const SECURITY_FEATURE_ID_V2 = 'siemV2' as const; export const SECURITY_FEATURE_ID_V3 = 'siemV3' as const; // New version for 9.2. export const SECURITY_FEATURE_ID_V4 = 'siemV4' as const; +// New version for 9.3. +export const SECURITY_FEATURE_ID_V5 = 'siemV5' as const; + +// Security UI privileges +export const SECURITY_UI_SHOW = 'show' as const; +export const SECURITY_UI_SHOW_PRIVILEGE = `${SECURITY_FEATURE_ID_V5}.${SECURITY_UI_SHOW}` as const; +export const SECURITY_UI_CRUD = 'crud' as const; +export const SECURITY_UI_CRUD_PRIVILEGE = `${SECURITY_FEATURE_ID_V5}.${SECURITY_UI_CRUD}` as const; /** * @deprecated deprecated in 8.17. Use CASE_FEATURE_ID_V2 instead @@ -35,6 +43,32 @@ export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SIEM_MIGRATIONS_FEATURE_ID = 'securitySolutionSiemMigrations' as const; +export const RULES_FEATURE_ID = 'securitySolutionRulesV1' as const; + +// Rules API privileges +export const RULES_API_READ = 'rules-read' as const; +export const RULES_API_ALL = 'rules-all' as const; +export const ALERTS_API_READ = 'alerts-read' as const; +export const ALERTS_API_ALL = 'alerts-all' as const; +export const EXCEPTIONS_API_READ = 'exceptions-read' as const; +export const EXCEPTIONS_API_ALL = 'exceptions-all' as const; +export const LISTS_API_READ = 'lists-read' as const; +export const LISTS_API_ALL = 'lists-all' as const; +export const LISTS_API_SUMMARY = 'lists-summary' as const; +export const INITIALIZE_SECURITY_SOLUTION = 'initialize-security-solution' as const; +export const USERS_API_READ = 'users-read' as const; + +// Rules UI privileges +export const RULES_UI_READ = 'read_rules' as const; +export const RULES_UI_DETECTIONS = 'detections' as const; +export const RULES_UI_EXTERNAL_DETECTIONS = 'external_detections' as const; +export const RULES_UI_READ_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_READ}` as const; +export const RULES_UI_EDIT = 'edit_rules' as const; +export const RULES_UI_EDIT_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_EDIT}` as const; +export const RULES_UI_DETECTIONS_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_DETECTIONS}` as const; +export const RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE = + `${RULES_FEATURE_ID}.${RULES_UI_EXTERNAL_DETECTIONS}` as const; + // Same as the plugin id defined by Cloud Security Posture export const CLOUD_POSTURE_APP_ID = 'csp' as const; diff --git a/x-pack/solutions/security/packages/features/src/product_features_keys.ts b/x-pack/solutions/security/packages/features/src/product_features_keys.ts index 099fb141eff8f..13a7cebe9b1b4 100644 --- a/x-pack/solutions/security/packages/features/src/product_features_keys.ts +++ b/x-pack/solutions/security/packages/features/src/product_features_keys.ts @@ -12,11 +12,8 @@ export enum ProductFeatureSecurityKey { /** Enables Configurations page for AI SOC */ configurations = 'configurations', - /** Elastic endpoint detections, includes alerts, rules, investigations */ + /** Elastic endpoint detections, includes CSP rules which remain provisionally within siem */ detections = 'detections', - - /** Enables external detections for AI SOC, includes alerts_summary, basic_rules*/ - externalDetections = 'external_detections', /** * Enables Investigation guide in Timeline */ @@ -109,11 +106,6 @@ export enum ProductFeatureSecurityKey { /** Enables Endpoint Workflow Insights */ securityWorkflowInsights = 'security_workflow_insights', - - /** - * Enables customization of prebuilt Elastic rules - */ - prebuiltRuleCustomization = 'prebuilt_rule_customization', } export enum ProductFeatureCasesKey { @@ -157,6 +149,19 @@ export enum ProductFeatureSiemMigrationsKey { siemMigrations = 'siem_migrations', } +export enum ProductFeatureRulesKey { + /** Elastic endpoint detections, includes alerts, rules, investigations */ + detections = 'detections', + + /** Enables external detections for AI SOC, includes alerts_summary, basic_rules*/ + externalDetections = 'external_detections', + + /** + * Enables customization of prebuilt Elastic rules + */ + prebuiltRuleCustomization = 'prebuilt_rule_customization', +} + // Merges the two enums. export const ProductFeatureKey = { ...ProductFeatureSecurityKey, @@ -166,6 +171,7 @@ export const ProductFeatureKey = { ...ProductFeatureSiemMigrationsKey, ...ProductFeatureTimelineKey, ...ProductFeatureNotesKey, + ...ProductFeatureRulesKey, }; // We need to merge the value and the type and export both to replicate how enum works. export type ProductFeatureKeyType = @@ -175,7 +181,8 @@ export type ProductFeatureKeyType = | ProductFeatureAttackDiscoveryKey | ProductFeatureSiemMigrationsKey | ProductFeatureTimelineKey - | ProductFeatureNotesKey; + | ProductFeatureNotesKey + | ProductFeatureRulesKey; export const ALL_PRODUCT_FEATURE_KEYS = Object.freeze(Object.values(ProductFeatureKey)); diff --git a/x-pack/solutions/security/packages/features/src/rules/index.ts b/x-pack/solutions/security/packages/features/src/rules/index.ts new file mode 100644 index 0000000000000..9544ddd09d22c --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getRulesBaseKibanaFeature } from './kibana_features'; +import type { ProductFeatureParams } from '../types'; +import type { SecurityFeatureParams } from '../security/types'; +import { rulesDefaultProductFeaturesConfig } from './product_feature_config'; + +export const getRulesFeature = (params: SecurityFeatureParams): ProductFeatureParams => ({ + baseKibanaFeature: getRulesBaseKibanaFeature(params), + baseKibanaSubFeatureIds: [], + subFeaturesMap: new Map(), + productFeatureConfig: rulesDefaultProductFeaturesConfig, +}); diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts new file mode 100644 index 0000000000000..a39684fab801c --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import { i18n } from '@kbn/i18n'; + +import { + ESQL_RULE_TYPE_ID, + EQL_RULE_TYPE_ID, + INDICATOR_RULE_TYPE_ID, + ML_RULE_TYPE_ID, + QUERY_RULE_TYPE_ID, + SAVED_QUERY_RULE_TYPE_ID, + THRESHOLD_RULE_TYPE_ID, + NEW_TERMS_RULE_TYPE_ID, +} from '@kbn/securitysolution-rules'; +import { + ALERTS_API_ALL, + ALERTS_API_READ, + APP_ID, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + LEGACY_NOTIFICATIONS_ID, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + RULES_FEATURE_ID, + RULES_UI_EDIT, + RULES_UI_READ, + SERVER_APP_ID, + USERS_API_READ, +} from '../constants'; +import { type BaseKibanaFeatureConfig } from '../types'; +import type { SecurityFeatureParams } from '../security/types'; + +const SECURITY_RULE_TYPES = [ + LEGACY_NOTIFICATIONS_ID, + ESQL_RULE_TYPE_ID, + EQL_RULE_TYPE_ID, + INDICATOR_RULE_TYPE_ID, + ML_RULE_TYPE_ID, + QUERY_RULE_TYPE_ID, + SAVED_QUERY_RULE_TYPE_ID, + THRESHOLD_RULE_TYPE_ID, + NEW_TERMS_RULE_TYPE_ID, +]; + +const alertingFeatures = SECURITY_RULE_TYPES.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [SERVER_APP_ID], +})); + +export const getRulesBaseKibanaFeature = ( + params: SecurityFeatureParams +): BaseKibanaFeatureConfig => ({ + id: RULES_FEATURE_ID, + name: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionRolesTitle', + { + defaultMessage: 'Rules', + } + ), + order: 1100, + category: DEFAULT_APP_CATEGORIES.security, + // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], + app: [RULES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + alerting: alertingFeatures, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + privileges: { + all: { + app: [RULES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + savedObject: { + all: params.savedObjects, + read: params.savedObjects, + }, + alerting: { + rule: { all: alertingFeatures }, + alert: { all: alertingFeatures }, + }, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + ui: [RULES_UI_READ, RULES_UI_EDIT], + api: [ + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + 'rac', + ], + }, + read: { + app: [RULES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + savedObject: { + all: [], + read: params.savedObjects, + }, + alerting: { + rule: { read: alertingFeatures }, + alert: { read: alertingFeatures }, + }, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + ui: [RULES_UI_READ], + api: [ + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + LISTS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + 'rac', + ], + }, + }, +}); diff --git a/x-pack/solutions/security/packages/features/src/rules/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/rules/product_feature_config.ts new file mode 100644 index 0000000000000..b78ae93bfe48e --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/product_feature_config.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProductFeatureRulesKey } from '../product_features_keys'; +import type { RulesProductFeaturesConfig } from './types'; + +export const rulesDefaultProductFeaturesConfig: RulesProductFeaturesConfig = { + [ProductFeatureRulesKey.externalDetections]: { + privileges: { + all: { + ui: ['external_detections'], + api: [], + }, + read: { + ui: ['external_detections'], + api: [], + }, + }, + }, + [ProductFeatureRulesKey.detections]: { + privileges: { + all: { + ui: ['detections'], + api: ['cloud-security-posture-all', 'cloud-security-posture-read', 'bulkGetUserProfiles'], + }, + read: { + ui: ['detections'], + api: ['cloud-security-posture-read', 'bulkGetUserProfiles'], + }, + }, + }, +}; diff --git a/x-pack/solutions/security/packages/features/src/rules/types.ts b/x-pack/solutions/security/packages/features/src/rules/types.ts new file mode 100644 index 0000000000000..af9bf035239c9 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/types.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ProductFeatureRulesKey } from '../product_features_keys'; +import type { ProductFeaturesConfig } from '../types'; + +export type RulesProductFeaturesConfig = ProductFeaturesConfig; diff --git a/x-pack/solutions/security/packages/features/src/security/index.ts b/x-pack/solutions/security/packages/features/src/security/index.ts index 90d72f4ef50a5..976fd4e92d2eb 100644 --- a/x-pack/solutions/security/packages/features/src/security/index.ts +++ b/x-pack/solutions/security/packages/features/src/security/index.ts @@ -30,6 +30,11 @@ import { getSecurityV4BaseKibanaSubFeatureIds, getSecurityV4SubFeaturesMap, } from './v4_features/kibana_sub_features'; +import { getSecurityV5BaseKibanaFeature } from './v5_features/kibana_features'; +import { + getSecurityV5BaseKibanaSubFeatureIds, + getSecurityV5SubFeaturesMap, +} from './v5_features/kibana_sub_features'; export const getSecurityFeature = ( params: SecurityFeatureParams @@ -66,3 +71,12 @@ export const getSecurityV4Feature = ( subFeaturesMap: getSecurityV4SubFeaturesMap(params), productFeatureConfig: securityDefaultProductFeaturesConfig, }); + +export const getSecurityV5Feature = ( + params: SecurityFeatureParams +): ProductFeatureParams => ({ + baseKibanaFeature: getSecurityV5BaseKibanaFeature(params), + baseKibanaSubFeatureIds: getSecurityV5BaseKibanaSubFeatureIds(params), + subFeaturesMap: getSecurityV5SubFeaturesMap(params), + productFeatureConfig: securityDefaultProductFeaturesConfig, +}); diff --git a/x-pack/solutions/security/packages/features/src/security/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/security/product_feature_config.ts index e7a80965433d7..1bc39214d74e1 100644 --- a/x-pack/solutions/security/packages/features/src/security/product_feature_config.ts +++ b/x-pack/solutions/security/packages/features/src/security/product_feature_config.ts @@ -22,34 +22,15 @@ export const securityDefaultProductFeaturesConfig: SecurityProductFeaturesConfig }, }, }, - - [ProductFeatureSecurityKey.externalDetections]: { - privileges: { - all: { - ui: ['external_detections'], - api: [], - }, - read: { - ui: ['external_detections'], - api: [], - }, - }, - }, [ProductFeatureSecurityKey.detections]: { privileges: { all: { ui: ['detections'], - api: [ - 'cloud-security-posture-all', - 'cloud-security-posture-read', - 'cloud-defend-all', - 'cloud-defend-read', - 'bulkGetUserProfiles', - ], + api: ['cloud-security-posture-all', 'cloud-security-posture-read', 'bulkGetUserProfiles'], }, read: { ui: ['detections'], - api: ['cloud-security-posture-read', 'cloud-defend-read', 'bulkGetUserProfiles'], + api: ['cloud-security-posture-read', 'bulkGetUserProfiles'], }, }, }, diff --git a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts index 675fb543847cc..23e9c5e7e8a3d 100644 --- a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts @@ -23,9 +23,23 @@ import { SERVER_APP_ID, LEGACY_NOTIFICATIONS_ID, CLOUD_POSTURE_APP_ID, - SECURITY_FEATURE_ID_V4, + SECURITY_FEATURE_ID_V5, TIMELINE_FEATURE_ID, NOTES_FEATURE_ID, + LISTS_API_SUMMARY, + LISTS_API_READ, + LISTS_API_ALL, + RULES_FEATURE_ID, + SECURITY_UI_SHOW, + SECURITY_UI_CRUD, + INITIALIZE_SECURITY_SOLUTION, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, } from '../../constants'; import type { SecurityFeatureParams } from '../types'; import type { BaseKibanaFeatureConfig } from '../../types'; @@ -57,7 +71,7 @@ export const getSecurityBaseKibanaFeature = ({ defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', values: { currentId: SERVER_APP_ID, - latestId: SECURITY_FEATURE_ID_V4, + latestId: SECURITY_FEATURE_ID_V5, }, } ), @@ -91,33 +105,40 @@ export const getSecurityBaseKibanaFeature = ({ default: [ { feature: TIMELINE_FEATURE_ID, privileges: ['all'] }, { feature: NOTES_FEATURE_ID, privileges: ['all'] }, - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - { feature: SECURITY_FEATURE_ID_V4, privileges: ['all'] }, + // note: overriden by product feature endpointArtifactManagement when enabled + { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, + { feature: RULES_FEATURE_ID, privileges: ['all'] }, ], minimal: [ { feature: TIMELINE_FEATURE_ID, privileges: ['all'] }, { feature: NOTES_FEATURE_ID, privileges: ['all'] }, - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - { feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_all'] }, + // note: overriden by product feature endpointArtifactManagement when enabled + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], api: [ APP_ID, - 'lists-all', - 'lists-read', - 'lists-summary', + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, 'rac', 'cloud-security-posture-all', 'cloud-security-posture-read', - 'cloud-defend-all', - 'cloud-defend-read', 'timeline_write', 'timeline_read', 'notes_write', 'notes_read', - 'bulkGetUserProfiles', ], savedObject: { all: ['alert', ...savedObjects], @@ -134,34 +155,37 @@ export const getSecurityBaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show', 'crud'], + ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], }, read: { replacedBy: { default: [ { feature: TIMELINE_FEATURE_ID, privileges: ['read'] }, { feature: NOTES_FEATURE_ID, privileges: ['read'] }, - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - { feature: SECURITY_FEATURE_ID_V4, privileges: ['read'] }, + { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, + { feature: RULES_FEATURE_ID, privileges: ['read'] }, ], minimal: [ { feature: TIMELINE_FEATURE_ID, privileges: ['read'] }, { feature: NOTES_FEATURE_ID, privileges: ['read'] }, - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - { feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_read'] }, + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], api: [ APP_ID, - 'lists-read', + LISTS_API_READ, + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, 'rac', 'cloud-security-posture-read', - 'cloud-defend-read', 'timeline_read', 'notes_read', - 'bulkGetUserProfiles', ], savedObject: { all: [], @@ -178,7 +202,7 @@ export const getSecurityBaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show'], + ui: [SECURITY_UI_SHOW], }, }, }); diff --git a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts index f66cb9bfe75fd..94ea900639a1f 100644 --- a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts @@ -6,7 +6,7 @@ */ import type { SubFeatureConfig } from '@kbn/features-plugin/common'; -import { SECURITY_FEATURE_ID_V4 } from '../../../constants'; +import { SECURITY_FEATURE_ID_V5 } from '../../../constants'; import { SecuritySubFeatureId } from '../../product_features_keys'; import type { SecurityFeatureParams } from '../types'; import type { SubFeatureReplacements } from '../../types'; @@ -28,44 +28,44 @@ import { } from '../kibana_sub_features'; const replacements: Partial> = { - [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V4 }], + [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V5 }], [SecuritySubFeatureId.trustedApplications]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { trusted_applications_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.hostIsolationExceptionsBasic]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { host_isolation_exceptions_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.blocklist]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { blocklist_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.eventFilters]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { event_filters_all: ['global_artifact_management_all'] }, }, ], + [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], [SecuritySubFeatureId.endpointExceptions]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { endpoint_exceptions_all: ['global_artifact_management_all'] }, }, ], - [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], }; /** diff --git a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts index aaf390b96b83b..788f29ef7bd4c 100644 --- a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts @@ -24,7 +24,21 @@ import { LEGACY_NOTIFICATIONS_ID, CLOUD_POSTURE_APP_ID, SERVER_APP_ID, - SECURITY_FEATURE_ID_V4, + SECURITY_FEATURE_ID_V5, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_FEATURE_ID, + SECURITY_UI_SHOW, + SECURITY_UI_CRUD, + INITIALIZE_SECURITY_SOLUTION, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, + RULES_API_ALL, } from '../../constants'; import type { SecurityFeatureParams } from '../types'; import type { BaseKibanaFeatureConfig } from '../../types'; @@ -56,7 +70,7 @@ export const getSecurityV2BaseKibanaFeature = ({ defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', values: { currentId: SECURITY_FEATURE_ID_V2, - latestId: SECURITY_FEATURE_ID_V4, + latestId: SECURITY_FEATURE_ID_V5, }, } ), @@ -87,14 +101,34 @@ export const getSecurityV2BaseKibanaFeature = ({ privileges: { all: { replacedBy: { - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - default: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['all'] }], - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - minimal: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_all'] }], + default: [ + // note: overriden by product feature endpointArtifactManagement when enabled + { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, + { feature: RULES_FEATURE_ID, privileges: ['all'] }, + ], + minimal: [ + // note: overriden by product feature endpointArtifactManagement when enabled + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-all', 'lists-read', 'lists-summary'], + api: [ + APP_ID, + 'rac', + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: ['alert', ...savedObjects], read: [], @@ -106,18 +140,31 @@ export const getSecurityV2BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show', 'crud'], + ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], }, read: { replacedBy: { - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - default: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['read'] }], - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - minimal: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_read'] }], + default: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, + { feature: RULES_FEATURE_ID, privileges: ['read'] }, + ], + minimal: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-read'], + api: [ + APP_ID, + 'rac', + LISTS_API_READ, + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: [], read: [...savedObjects], @@ -133,7 +180,7 @@ export const getSecurityV2BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show'], + ui: [SECURITY_UI_SHOW], }, }, }); diff --git a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts index 518bc6ca65d4e..83c17704b8cfb 100644 --- a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts @@ -8,7 +8,7 @@ import type { SubFeatureConfig } from '@kbn/features-plugin/common'; import { SecuritySubFeatureId } from '../../product_features_keys'; -import { SECURITY_FEATURE_ID_V4 } from '../../constants'; +import { SECURITY_FEATURE_ID_V5 } from '../../constants'; import type { SecurityFeatureParams } from '../types'; import { endpointListSubFeature, @@ -31,46 +31,46 @@ import type { SubFeatureReplacements } from '../../types'; import { addSubFeatureReplacements } from '../../utils'; const replacements: Partial> = { - [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.workflowInsights]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.globalArtifactManagement]: [{ feature: SECURITY_FEATURE_ID_V4 }], + [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.workflowInsights]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.globalArtifactManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], [SecuritySubFeatureId.trustedApplications]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { trusted_applications_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.hostIsolationExceptionsBasic]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { host_isolation_exceptions_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.blocklist]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { blocklist_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.eventFilters]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { event_filters_all: ['global_artifact_management_all'] }, }, ], [SecuritySubFeatureId.endpointExceptions]: [ { - feature: SECURITY_FEATURE_ID_V4, + feature: SECURITY_FEATURE_ID_V5, additionalPrivileges: { endpoint_exceptions_all: ['global_artifact_management_all'] }, }, ], - [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], + [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], }; /** diff --git a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts index cfd69bc230411..c00578819438d 100644 --- a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts @@ -24,7 +24,21 @@ import { LEGACY_NOTIFICATIONS_ID, CLOUD_POSTURE_APP_ID, SERVER_APP_ID, - SECURITY_FEATURE_ID_V4, + SECURITY_FEATURE_ID_V5, + RULES_FEATURE_ID, + LISTS_API_SUMMARY, + LISTS_API_READ, + LISTS_API_ALL, + SECURITY_UI_SHOW, + SECURITY_UI_CRUD, + INITIALIZE_SECURITY_SOLUTION, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, } from '../../constants'; import type { SecurityFeatureParams } from '../types'; import type { BaseKibanaFeatureConfig } from '../../types'; @@ -56,12 +70,11 @@ export const getSecurityV3BaseKibanaFeature = ({ defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', values: { currentId: SECURITY_FEATURE_ID_V3, - latestId: SECURITY_FEATURE_ID_V4, + latestId: SECURITY_FEATURE_ID_V5, }, } ), }, - id: SECURITY_FEATURE_ID_V3, name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionTitle', @@ -87,14 +100,32 @@ export const getSecurityV3BaseKibanaFeature = ({ privileges: { all: { replacedBy: { - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - default: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['all'] }], - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - minimal: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_all'] }], + default: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, + { feature: RULES_FEATURE_ID, privileges: ['all'] }, + ], + minimal: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-all', 'lists-read', 'lists-summary'], + api: [ + APP_ID, + 'rac', + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: ['alert', ...savedObjects], read: [], @@ -106,18 +137,31 @@ export const getSecurityV3BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show', 'crud'], + ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], }, read: { replacedBy: { - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - default: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['read'] }], - // note: ESS/serverless specific productFeaturesExtensions modify this privilege array - minimal: [{ feature: SECURITY_FEATURE_ID_V4, privileges: ['minimal_read'] }], + default: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, + { feature: RULES_FEATURE_ID, privileges: ['read'] }, + ], + minimal: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-read'], + api: [ + APP_ID, + 'rac', + LISTS_API_READ, + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: [], read: [...savedObjects], @@ -133,7 +177,7 @@ export const getSecurityV3BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show'], + ui: [SECURITY_UI_SHOW], }, }, }); diff --git a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts index 24bc2af5b04de..5063ec9fdb9f0 100644 --- a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts @@ -27,26 +27,26 @@ import { trustedDevicesSubFeature, } from '../kibana_sub_features'; import type { SubFeatureReplacements } from '../../types'; -import { SECURITY_FEATURE_ID_V4 } from '../../constants'; +import { SECURITY_FEATURE_ID_V5 } from '../../constants'; import { addSubFeatureReplacements } from '../../utils'; const replacements: Partial> = { - [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.workflowInsights]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.globalArtifactManagement]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.trustedApplications]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.trustedDevices]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.hostIsolationExceptionsBasic]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.blocklist]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.eventFilters]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.endpointExceptions]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], - [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V4 }], + [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.workflowInsights]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.globalArtifactManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.trustedApplications]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.trustedDevices]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolationExceptionsBasic]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.blocklist]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.eventFilters]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.endpointExceptions]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], }; /** diff --git a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts index 315d01066ddfe..2d1c676ccab5d 100644 --- a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts @@ -24,6 +24,21 @@ import { LEGACY_NOTIFICATIONS_ID, CLOUD_POSTURE_APP_ID, SERVER_APP_ID, + SECURITY_FEATURE_ID_V5, + RULES_FEATURE_ID, + LISTS_API_READ, + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + LISTS_API_ALL, + LISTS_API_SUMMARY, + RULES_API_ALL, + ALERTS_API_ALL, + EXCEPTIONS_API_ALL, + SECURITY_UI_CRUD, + SECURITY_UI_SHOW, } from '../../constants'; import type { SecurityFeatureParams } from '../types'; import type { BaseKibanaFeatureConfig } from '../../types'; @@ -48,6 +63,18 @@ const alertingFeatures = SECURITY_RULE_TYPES.map((ruleTypeId) => ({ export const getSecurityV4BaseKibanaFeature = ({ savedObjects, }: SecurityFeatureParams): BaseKibanaFeatureConfig => ({ + deprecated: { + notice: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionSecurity.deprecationMessage', + { + defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', + values: { + currentId: SECURITY_FEATURE_ID_V4, + latestId: SECURITY_FEATURE_ID_V5, + }, + } + ), + }, id: SECURITY_FEATURE_ID_V4, name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionTitle', @@ -72,9 +99,33 @@ export const getSecurityV4BaseKibanaFeature = ({ ), privileges: { all: { + replacedBy: { + default: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, + { feature: RULES_FEATURE_ID, privileges: ['all'] }, + ], + minimal: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + ], + }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-all', 'lists-read', 'lists-summary'], + api: [ + APP_ID, + 'rac', + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: ['alert', ...savedObjects], read: [], @@ -86,12 +137,31 @@ export const getSecurityV4BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show', 'crud'], + ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], }, read: { + replacedBy: { + default: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, + { feature: RULES_FEATURE_ID, privileges: ['read'] }, + ], + minimal: [ + { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + ], + }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], - api: [APP_ID, 'rac', 'lists-read'], + api: [ + APP_ID, + 'rac', + LISTS_API_READ, + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], savedObject: { all: [], read: [...savedObjects], @@ -107,7 +177,7 @@ export const getSecurityV4BaseKibanaFeature = ({ management: { insightsAndAlerting: ['triggersActions'], }, - ui: ['show'], + ui: [SECURITY_UI_SHOW], }, }, }); diff --git a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts index ae709b73a6b2a..4877ef932f367 100644 --- a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts @@ -26,6 +26,28 @@ import { workflowInsightsSubFeature, trustedDevicesSubFeature, } from '../kibana_sub_features'; +import type { SubFeatureReplacements } from '../../types'; +import { SECURITY_FEATURE_ID_V5 } from '../../constants'; +import { addSubFeatureReplacements } from '../../utils'; + +const replacements: Partial> = { + [SecuritySubFeatureId.endpointList]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.workflowInsights]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.globalArtifactManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.trustedApplications]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.trustedDevices]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolationExceptionsBasic]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.blocklist]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.eventFilters]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.endpointExceptions]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.policyManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.responseActionsHistory]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.hostIsolation]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.processOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], +}; /** * Sub-features that will always be available for Security @@ -68,6 +90,11 @@ export const getSecurityV4SubFeaturesMap = ({ securitySubFeaturesList.map(([id, originalSubFeature]) => { let subFeature = originalSubFeature; + const featureReplacements = replacements[id]; + if (featureReplacements) { + subFeature = addSubFeatureReplacements(subFeature, featureReplacements); + } + // Space awareness is now always enabled - set requireAllSpaces to false and remove privilegesTooltip subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts new file mode 100644 index 0000000000000..090e3a1c7ed5a --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import { + APP_ID, + CLOUD_POSTURE_APP_ID, + INITIALIZE_SECURITY_SOLUTION, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + SECURITY_FEATURE_ID_V5, + SECURITY_UI_CRUD, + SECURITY_UI_SHOW, + USERS_API_READ, +} from '../../constants'; +import type { BaseKibanaFeatureConfig } from '../../types'; +import type { SecurityFeatureParams } from '../types'; + +export const getSecurityV5BaseKibanaFeature = ({ + savedObjects, +}: SecurityFeatureParams): BaseKibanaFeatureConfig => ({ + id: SECURITY_FEATURE_ID_V5, + name: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionTitle', + { + defaultMessage: 'Security', + } + ), + order: 1100, + category: DEFAULT_APP_CATEGORIES.security, + // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], + app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + catalogue: [APP_ID], + description: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.securityGroupDescription', + { + defaultMessage: + "Each sub-feature privilege in this group must be assigned individually. Global assignment is only supported if your pricing plan doesn't allow individual feature privileges.", + } + ), + privileges: { + all: { + app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + catalogue: [APP_ID], + api: [ + APP_ID, + 'rac', + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + ], + savedObject: { + all: ['alert', ...savedObjects], + read: [], + }, + ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], + }, + read: { + app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + catalogue: [APP_ID], + api: [APP_ID, 'rac', LISTS_API_READ, USERS_API_READ, INITIALIZE_SECURITY_SOLUTION], + savedObject: { + all: [], + read: [...savedObjects], + }, + ui: [SECURITY_UI_SHOW], + }, + }, +}); diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts new file mode 100644 index 0000000000000..6bf4461430984 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import { SecuritySubFeatureId } from '../../product_features_keys'; +import type { SecurityFeatureParams } from '../types'; +import { + endpointListSubFeature, + endpointExceptionsSubFeature, + globalArtifactManagementSubFeature, + trustedApplicationsSubFeature, + hostIsolationExceptionsBasicSubFeature, + blocklistSubFeature, + eventFiltersSubFeature, + policyManagementSubFeature, + responseActionsHistorySubFeature, + hostIsolationSubFeature, + processOperationsSubFeature, + fileOperationsSubFeature, + executeActionSubFeature, + scanActionSubFeature, + workflowInsightsSubFeature, + trustedDevicesSubFeature, +} from '../kibana_sub_features'; + +/** + * Sub-features that will always be available for Security + * regardless of the product type. + */ +export const getSecurityV5BaseKibanaSubFeatureIds = ( + { experimentalFeatures }: SecurityFeatureParams // currently un-used, but left here as a convenience for possible future use +): SecuritySubFeatureId[] => []; + +/** + * Defines all the Security Assistant subFeatures available. + * The order of the subFeatures is the order they will be displayed + */ +export const getSecurityV5SubFeaturesMap = ({ + experimentalFeatures, +}: SecurityFeatureParams): Map => { + const securitySubFeaturesList: Array<[SecuritySubFeatureId, SubFeatureConfig]> = [ + [SecuritySubFeatureId.endpointList, endpointListSubFeature()], + [SecuritySubFeatureId.workflowInsights, workflowInsightsSubFeature()], + [ + SecuritySubFeatureId.globalArtifactManagement, + globalArtifactManagementSubFeature(experimentalFeatures), + ], + [SecuritySubFeatureId.trustedApplications, trustedApplicationsSubFeature()], + [SecuritySubFeatureId.trustedDevices, trustedDevicesSubFeature()], + [SecuritySubFeatureId.hostIsolationExceptionsBasic, hostIsolationExceptionsBasicSubFeature()], + [SecuritySubFeatureId.blocklist, blocklistSubFeature()], + [SecuritySubFeatureId.eventFilters, eventFiltersSubFeature()], + [SecuritySubFeatureId.endpointExceptions, endpointExceptionsSubFeature()], + [SecuritySubFeatureId.policyManagement, policyManagementSubFeature()], + [SecuritySubFeatureId.responseActionsHistory, responseActionsHistorySubFeature()], + [SecuritySubFeatureId.hostIsolation, hostIsolationSubFeature()], + [SecuritySubFeatureId.processOperations, processOperationsSubFeature()], + [SecuritySubFeatureId.fileOperations, fileOperationsSubFeature()], + [SecuritySubFeatureId.executeAction, executeActionSubFeature()], + [SecuritySubFeatureId.scanAction, scanActionSubFeature()], + ]; + + const securitySubFeaturesMap = new Map( + securitySubFeaturesList.map(([id, originalSubFeature]) => { + let subFeature = originalSubFeature; + + // If the feature is space-aware, we need to set false to the requireAllSpaces flag and remove the privilegesTooltip + if (experimentalFeatures.endpointManagementSpaceAwarenessEnabled) { + subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; + } + + return [id, subFeature]; + }) + ); + + // Remove disabled experimental features + if (!experimentalFeatures.defendInsightsPolicyResponseFailure) { + securitySubFeaturesMap.delete(SecuritySubFeatureId.workflowInsights); + } + if (!experimentalFeatures.trustedDevices) { + securitySubFeaturesMap.delete(SecuritySubFeatureId.trustedDevices); + } + + return Object.freeze(securitySubFeaturesMap); +}; diff --git a/x-pack/solutions/security/packages/features/src/types.ts b/x-pack/solutions/security/packages/features/src/types.ts index 959528dd5361a..2a0b6ad2c2fe5 100644 --- a/x-pack/solutions/security/packages/features/src/types.ts +++ b/x-pack/solutions/security/packages/features/src/types.ts @@ -23,6 +23,7 @@ import type { ProductFeatureSiemMigrationsKey, ProductFeatureTimelineKey, ProductFeatureNotesKey, + ProductFeatureRulesKey, } from './product_features_keys'; export type { ProductFeatureKeyType }; @@ -94,6 +95,7 @@ export type TimelineProductFeaturesConfig = ProductFeaturesConfig; export type SiemMigrationsProductFeaturesConfig = ProductFeaturesConfig; +export type RulesProductFeaturesConfig = ProductFeaturesConfig; export type AppSubFeaturesMap = Map; @@ -122,6 +124,7 @@ interface ProductFeatureConfigExtensions { timeline: ConfigExtensions; notes: ConfigExtensions; siemMigrations: ConfigExtensions; + rules: ConfigExtensions; } export type ProductFeaturesConfiguratorExtensions = Partial; diff --git a/x-pack/solutions/security/plugins/elastic_assistant/common/constants.ts b/x-pack/solutions/security/plugins/elastic_assistant/common/constants.ts index 66081eec3c2fa..6165a1f76d542 100755 --- a/x-pack/solutions/security/plugins/elastic_assistant/common/constants.ts +++ b/x-pack/solutions/security/plugins/elastic_assistant/common/constants.ts @@ -6,7 +6,7 @@ */ export { - SECURITY_FEATURE_ID_V4 as SECURITY_FEATURE_ID, + SECURITY_FEATURE_ID_V5 as SECURITY_FEATURE_ID, CASES_FEATURE_ID_V3 as CASES_FEATURE_ID, } from '@kbn/security-solution-features/constants'; diff --git a/x-pack/solutions/security/plugins/elastic_assistant/scripts/create_and_login_users.js b/x-pack/solutions/security/plugins/elastic_assistant/scripts/create_and_login_users.js index ba9d479c66111..ff6c7a6cba14b 100644 --- a/x-pack/solutions/security/plugins/elastic_assistant/scripts/create_and_login_users.js +++ b/x-pack/solutions/security/plugins/elastic_assistant/scripts/create_and_login_users.js @@ -98,6 +98,7 @@ const createRestrictedRole = async (roleName) => { uptime: ['all'], observabilityCasesV3: ['all'], [SECURITY_FEATURE_ID]: ['all'], + rules: ['all'], securitySolutionCasesV3: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_item_route.ts index 1ee178e9bc646..d4fb35dfec058 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_item_route.ts @@ -13,6 +13,7 @@ import { CreateEndpointListItemRequestBody, CreateEndpointListItemResponse, } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -26,7 +27,7 @@ export const createEndpointListItemRoute = (router: ListsPluginRouter): void => path: ENDPOINT_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_route.ts index 54887adba7df4..70092c8bc6835 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_endpoint_list_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { ENDPOINT_LIST_URL } from '@kbn/securitysolution-list-constants'; import { CreateEndpointListResponse } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -30,7 +31,7 @@ export const createEndpointListRoute = (router: ListsPluginRouter): void => { path: ENDPOINT_LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts index e5c6bfd09dfc5..a3c17034d8247 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -13,6 +13,7 @@ import { CreateExceptionListItemRequestBody, CreateExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +29,7 @@ export const createExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts index c7e0a952743c3..fcc089dc4d566 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts @@ -13,6 +13,7 @@ import { CreateExceptionListRequestBody, CreateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +26,7 @@ export const createExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/delete_endpoint_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/delete_endpoint_list_item_route.ts index ee7093bcc1c50..aebc0f772dc6b 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/delete_endpoint_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/delete_endpoint_list_item_route.ts @@ -12,6 +12,7 @@ import { DeleteEndpointListItemRequestQuery, DeleteEndpointListItemResponse, } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +29,7 @@ export const deleteEndpointListItemRoute = (router: ListsPluginRouter): void => path: ENDPOINT_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts index d8eb32e9eeaf3..fae33f8fdcf90 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts @@ -12,6 +12,7 @@ import { DeleteExceptionListItemRequestQuery, DeleteExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +29,7 @@ export const deleteExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts index db6bb460cbd37..0b7e746182be0 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts @@ -12,6 +12,7 @@ import { DeleteExceptionListRequestQuery, DeleteExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const deleteExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts index 308a2e4cd3a4c..c8ed978b65940 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts @@ -12,6 +12,7 @@ import { DuplicateExceptionListRequestQuery, DuplicateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const duplicateExceptionsRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_duplicate`, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts index 8fdd7dbc5e392..de27a9778be3c 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { ExportExceptionListRequestQuery } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -21,7 +22,7 @@ export const exportExceptionsRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_export`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/find_endpoint_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/find_endpoint_list_item_route.ts index d54560fb6c929..c19701b62d035 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/find_endpoint_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/find_endpoint_list_item_route.ts @@ -12,6 +12,7 @@ import { FindEndpointListItemsRequestQuery, FindEndpointListItemsResponse, } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const findEndpointListItemRoute = (router: ListsPluginRouter): void => { path: `${ENDPOINT_LIST_ITEM_URL}/_find`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts index 964a13296c804..bd5a0465bae34 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -12,6 +12,7 @@ import { FindExceptionListItemsRequestQuery, FindExceptionListItemsResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const findExceptionListItemRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_ITEM_URL}/_find`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts index 43a890780013b..85e2ff63eea18 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts @@ -12,6 +12,7 @@ import { FindExceptionListsRequestQuery, FindExceptionListsResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const findExceptionListRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_find`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts index 4dc6ddc7a30a4..a35efffde1c9f 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts @@ -15,6 +15,7 @@ import { ImportExceptionListRequestQuery, ImportExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; import type { ConfigType } from '../config'; @@ -39,7 +40,7 @@ export const importExceptionsRoute = (router: ListsPluginRouter, config: ConfigT path: `${EXCEPTION_LIST_URL}/_import`, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/internal/create_exceptions_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/internal/create_exceptions_list_route.ts index 78187e5427eb1..d22cf64c03f42 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/internal/create_exceptions_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/internal/create_exceptions_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { InternalCreateExceptionListSchemaDecoded } from '@kbn/securitysolution-io-ts-list-types'; import { internalCreateExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; import { INTERNAL_EXCEPTIONS_LIST_ENSURE_CREATED_URL } from '@kbn/securitysolution-list-constants'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import { createExceptionListHandler } from '../../handlers/create_exception_list_handler'; import type { ListsPluginRouter } from '../../types'; @@ -21,7 +22,7 @@ export const internalCreateExceptionListRoute = (router: ListsPluginRouter): voi path: INTERNAL_EXCEPTIONS_LIST_ENSURE_CREATED_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/internal/find_lists_by_size_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/internal/find_lists_by_size_route.ts index f8e5fc23e2e15..cb63dd37f2de2 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/internal/find_lists_by_size_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/internal/find_lists_by_size_route.ts @@ -13,6 +13,7 @@ import { MAXIMUM_SMALL_VALUE_LIST_SIZE, } from '@kbn/securitysolution-list-constants'; import { chunk } from 'lodash'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { decodeCursor } from '../../services/utils'; @@ -26,7 +27,7 @@ export const findListsBySizeRoute = (router: ListsPluginRouter): void => { path: INTERNAL_FIND_LISTS_BY_SIZE, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/create_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/create_list_route.ts index 23934bdfc792f..58be1c9611464 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/create_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/create_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { CreateListRequestBody, CreateListResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -21,7 +22,7 @@ export const createListRoute = (router: ListsPluginRouter): void => { path: LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/delete_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/delete_list_route.ts index a2f53918f12d5..918b568de020d 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/delete_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/delete_list_route.ts @@ -19,6 +19,7 @@ import { getSavedObjectType } from '@kbn/securitysolution-list-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { DeleteListRequestQuery, DeleteListResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import type { ExceptionListClient } from '../../services/exception_lists/exception_list_client'; @@ -33,7 +34,7 @@ export const deleteListRoute = (router: ListsPluginRouter): void => { path: LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/import_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/import_list_item_route.ts index 36996cc8e6da9..238023d355653 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/import_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/import_list_item_route.ts @@ -15,6 +15,7 @@ import { ImportListItemsRequestQuery, ImportListItemsResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import type { ConfigType } from '../../config'; @@ -41,7 +42,7 @@ export const importListItemRoute = (router: ListsPluginRouter, config: ConfigTyp path: `${LIST_ITEM_URL}/_import`, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/patch_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/patch_list_route.ts index 369084cc21a2d..dfe5a41ee1673 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/patch_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/patch_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { PatchListRequestBody, PatchListResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -21,7 +22,7 @@ export const patchListRoute = (router: ListsPluginRouter): void => { path: LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/read_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/read_list_route.ts index 7fa6d20867bec..24b0aa2ca5417 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/read_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/read_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { ReadListRequestQuery, ReadListResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -21,7 +22,7 @@ export const readListRoute = (router: ListsPluginRouter): void => { path: LIST_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list/update_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list/update_list_route.ts index a09c91b869372..b85d0dd908551 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list/update_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list/update_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { UpdateListRequestBody, UpdateListResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -21,7 +22,7 @@ export const updateListRoute = (router: ListsPluginRouter): void => { path: LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_index/create_list_index_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_index/create_list_index_route.ts index 1881e51c5888b..7b55281af136e 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_index/create_list_index_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_index/create_list_index_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_INDEX } from '@kbn/securitysolution-list-constants'; import { CreateListIndexResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -20,7 +21,7 @@ export const createListIndexRoute = (router: ListsPluginRouter): void => { path: LIST_INDEX, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_index/delete_list_index_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_index/delete_list_index_route.ts index e880b96c868a9..4930e85090890 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_index/delete_list_index_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_index/delete_list_index_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_INDEX } from '@kbn/securitysolution-list-constants'; import { DeleteListIndexResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListClient } from '../../services/lists/list_client'; import type { ListsPluginRouter } from '../../types'; @@ -37,7 +38,7 @@ export const deleteListIndexRoute = (router: ListsPluginRouter): void => { path: LIST_INDEX, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_index/export_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_index/export_list_item_route.ts index 0c66787b80739..ea50192251909 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_index/export_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_index/export_list_item_route.ts @@ -11,6 +11,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { ExportListItemsRequestQuery } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -23,7 +24,7 @@ export const exportListItemRoute = (router: ListsPluginRouter): void => { path: `${LIST_ITEM_URL}/_export`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_index/find_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_index/find_list_route.ts index 13dd137a3d84f..c8f92970a95ca 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_index/find_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_index/find_list_route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { FindListsRequestQuery, FindListsResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { decodeCursor } from '../../services/utils'; @@ -21,7 +22,7 @@ export const findListRoute = (router: ListsPluginRouter): void => { path: `${LIST_URL}/_find`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_index/read_list_index_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_index/read_list_index_route.ts index 2cbe90aa3c81e..88bfd360c00ca 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_index/read_list_index_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_index/read_list_index_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_INDEX } from '@kbn/securitysolution-list-constants'; import { ReadListIndexResponse } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -20,7 +21,7 @@ export const readListIndexRoute = (router: ListsPluginRouter): void => { path: LIST_INDEX, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/create_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/create_list_item_route.ts index b43b5e258d42a..ff55b8d816b2a 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/create_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/create_list_item_route.ts @@ -12,6 +12,7 @@ import { CreateListItemRequestBody, CreateListItemResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -24,7 +25,7 @@ export const createListItemRoute = (router: ListsPluginRouter): void => { path: LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/delete_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/delete_list_item_route.ts index 94c6b17f28d4d..1817be3399301 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/delete_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/delete_list_item_route.ts @@ -12,6 +12,7 @@ import { DeleteListItemRequestQuery, DeleteListItemResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -24,7 +25,7 @@ export const deleteListItemRoute = (router: ListsPluginRouter): void => { path: LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/find_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/find_list_item_route.ts index 5ed305de7ec8a..e8d17d4a7434b 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/find_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/find_list_item_route.ts @@ -12,6 +12,7 @@ import { FindListItemsRequestQuery, FindListItemsResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { decodeCursor } from '../../services/utils'; @@ -24,7 +25,7 @@ export const findListItemRoute = (router: ListsPluginRouter): void => { path: `${LIST_ITEM_URL}/_find`, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/patch_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/patch_list_item_route.ts index ef9290bc2ef32..37808784869c9 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/patch_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/patch_list_item_route.ts @@ -12,6 +12,7 @@ import { PatchListItemRequestBody, PatchListItemResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -24,7 +25,7 @@ export const patchListItemRoute = (router: ListsPluginRouter): void => { path: LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/read_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/read_list_item_route.ts index 421108552b7bd..dd88b489801cf 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/read_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/read_list_item_route.ts @@ -12,6 +12,7 @@ import { ReadListItemRequestQuery, ReadListItemResponse, } from '@kbn/securitysolution-lists-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse } from '../utils'; @@ -24,7 +25,7 @@ export const readListItemRoute = (router: ListsPluginRouter): void => { path: LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_item/update_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_item/update_list_item_route.ts index 14c992870e921..b99d79dfe4e42 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_item/update_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_item/update_list_item_route.ts @@ -7,6 +7,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { LIST_ITEM_URL } from '@kbn/securitysolution-list-constants'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { UpdateListItemRequestBody, @@ -24,7 +25,7 @@ export const updateListItemRoute = (router: ListsPluginRouter): void => { path: LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/list_privileges/read_list_privileges_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/list_privileges/read_list_privileges_route.ts index bf322d10cfc85..d7758cdeab850 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/list_privileges/read_list_privileges_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/list_privileges/read_list_privileges_route.ts @@ -8,6 +8,7 @@ import { readPrivileges, transformError } from '@kbn/securitysolution-es-utils'; import { merge } from 'lodash/fp'; import { LIST_PRIVILEGES_URL } from '@kbn/securitysolution-list-constants'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../../types'; import { buildSiemResponse, getListClient } from '../utils'; @@ -19,7 +20,7 @@ export const readPrivilegesRoute = (router: ListsPluginRouter): void => { path: LIST_PRIVILEGES_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/read_endpoint_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/read_endpoint_list_item_route.ts index 2f607d4c4c334..4a6b1aabd8685 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/read_endpoint_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/read_endpoint_list_item_route.ts @@ -12,6 +12,7 @@ import { ReadEndpointListItemRequestQuery, ReadEndpointListItemResponse, } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +29,7 @@ export const readEndpointListItemRoute = (router: ListsPluginRouter): void => { path: ENDPOINT_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts index ceb0195c390ab..55f875388310a 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts @@ -12,6 +12,7 @@ import { ReadExceptionListItemRequestQuery, ReadExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +29,7 @@ export const readExceptionListItemRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts index 2ff46ffba56f4..3f89d3feceba9 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts @@ -12,6 +12,7 @@ import { ReadExceptionListRequestQuery, ReadExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const readExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: ['lists-read'], + requiredPrivileges: [LISTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/summary_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/summary_exception_list_route.ts index bf5fe000a7fb6..231d9ca622d94 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/summary_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/summary_exception_list_route.ts @@ -12,6 +12,7 @@ import { ReadExceptionListSummaryRequestQuery, ReadExceptionListSummaryResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_SUMMARY } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const summaryExceptionListRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/summary`, security: { authz: { - requiredPrivileges: ['lists-summary'], + requiredPrivileges: [LISTS_API_SUMMARY], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/update_endpoint_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/update_endpoint_list_item_route.ts index a6c633ab57c3a..e5350ec0268d1 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/update_endpoint_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/update_endpoint_list_item_route.ts @@ -12,6 +12,7 @@ import { UpdateEndpointListItemRequestBody, UpdateEndpointListItemResponse, } from '@kbn/securitysolution-endpoint-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -26,7 +27,7 @@ export const updateEndpointListItemRoute = (router: ListsPluginRouter): void => path: ENDPOINT_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts index da1541bb86178..b0fd92e52e732 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -12,6 +12,7 @@ import { UpdateExceptionListItemRequestBody, UpdateExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -27,7 +28,7 @@ export const updateExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts index 36d65d9b1ac5e..dda81dcf1e54f 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts @@ -12,6 +12,7 @@ import { UpdateExceptionListRequestBody, UpdateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -24,7 +25,7 @@ export const updateExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: ['lists-all'], + requiredPrivileges: [LISTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/tsconfig.json b/x-pack/solutions/security/plugins/lists/tsconfig.json index 3ae7ce404b656..36063a12c4157 100644 --- a/x-pack/solutions/security/plugins/lists/tsconfig.json +++ b/x-pack/solutions/security/plugins/lists/tsconfig.json @@ -45,7 +45,8 @@ "@kbn/core-security-server", "@kbn/core-http-server-mocks", "@kbn/core-http-server-utils", - "@kbn/react-query" + "@kbn/react-query", + "@kbn/security-solution-features" ], "exclude": ["target/**/*"] } diff --git a/x-pack/solutions/security/plugins/security_solution/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/constants.ts index 6c1b0961bb54f..2cc2c6ff37f5d 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/constants.ts @@ -7,6 +7,7 @@ import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import type { FilterControlConfig } from '@kbn/alerts-ui-shared'; +import { SECURITY_FEATURE_ID_V5 } from '@kbn/security-solution-features/constants'; import * as i18n from './translations'; export { SecurityPageName } from '@kbn/security-solution-navigation'; @@ -25,7 +26,8 @@ export const CASES_FEATURE_ID = 'securitySolutionCasesV3' as const; export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SERVER_APP_ID = 'siem' as const; -export const SECURITY_FEATURE_ID = 'siemV4' as const; +export const SECURITY_FEATURE_ID = SECURITY_FEATURE_ID_V5; +export { RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; export const APP_NAME = 'Security' as const; export const APP_ICON_SOLUTION = 'logoSecurity' as const; export const APP_PATH = `/app/security` as const; diff --git a/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.test.tsx index b0c17049d1d8a..80855a7b8f1d3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.test.tsx @@ -49,6 +49,7 @@ describe('global header', () => { }, }; const store = createMockStore(state); + // mock capabilities to exclude Search AI Lake configurations beforeEach(() => { jest.clearAllMocks(); (useKibana as jest.Mock).mockReturnValue({ @@ -57,6 +58,7 @@ describe('global header', () => { ...mockUseKibana().services, application: { capabilities: { + ...mockUseKibana().services.application.capabilities, [SECURITY_FEATURE_ID]: { configurations: false, }, @@ -65,6 +67,7 @@ describe('global header', () => { }, }); }); + it('has add data link', () => { const { getByText } = render( @@ -94,6 +97,7 @@ describe('global header', () => { [SECURITY_FEATURE_ID]: { configurations: true, }, + fleet: { read: true }, }, }, }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.tsx index 75a7df7237dd3..cb156590ce370 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/app/home/global_header/index.tsx @@ -52,6 +52,8 @@ export const GlobalHeader = React.memo(() => { application: { capabilities }, } = useKibana().services; const hasSearchAILakeConfigurations = capabilities[SECURITY_FEATURE_ID]?.configurations === true; + const canReadFleet = capabilities.fleet.read === true; + const canAddData = canReadFleet && !hasSearchAILakeConfigurations; const { pathname } = useLocation(); const getTimeline = useMemo(() => timelineSelectors.getTimelineByIdSelector(), []); @@ -106,7 +108,7 @@ export const GlobalHeader = React.memo(() => { - {!hasSearchAILakeConfigurations && ( + {canAddData && ( { it('for serverless, it specifies capabilities as an AND condition, via a nested array', () => { expect(links.capabilities).toEqual([ - [`${SECURITY_FEATURE_ID}.show`, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], + [SECURITY_UI_SHOW_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], ]); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts index bab8fec37b6de..02b1d8b048153 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts @@ -7,19 +7,17 @@ import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { ATTACK_DISCOVERY } from '../app/translations'; import { ATTACK_DISCOVERY_FEATURE_ID, ATTACK_DISCOVERY_PATH, SecurityPageName, - SECURITY_FEATURE_ID, } from '../../common/constants'; import type { LinkItem } from '../common/links/types'; export const links: LinkItem = { - capabilities: [ - [`${SECURITY_FEATURE_ID}.show`, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], - ], // This is an AND condition via the nested array + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`]], // This is an AND condition via the nested array globalNavPosition: 4, globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.attackDiscovery', { diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/index.test.tsx index 9a5d5185add0f..82143d239187f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/index.test.tsx @@ -24,6 +24,7 @@ import { mockFindAnonymizationFieldsResponse } from './mock/mock_find_anonymizat import { ATTACK_DISCOVERY_PAGE_TITLE } from './page_title/translations'; import { useAttackDiscovery } from './use_attack_discovery'; import { useLoadConnectors } from '@kbn/elastic-assistant/impl/connectorland/use_load_connectors'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; const mockConnectors: unknown[] = [ { @@ -82,7 +83,7 @@ jest.mock( }) ); -const mockSecurityCapabilities = [`${SECURITY_FEATURE_ID}.show`]; +const mockSecurityCapabilities = [SECURITY_UI_SHOW_PRIVILEGE]; jest.mock('../../common/links', () => ({ useLinkInfo: () => diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/results/history/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/results/history/index.test.tsx index 3b0c3ac4ceeff..36140f9b761d0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/results/history/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/pages/results/history/index.test.tsx @@ -35,7 +35,42 @@ jest.mock('react-router-dom-v5-compat', () => ({ jest.mock('../../../../common/lib/kibana', () => ({ useDateFormat: jest.fn(), - useKibana: jest.fn(), + useKibana: jest.fn(() => ({ + services: { + application: { + capabilities: { + siemV2: { crud_alerts: true, read_alerts: true }, + siemV3: { configurations: true }, + siemV4: { configurations: true }, + siemV5: { configurations: true }, + }, + navigateToUrl: jest.fn(), + }, + cases: { + helpers: { + canUseCases: jest.fn().mockReturnValue({ + all: true, + connectors: true, + create: true, + delete: true, + push: true, + read: true, + settings: true, + update: true, + }), + }, + hooks: { + useCasesAddToExistingCase: jest.fn(), + useCasesAddToExistingCaseModal: jest.fn().mockReturnValue({ open: jest.fn() }), + useCasesAddToNewCaseFlyout: jest.fn(), + }, + ui: { getCasesContext: mockCasesContext }, + }, + theme: { + getTheme: jest.fn().mockReturnValue({ darkMode: false }), + }, + }, + })), useToasts: jest.fn(() => ({ addError: jest.fn(), addSuccess: jest.fn(), diff --git a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/links.ts b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/links.ts index d22284258680d..d2a210f394e3e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/links.ts @@ -6,8 +6,8 @@ */ import { getSecuritySolutionLink } from '@kbn/cloud-security-posture-plugin/public'; import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import type { SecurityPageName } from '../../common/constants'; -import { SECURITY_FEATURE_ID } from '../../common/constants'; import cloudSecurityPostureDashboardImage from '../common/images/cloud_security_posture_dashboard_page.png'; import cloudNativeVulnerabilityManagementDashboardImage from '../common/images/cloud_native_vulnerability_management_dashboard_page.png'; import type { LinkItem } from '../common/links/types'; @@ -15,7 +15,7 @@ import { IconEndpoints } from '../common/icons/endpoints'; const commonLinkProperties: Partial = { hideTimeline: true, - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [SECURITY_UI_SHOW_PRIVILEGE], }; export const findingsLinks: LinkItem = { diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx index f1d819bdc1df7..416ecd502580b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -128,7 +128,7 @@ const StatefulEventsViewerComponent: React.FC ({ - useUserData: jest.fn().mockReturnValue([{ canUserCRUD: true, hasIndexWrite: true }]), + useUserData: jest.fn().mockReturnValue([{ hasIndexWrite: true }]), })); jest.mock('../../hooks/use_experimental_features', () => ({ useIsExperimentalFeatureEnabled: jest.fn().mockReturnValue(false), @@ -125,6 +125,7 @@ describe('Actions', () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...mockInitialUserPrivilegesState(), endpointPrivileges: { loading: false, canWriteEventFilters: true }, + rulesPrivileges: { read: true, edit: true }, }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx index 435e5005451de..ac89eaa438ed9 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx @@ -7,7 +7,8 @@ import React, { createContext, useMemo } from 'react'; import type { Capabilities } from '@kbn/core/types'; -import { SECURITY_FEATURE_ID } from '../../../../common/constants'; +import { RULES_UI_EDIT, RULES_UI_READ } from '@kbn/security-solution-features/constants'; +import { SECURITY_FEATURE_ID, RULES_FEATURE_ID } from '../../../../common/constants'; import { useFetchListPrivileges } from '../../../detections/components/user_privileges/use_fetch_list_privileges'; import { useFetchDetectionEnginePrivileges } from '../../../detections/components/user_privileges/use_fetch_detection_engine_privileges'; import { getEndpointPrivilegesInitialState, useEndpointPrivileges } from './endpoint'; @@ -19,18 +20,20 @@ export interface UserPrivilegesState { listPrivileges: ReturnType; detectionEnginePrivileges: ReturnType; endpointPrivileges: EndpointPrivileges; - kibanaSecuritySolutionsPrivileges: { crud: boolean; read: boolean }; + siemPrivileges: { crud: boolean; read: boolean }; timelinePrivileges: { crud: boolean; read: boolean }; notesPrivileges: { crud: boolean; read: boolean }; + rulesPrivileges: { read: boolean; edit: boolean }; } export const initialUserPrivilegesState = (): UserPrivilegesState => ({ listPrivileges: { loading: false, error: undefined, result: undefined }, detectionEnginePrivileges: { loading: false, error: undefined, result: undefined }, endpointPrivileges: getEndpointPrivilegesInitialState(), - kibanaSecuritySolutionsPrivileges: { crud: false, read: false }, + siemPrivileges: { crud: false, read: false }, timelinePrivileges: { crud: false, read: false }, notesPrivileges: { crud: false, read: false }, + rulesPrivileges: { read: false, edit: false }, }); export const UserPrivilegesContext = createContext( initialUserPrivilegesState() @@ -48,11 +51,17 @@ export const UserPrivilegesProvider = ({ const crud: boolean = kibanaCapabilities[SECURITY_FEATURE_ID].crud === true; const read: boolean = kibanaCapabilities[SECURITY_FEATURE_ID].show === true; - const listPrivileges = useFetchListPrivileges(read); - const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(read); + const rulesCapabilities = kibanaCapabilities[RULES_FEATURE_ID]; + const readRules = rulesCapabilities?.[RULES_UI_READ] === true; + const editRules = rulesCapabilities?.[RULES_UI_EDIT] === true; + + const shouldFetchListPrivileges = read || readRules; + + const listPrivileges = useFetchListPrivileges(shouldFetchListPrivileges); + const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(); const endpointPrivileges = useEndpointPrivileges(); - const kibanaSecuritySolutionsPrivileges = useMemo( + const siemPrivileges = useMemo( () => ({ crud, read, @@ -70,22 +79,31 @@ export const UserPrivilegesProvider = ({ [kibanaCapabilities] ); + const rulesPrivileges = useMemo(() => { + return { + read: readRules, + edit: editRules, + }; + }, [readRules, editRules]); + const contextValue = useMemo( () => ({ listPrivileges, detectionEnginePrivileges, endpointPrivileges, - kibanaSecuritySolutionsPrivileges, + siemPrivileges, timelinePrivileges, notesPrivileges, + rulesPrivileges, }), [ listPrivileges, detectionEnginePrivileges, endpointPrivileges, - kibanaSecuritySolutionsPrivileges, + siemPrivileges, timelinePrivileges, notesPrivileges, + rulesPrivileges, ] ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx index 6ef2b022f0e77..3c1e91fbda9eb 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx @@ -8,8 +8,8 @@ import { renderHook } from '@testing-library/react'; import { useMissingPrivileges } from './use_missing_privileges'; import { useUserPrivileges } from '../components/user_privileges'; -import { useUserData } from '../../detections/components/user_info'; -import { SECURITY_FEATURE_ID } from '../../../common'; +import { getUserPrivilegesMockDefaultValue } from '../components/user_privileges/__mocks__'; +import { RULES_FEATURE_ID } from '../../../common/constants'; jest.mock('../components/user_privileges'); jest.mock('../../detections/components/user_info'); @@ -32,6 +32,7 @@ const detectionEnginePrivileges = { is_authenticated: true, has_encryption_key: true, }; + const listPrivileges = { is_authenticated: true, lists: { @@ -68,99 +69,106 @@ const listPrivileges = { }, }; +type UseUserPrivilegesReturn = ReturnType; + +const buildUseUserPrivilegesMockReturn = ( + overrides: Partial = {} +): UseUserPrivilegesReturn => ({ + ...getUserPrivilegesMockDefaultValue(), + detectionEnginePrivileges: { + // @ts-expect-error partial mock + result: detectionEnginePrivileges, + }, + listPrivileges: { + // @ts-expect-error partial mock + result: listPrivileges, + }, + ...overrides, +}); + describe('useMissingPrivileges', () => { beforeEach(() => { jest.clearAllMocks(); + + (useUserPrivileges as jest.Mock).mockReturnValue(buildUseUserPrivilegesMockReturn()); }); - it('should return empty arrays if canUserCRUD is null', () => { - (useUserPrivileges as jest.Mock).mockReturnValue({ - detectionEnginePrivileges: { - result: detectionEnginePrivileges, - }, - listPrivileges: { - result: listPrivileges, - }, - }); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: null }]); + it('reports no privileges missing while detectionEnginePrivileges result is null', () => { + (useUserPrivileges as jest.Mock).mockReturnValue( + buildUseUserPrivilegesMockReturn({ + detectionEnginePrivileges: { + // @ts-expect-error partial mock + result: null, + }, + }) + ); const hookResult = renderHook(() => useMissingPrivileges()); - expect(hookResult.result.current).toEqual({ featurePrivileges: [], indexPrivileges: [], }); }); - it('should return empty arrays if detectionEnginePrivileges result is null', () => { - (useUserPrivileges as jest.Mock).mockReturnValue({ - detectionEnginePrivileges: { - result: null, - }, - listPrivileges: { - result: listPrivileges, - }, - }); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: true }]); + it('reports missing rulesPrivileges if user cannot edit rules', () => { + (useUserPrivileges as jest.Mock).mockReturnValue( + buildUseUserPrivilegesMockReturn({ + rulesPrivileges: { edit: false, read: true }, + }) + ); const hookResult = renderHook(() => useMissingPrivileges()); - expect(hookResult.result.current).toEqual({ - featurePrivileges: [], - indexPrivileges: [], - }); + expect(hookResult.result.current).toEqual( + expect.objectContaining({ + featurePrivileges: expect.arrayContaining([[RULES_FEATURE_ID, ['all']]]), + }) + ); }); - it('should return empty arrays if listPrivileges result is null', () => { - (useUserPrivileges as jest.Mock).mockReturnValue({ - detectionEnginePrivileges: { - result: detectionEnginePrivileges, - }, - listPrivileges: { - result: null, - }, - }); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: true }]); + it('reports no privileges missing while listPrivileges result is null', () => { + (useUserPrivileges as jest.Mock).mockReturnValue( + buildUseUserPrivilegesMockReturn({ + listPrivileges: { + // @ts-expect-error partial mock + result: null, + }, + }) + ); const hookResult = renderHook(() => useMissingPrivileges()); - expect(hookResult.result.current).toEqual({ featurePrivileges: [], indexPrivileges: [], }); }); - it('should return featurePrivileges security feature all if user does not have CRUD', () => { - (useUserPrivileges as jest.Mock).mockReturnValue({ - detectionEnginePrivileges: { - result: detectionEnginePrivileges, - }, - listPrivileges: { - result: listPrivileges, - }, - }); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: false }]); - + // TODO this behavior now seems inadequate. What should be reported if user does not have rules:read? Do we ever report `siemv5` feature as missing? + it.skip('reports missing "all" privilege for security if user does not have CRUD', () => { const hookResult = renderHook(() => useMissingPrivileges()); - expect(hookResult.result.current.featurePrivileges).toEqual([[SECURITY_FEATURE_ID, ['all']]]); + expect(hookResult.result.current.featurePrivileges).toEqual( + expect.arrayContaining([RULES_FEATURE_ID, ['all']]) + ); }); - it('should return featurePrivileges and indexPrivileges', () => { - (useUserPrivileges as jest.Mock).mockReturnValue({ - detectionEnginePrivileges: { - result: detectionEnginePrivileges, - }, - listPrivileges: { - result: listPrivileges, - }, - }); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: true }]); + it('reports no missing rule privileges if user can edit rules', () => { + (useUserPrivileges as jest.Mock).mockReturnValue( + buildUseUserPrivilegesMockReturn({ + rulesPrivileges: { edit: true, read: true }, + }) + ); + + const hookResult = renderHook(() => useMissingPrivileges()); + + expect(hookResult.result.current.featurePrivileges).toEqual([]); + }); + it('reports complex index privileges when all data is available', () => { const hookResult = renderHook(() => useMissingPrivileges()); expect(hookResult.result.current).toEqual({ - featurePrivileges: [], + featurePrivileges: [[RULES_FEATURE_ID, ['all']]], indexPrivileges: [ ['.items-default', ['view_index_metadata', 'manage']], ['.lists-default', ['view_index_metadata', 'manage']], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts index f8f24cc67c914..5b2f9f6617996 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts @@ -5,10 +5,9 @@ * 2.0. */ +import { RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; import { useMemo } from 'react'; -import { SECURITY_FEATURE_ID } from '../../../common/constants'; import type { Privilege } from '../../detections/containers/detection_engine/alerts/types'; -import { useUserData } from '../../detections/components/user_info'; import { useUserPrivileges } from '../components/user_privileges'; const REQUIRED_INDEX_PRIVILEGES = ['read', 'write', 'view_index_metadata', 'manage'] as const; @@ -50,17 +49,13 @@ export interface MissingPrivileges { */ export const useMissingPrivileges = (): MissingPrivileges => { const { detectionEnginePrivileges, listPrivileges } = useUserPrivileges(); - const [{ canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; return useMemo(() => { const featurePrivileges: MissingFeaturePrivileges[] = []; const indexPrivileges: MissingIndexPrivileges[] = []; - if ( - canUserCRUD == null || - listPrivileges.result == null || - detectionEnginePrivileges.result == null - ) { + if (listPrivileges.result == null || detectionEnginePrivileges.result == null) { /** * Do not check privileges till we get all the data. That helps to reduce * subsequent layout shift while loading and skip unneeded re-renders. @@ -71,8 +66,8 @@ export const useMissingPrivileges = (): MissingPrivileges => { }; } - if (!canUserCRUD) { - featurePrivileges.push([SECURITY_FEATURE_ID, ['all']]); + if (canEditRules === false) { + featurePrivileges.push([RULES_FEATURE_ID, ['all']]); } const missingItemsPrivileges = getMissingIndexPrivileges(listPrivileges.result.listItems.index); @@ -96,5 +91,5 @@ export const useMissingPrivileges = (): MissingPrivileges => { featurePrivileges, indexPrivileges, }; - }, [canUserCRUD, listPrivileges, detectionEnginePrivileges]); + }, [listPrivileges.result, detectionEnginePrivileges.result, canEditRules]); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts b/x-pack/solutions/security/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts index 72261d61ba7ee..35d46a40ce197 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/lib/kibana/kibana_react.mock.ts @@ -222,6 +222,10 @@ export const createStartServicesMock = ( actions: { show: true, }, + fleet: { + crud: true, + read: true, + }, }, }, security, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.test.ts b/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.test.ts deleted file mode 100644 index 34abe0dd52c9a..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { hasUserCRUDPermission } from '.'; - -describe('privileges utils', () => { - describe('hasUserCRUDPermission', () => { - test("returns true when user's CRUD operations are null", () => { - const result = hasUserCRUDPermission(null); - - expect(result).toBeTruthy(); - }); - - test('returns false when user cannot CRUD', () => { - const result = hasUserCRUDPermission(false); - - expect(result).toBeFalsy(); - }); - - test('returns true when user can CRUD', () => { - const result = hasUserCRUDPermission(true); - - expect(result).toBeTruthy(); - }); - }); -}); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.ts b/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.ts index 91b60c07d3f75..af998e97ebe34 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/privileges/index.ts @@ -28,10 +28,6 @@ export const canEditRuleWithActions = ( return true; }; -// typed as null not undefined as the initial state for this value is null. -export const hasUserCRUDPermission = (canUserCRUD: boolean | null): boolean => - canUserCRUD != null ? canUserCRUD : true; - export const explainLackOfPermission = ( rule: Rule | null | undefined, hasMlPermissions: boolean, @@ -40,7 +36,7 @@ export const explainLackOfPermission = ( | Readonly<{ [x: string]: boolean; }>, - canUserCRUD: boolean | null + canEditRules: boolean ): string | undefined => { if (rule == null) { return undefined; @@ -48,8 +44,8 @@ export const explainLackOfPermission = ( return i18nActions.ML_RULES_DISABLED_MESSAGE; } else if (!canEditRuleWithActions(rule, hasReadActionsPrivileges)) { return i18nActions.LACK_OF_KIBANA_ACTIONS_FEATURE_PRIVILEGES; - } else if (!hasUserCRUDPermission(canUserCRUD)) { - return i18nActions.LACK_OF_KIBANA_SECURITY_PRIVILEGES; + } else if (!canEditRules) { + return i18nActions.LACK_OF_KIBANA_RULES_FEATURE_PRIVILEGES; } else { return undefined; } diff --git a/x-pack/solutions/security/plugins/security_solution/public/configurations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/configurations/links.ts index bf230082f623d..4f4053bafc207 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/configurations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/configurations/links.ts @@ -5,6 +5,10 @@ * 2.0. */ +import { + RULES_UI_READ_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, +} from '@kbn/security-solution-features/constants'; import { ConfigurationTabs } from './constants'; import * as i18n from './translations'; import type { LinkItem } from '..'; @@ -12,7 +16,7 @@ import { CONFIGURATIONS_PATH, SECURITY_FEATURE_ID, SecurityPageName } from '../. import { CONFIGURATIONS } from '../app/translations'; export const configurationsLinks: LinkItem = { - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.configurations`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${SECURITY_FEATURE_ID}.configurations`]], globalNavPosition: 3, globalSearchKeywords: [i18n.CONFIGURATIONS], hideTimeline: true, @@ -34,6 +38,7 @@ export const configurationsLinks: LinkItem = { path: `${CONFIGURATIONS_PATH}/${ConfigurationTabs.basicRules}`, skipUrlState: true, hideTimeline: true, + capabilities: [RULES_UI_READ_PRIVILEGE], }, { id: SecurityPageName.configurationsAiSettings, diff --git a/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx index 6eb4a7caad6a6..fe56f9649c0fc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx @@ -19,7 +19,6 @@ import { import React, { useCallback, useMemo, useState } from 'react'; import type { FindRulesSortField } from '../../../../common/api/detection_engine'; import { Loader } from '../../../common/components/loader'; -import { hasUserCRUDPermission } from '../../../common/utils/privileges'; import type { EuiBasicTableOnChange } from '../../../detection_engine/common/types'; import type { Rule } from '../../../detection_engine/rule_management/logic'; import { useRuleManagementFilters } from '../../../detection_engine/rule_management/logic/use_rule_management_filters'; @@ -34,8 +33,8 @@ import { useEnabledColumn, useRuleExecutionStatusColumn, } from '../../../detection_engine/rule_management_ui/components/rules_table/use_columns'; -import { useUserData } from '../../../detections/components/user_info'; import * as i18n from './translations'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; const INITIAL_SORT_FIELD = 'name'; @@ -177,11 +176,10 @@ interface ColumnsProps { } const useRulesColumns = ({ currentTab }: ColumnsProps): Array> => { - const [{ canUserCRUD }] = useUserData(); - const hasPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const enabledColumn = useEnabledColumn({ - hasCRUDPermissions: hasPermissions, + hasCRUDPermissions: canEditRules, isLoadingJobs: false, mlJobs: [], startMlJobs: async (jobIds: string[] | undefined) => {}, diff --git a/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts b/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts index 7ffb6463f42e5..34718b9eedc75 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts @@ -5,6 +5,7 @@ * 2.0. */ import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { DASHBOARDS_PATH, SecurityPageName, SECURITY_FEATURE_ID } from '../../common/constants'; import { DASHBOARDS } from '../app/translations'; import type { LinkItem } from '../common/links/types'; @@ -31,7 +32,7 @@ export const dashboardsLinks: LinkItem = { title: DASHBOARDS, path: DASHBOARDS_PATH, globalNavPosition: 1, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${SECURITY_FEATURE_ID}.detections`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.dashboards', { defaultMessage: 'Dashboards', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/common/translations.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/common/translations.ts index 1c6105e9016cd..3ac41ef3c95b6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/common/translations.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/common/translations.ts @@ -682,10 +682,10 @@ export const LACK_OF_KIBANA_ACTIONS_FEATURE_PRIVILEGES = i18n.translate( } ); -export const LACK_OF_KIBANA_SECURITY_PRIVILEGES = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaSecurityPrivileges', +export const LACK_OF_KIBANA_RULES_FEATURE_PRIVILEGES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.lackOfKibanaRulesFeaturePrivileges', { - defaultMessage: 'You do not have Kibana Security privileges', + defaultMessage: 'You do not have Kibana Rules privileges', } ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index d11e2b6dc1e08..6496093f9fce1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -29,7 +29,6 @@ import { import { useCreateRule } from '../../../rule_management/logic'; import type { RuleCreateProps } from '../../../../../common/api/detection_engine/model/rule_schema'; import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { getDetectionEngineUrl, @@ -84,6 +83,7 @@ import { extractValidationMessages } from '../../../rule_creation/logic/extract_ import { NextStep } from '../../components/next_step'; import { useRuleForms, useRuleIndexPattern } from '../form'; import { CustomHeaderPageMemo } from '..'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const MyEuiPanel = styled(EuiPanel)<{ zindex?: number; @@ -111,15 +111,9 @@ const MyEuiPanel = styled(EuiPanel)<{ MyEuiPanel.displayName = 'MyEuiPanel'; const CreateRulePageComponent: React.FC = () => { - const [ - { - loading: userInfoLoading, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - canUserCRUD, - }, - ] = useUserData(); + const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = + useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { addSuccess } = useAppToasts(); @@ -812,7 +806,7 @@ const CreateRulePageComponent: React.FC = () => { path: getDetectionEngineUrl(), }); return null; - } else if (!hasUserCRUDPermission(canUserCRUD)) { + } else if (!canEditRules) { navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRulesUrl(), diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index 62bd0d5db1ed3..d87d7b45035c3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -35,7 +35,6 @@ import type { import { useRule, useUpdateRule } from '../../../rule_management/logic'; import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { getDetectionEngineUrl, getRuleDetailsUrl, @@ -75,20 +74,15 @@ import { usePrebuiltRulesCustomizationStatus } from '../../../rule_management/lo import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../../../rule_creation/components/alert_suppression_edit'; import { usePrebuiltRuleCustomizationUpsellingMessage } from '../../../rule_management/logic/prebuilt_rules/use_prebuilt_rule_customization_upselling_message'; import { useRuleUpdateCallout } from '../../../rule_management/hooks/use_rule_update_callout'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { const { addSuccess } = useAppToasts(); - const [ - { - loading: userInfoLoading, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - canUserCRUD, - }, - ] = useUserData(); + const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = + useUserData(); const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { application, triggersActionsUi } = useKibana().services; const { navigateToApp } = application; @@ -519,7 +513,7 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { path: getDetectionEngineUrl(), }); return null; - } else if (!hasUserCRUDPermission(canUserCRUD)) { + } else if (!canEditRules) { navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? ''), diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 97e801f1d49b4..4c464aec3e484 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -108,7 +108,6 @@ import { SourcererScopeName } from '../../../../sourcerer/store/model'; import { canEditRuleWithActions, explainLackOfPermission, - hasUserCRUDPermission, isBoolean, } from '../../../../common/utils/privileges'; @@ -155,6 +154,7 @@ import { useLegacyUrlRedirect } from './use_redirect_legacy_url'; import { RuleDetailTabs, useRuleDetailsTabs } from './use_rule_details_tabs'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { useRuleUpdateCallout } from '../../../rule_management/hooks/use_rule_update_callout'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const RULE_EXCEPTION_LIST_TYPES = [ ExceptionListTypeEnum.DETECTION, @@ -258,13 +258,13 @@ export const RuleDetailsPage = connector( isSignalIndexExists, isAuthenticated, hasEncryptionKey, - canUserCRUD, hasIndexRead, signalIndexName, hasIndexWrite, hasIndexMaintenance, }, ] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); @@ -680,7 +680,7 @@ export const RuleDetailsPage = connector( rule, hasMlPermissions, hasActionsPrivileges, - canUserCRUD + canEditRules )} > @@ -690,7 +690,7 @@ export const RuleDetailsPage = connector( !rule || !isExistingRule || !canEditRuleWithActions(rule, hasActionsPrivileges) || - !hasUserCRUDPermission(canUserCRUD) || + !canEditRules || (isMlRule(rule?.type) && !hasMlPermissions) } enabled={isRuleEnabled} @@ -710,23 +710,21 @@ export const RuleDetailsPage = connector( ruleId={ruleId} disabled={ !isExistingRule || - !hasUserCRUDPermission(canUserCRUD) || + !canEditRules || (isMlRule(rule?.type) && !hasMlPermissions) } disabledReason={explainLackOfPermission( rule, hasMlPermissions, hasActionsPrivileges, - canUserCRUD + canEditRules )} /> { const { services } = useKibana(); const toasts = useToasts(); - const [{ canUserCRUD, hasIndexWrite }] = useUserData(); + const [{ hasIndexWrite }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const exceptionListsToQuery = useMemo( () => rule != null && rule.exceptions_list != null @@ -459,8 +461,8 @@ const ExceptionsViewerComponent = ({ // User privileges checks useEffect((): void => { - setReadOnly(isViewReadOnly || !canUserCRUD || !hasIndexWrite); - }, [setReadOnly, isViewReadOnly, canUserCRUD, hasIndexWrite]); + setReadOnly(isViewReadOnly || !canEditRules || !hasIndexWrite); + }, [setReadOnly, isViewReadOnly, hasIndexWrite, canEditRules]); useEffect(() => { if (exceptionListsToQuery.length > 0) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx index 399692e6cb099..e8ea87a747509 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx @@ -14,16 +14,15 @@ import { BackfillStatusInfo } from './backfill_status'; import { FormattedDate } from '../../../../common/components/formatted_date'; import type { BackfillRow, BackfillStatus } from '../../types'; import * as i18n from '../../translations'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; -import { useUserData } from '../../../../detections/components/user_info'; import { getBackfillRowsFromResponse } from './utils'; import { HeaderSection } from '../../../../common/components/header_section'; import { TableHeaderTooltipCell } from '../../../rule_management_ui/components/rules_table/table_header_tooltip_cell'; import { useKibana } from '../../../../common/lib/kibana'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const DEFAULT_PAGE_SIZE = 10; -const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => { +const getBackfillsTableColumns = (canEditRules: boolean) => { const stopAction = { name: i18n.BACKFILLS_TABLE_COLUMN_ACTION, render: (item: BackfillRow) => , @@ -126,7 +125,7 @@ const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => { }, ]; - if (hasCRUDPermissions) { + if (canEditRules) { columns.push(stopAction); } @@ -136,8 +135,7 @@ const getBackfillsTableColumns = (hasCRUDPermissions: boolean) => { export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) => { const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE); - const [{ canUserCRUD }] = useUserData(); - const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { timelines } = useKibana().services; const { data, isLoading, isError, refetch, dataUpdatedAt } = useFindBackfillsForRules({ ruleIds: [ruleId], @@ -147,7 +145,7 @@ export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) => const backfills: BackfillRow[] = getBackfillRowsFromResponse(data?.data ?? []); - const columns = getBackfillsTableColumns(hasCRUDPermissions); + const columns = getBackfillsTableColumns(canEditRules); const pagination = { pageIndex, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx index 6c3d4c8bc8c80..13419eec26fda 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx @@ -25,8 +25,6 @@ import { EuiSuperDatePicker, EuiTextColor, } from '@elastic/eui'; -import { useUserData } from '../../../../detections/components/user_info'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { HeaderSection } from '../../../../common/components/header_section'; import { TableHeaderTooltipCell } from '../../../rule_management_ui/components/rules_table/table_header_tooltip_cell'; import { FormattedDate } from '../../../../common/components/formatted_date'; @@ -40,6 +38,7 @@ import { useFindGapsForRule } from '../../api/hooks/use_find_gaps_for_rule'; import { FillGap } from './fill_gap'; import { FillRuleGapsButton } from './fill_rule_gaps_button'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const DatePickerEuiFlexItem = styled(EuiFlexItem)` max-width: 582px; @@ -176,14 +175,13 @@ export const RuleGaps = ({ ruleId, enabled }: { ruleId: string; enabled: boolean start: 'now-24h', end: 'now', }); - const [{ canUserCRUD }] = useUserData(); const { timelines } = useKibana().services; - const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const [refreshInterval, setRefreshInterval] = useState(1000); const [isPaused, setIsPaused] = useState(true); const [selectedStatuses, setSelectedStatuses] = useState([]); const isBulkFillRuleGapsEnabled = useIsExperimentalFeatureEnabled('bulkFillRuleGapsEnabled'); - const isFillRuleGapsButtonEnabled = hasCRUDPermissions && isBulkFillRuleGapsEnabled; + const isFillRuleGapsButtonEnabled = canEditRules && isBulkFillRuleGapsEnabled; const [sort, setSort] = useState<{ field: keyof Gap; direction: 'desc' | 'asc' }>({ field: '@timestamp', direction: 'desc', @@ -215,7 +213,7 @@ export const RuleGaps = ({ ruleId, enabled }: { ruleId: string; enabled: boolean totalItemCount: Math.min(totalItemCount, MaxItemCount), }; - const columns = getGapsTableColumns(hasCRUDPermissions, ruleId, enabled); + const columns = getGapsTableColumns(canEditRules, ruleId, enabled); const onRefreshCallback = () => { refetch(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx index 2f48e2ed6f356..139a59c14c8a7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx @@ -7,11 +7,10 @@ import React from 'react'; import type { RuleObjectId } from '../../../../../common/api/detection_engine/model/rule_schema'; -import { useUserData } from '../../../../detections/components/user_info'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { useKibana } from '../../../../common/lib/kibana'; import { useInvalidateFetchRulesSnoozeSettingsQuery } from '../../api/hooks/use_fetch_rules_snooze_settings_query'; import { useRuleSnoozeSettings } from './use_rule_snooze_settings'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; interface RuleSnoozeBadgeProps { /** @@ -27,8 +26,7 @@ export function RuleSnoozeBadge({ }: RuleSnoozeBadgeProps): JSX.Element { const RulesListNotifyBadge = useKibana().services.triggersActionsUi.getRulesListNotifyBadge; const { snoozeSettings, error } = useRuleSnoozeSettings(ruleId); - const [{ canUserCRUD }] = useUserData(); - const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const invalidateFetchRuleSnoozeSettings = useInvalidateFetchRulesSnoozeSettingsQuery(); return ( @@ -36,7 +34,7 @@ export function RuleSnoozeBadge({ ruleId={ruleId} snoozeSettings={snoozeSettings} loading={!snoozeSettings && !error} - disabled={!hasCRUDPermissions || error} + disabled={!canEditRules || error} showTooltipInline={showTooltipInline} onRuleChanged={invalidateFetchRuleSnoozeSettings} /> diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/pre_packaged_rules/load_empty_prompt.tsx index 77513dcdcb39e..7986a93ea1ec0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/pre_packaged_rules/load_empty_prompt.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/pre_packaged_rules/load_empty_prompt.tsx @@ -8,9 +8,9 @@ import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { memo } from 'react'; import styled from 'styled-components'; -import { useUserData } from '../../../../detections/components/user_info'; import { AddElasticRulesButton } from './add_elastic_rules_button'; import * as i18n from './translations'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const EmptyPrompt = styled(EuiEmptyPrompt)` align-self: center; /* Corrects horizontal centering in IE11 */ @@ -19,7 +19,7 @@ const EmptyPrompt = styled(EuiEmptyPrompt)` EmptyPrompt.displayName = 'EmptyPrompt'; const PrePackagedRulesPromptComponent = () => { - const [{ loading, canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; return ( { { const { @@ -32,8 +32,7 @@ export const AddPrebuiltRulesHeaderButtons = () => { }, actions: { installAllRules, installSelectedRules }, } = useAddPrebuiltRulesTableContext(); - const [{ loading: isUserDataLoading, canUserCRUD }] = useUserData(); - const canUserEditRules = canUserCRUD && !isUserDataLoading; + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const numberOfSelectedRules = selectedRules.length ?? 0; const shouldDisplayInstallSelectedRulesButton = numberOfSelectedRules > 0; @@ -75,7 +74,7 @@ export const AddPrebuiltRulesHeaderButtons = () => { {i18n.INSTALL_SELECTED_RULES(numberOfSelectedRules)} @@ -91,7 +90,7 @@ export const AddPrebuiltRulesHeaderButtons = () => { iconType="boxesVertical" aria-label={i18n.INSTALL_RULES_OVERFLOW_BUTTON_ARIA_LABEL} onClick={onOverflowButtonClick} - disabled={!canUserEditRules || isRequestInProgress} + disabled={!canEditRules || isRequestInProgress} /> } isOpen={isOverflowPopoverOpen} @@ -110,7 +109,7 @@ export const AddPrebuiltRulesHeaderButtons = () => { iconType="plusInCircle" data-test-subj="installAllRulesButton" onClick={installAllRules} - disabled={!canUserEditRules || !hasRulesToInstall || isRequestInProgress} + disabled={!canEditRules || !hasRulesToInstall || isRequestInProgress} aria-label={i18n.INSTALL_ALL_ARIA_LABEL} > {i18n.INSTALL_ALL} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx index c1b41e0965e2d..ce219280fb464 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx @@ -10,11 +10,12 @@ import { AddPrebuiltRulesTable } from './add_prebuilt_rules_table'; import { AddPrebuiltRulesHeaderButtons } from './add_prebuilt_rules_header_buttons'; import { AddPrebuiltRulesTableContextProvider } from './add_prebuilt_rules_table_context'; -import { useUserData } from '../../../../../detections/components/user_info'; import { usePrebuiltRulesInstallReview } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_install_review'; import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query'; import { useIsUpgradingSecurityPackages } from '../../../../rule_management/logic/use_upgrade_security_packages'; import { QueryClient, QueryClientProvider } from '@kbn/react-query'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; +import { initialUserPrivilegesState } from '../../../../../common/components/user_privileges/user_privileges_context'; // Mock components not needed in this test suite jest.mock('../../../../rule_management/components/rule_details/rule_details_flyout', () => ({ @@ -96,18 +97,14 @@ jest.mock( }) ); -jest.mock('../../../../../detections/components/user_info', () => ({ - useUserData: jest.fn(), -})); +jest.mock('../../../../../common/components/user_privileges'); describe('AddPrebuiltRulesTable', () => { it('disables `Install all` button if user has no write permissions', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: false, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: false }, + }); render( @@ -125,12 +122,10 @@ describe('AddPrebuiltRulesTable', () => { }); it('disables `Install all` button if prebuilt package is being installed', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: true, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); (useIsUpgradingSecurityPackages as jest.Mock).mockReturnValueOnce(true); @@ -150,12 +145,10 @@ describe('AddPrebuiltRulesTable', () => { }); it('enables Install all` button when user has permissions', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: true, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); render( @@ -173,17 +166,15 @@ describe('AddPrebuiltRulesTable', () => { }); it.each([ - ['Security:Read', true], - ['Security:Write', false], + ['Rule:Read', true], + ['Rule:Write', false], ])( `renders "No rules available for install" when there are no rules to install and user has %s`, - async (_permissions, canUserCRUD) => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD, - }, - ]); + async (_permissions, canEdit) => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: canEdit }, + }); (usePrebuiltRulesInstallReview as jest.Mock).mockReturnValueOnce({ data: { @@ -217,12 +208,10 @@ describe('AddPrebuiltRulesTable', () => { ); it('does not render `Install rule` on rule rows for users with no write permissions', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: false, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: false }, + }); const id = 'rule-1'; (usePrebuiltRulesInstallReview as jest.Mock).mockReturnValueOnce({ @@ -267,12 +256,10 @@ describe('AddPrebuiltRulesTable', () => { }); it('renders `Install rule` on rule rows for users with write permissions', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: true, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); const id = 'rule-1'; (usePrebuiltRulesInstallReview as jest.Mock).mockReturnValueOnce({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx index 0d838abede125..66458f795da19 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx @@ -12,7 +12,6 @@ import React, { createContext, useCallback, useContext, useMemo, useState } from import type { RuleSignatureId } from '../../../../../../common/api/detection_engine'; import type { RuleResponse } from '../../../../../../common/api/detection_engine/model/rule_schema'; import { invariant } from '../../../../../../common/utils/invariant'; -import { useUserData } from '../../../../../detections/components/user_info'; import { useFetchPrebuiltRulesStatusQuery } from '../../../../rule_management/api/hooks/prebuilt_rules/use_fetch_prebuilt_rules_status_query'; import { PERFORM_ALL_RULES_INSTALLATION_KEY } from '../../../../rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation'; import { @@ -26,6 +25,7 @@ import { isUpgradeReviewRequestEnabled } from './add_prebuilt_rules_utils'; import * as i18n from './translations'; import type { AddPrebuiltRulesTableFilterOptions } from './use_filter_prebuilt_rules_to_install'; import { useFilterPrebuiltRulesToInstall } from './use_filter_prebuilt_rules_to_install'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; export interface AddPrebuiltRulesTableState { /** @@ -112,7 +112,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ const [loadingRules, setLoadingRules] = useState([]); const [selectedRules, setSelectedRules] = useState([]); - const [{ loading: userInfoLoading, canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const [filterOptions, setFilterOptions] = useState({ filter: '', @@ -127,6 +127,11 @@ export const AddPrebuiltRulesTableContextProvider = ({ mutationKey: PERFORM_ALL_RULES_INSTALLATION_KEY, }) > 0; + const isUpgradeReviewEnabled = isUpgradeReviewRequestEnabled({ + canEditRules, + isUpgradingSecurityPackages, + prebuiltRulesStatus: prebuiltRulesStatus?.stats, + }); const { data: { rules, stats: { tags } } = { rules: [], @@ -141,11 +146,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ refetchInterval: 60000, // Refetch available rules for installation every minute keepPreviousData: true, // Use this option so that the state doesn't jump between "success" and "loading" on page change // Fetch rules to install only after background installation of security_detection_rules package is complete - enabled: isUpgradeReviewRequestEnabled({ - canUserCRUD, - isUpgradingSecurityPackages, - prebuiltRulesStatus: prebuiltRulesStatus?.stats, - }), + enabled: isUpgradeReviewEnabled, }); const isAnyRuleInstalling = loadingRules.length > 0 || isInstallingAllRules; @@ -213,9 +214,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ (rule: RuleResponse, closeRulePreview: () => void) => { const isPreviewRuleLoading = loadingRules.includes(rule.rule_id); const canPreviewedRuleBeInstalled = - !userInfoLoading && - canUserCRUD && - !(isPreviewRuleLoading || isRefetching || isUpgradingSecurityPackages); + canEditRules && !(isPreviewRuleLoading || isRefetching || isUpgradingSecurityPackages); return ( @@ -247,14 +246,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ ); }, - [ - loadingRules, - userInfoLoading, - canUserCRUD, - isRefetching, - isUpgradingSecurityPackages, - installOneRule, - ] + [loadingRules, canEditRules, isRefetching, isUpgradingSecurityPackages, installOneRule] ); const { rulePreviewFlyout, openRulePreview } = useRulePreviewFlyout({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_utils.ts b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_utils.ts index fa032f1b32f6d..96cd9a1bbcd72 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_utils.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_utils.ts @@ -8,13 +8,13 @@ import type { PrebuiltRulesStatusStats } from '../../../../../../common/api/detection_engine'; interface UpgradeReviewEnabledProps { - canUserCRUD: boolean | null; + canEditRules: boolean | null; isUpgradingSecurityPackages: boolean; prebuiltRulesStatus?: PrebuiltRulesStatusStats; } export const isUpgradeReviewRequestEnabled = ({ - canUserCRUD, + canEditRules, isUpgradingSecurityPackages, prebuiltRulesStatus, }: UpgradeReviewEnabledProps) => { @@ -26,7 +26,7 @@ export const isUpgradeReviewRequestEnabled = ({ // If user is read-only, allow request to proceed even though the Prebuilt // Rules might not be installed. For these users, the Fleet endpoint quickly // fails with 403 so isUpgradingSecurityPackages is false - if (canUserCRUD === false) { + if (canEditRules === false) { return true; } diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx index 7b430ecd93723..c27d94b2d784c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx @@ -16,8 +16,6 @@ import { IntegrationsPopover } from '../../../../common/components/related_integ import { SeverityBadge } from '../../../../../common/components/severity_badge'; import * as i18n from '../../../../common/translations'; import type { Rule } from '../../../../rule_management/logic'; -import { useUserData } from '../../../../../detections/components/user_info'; -import { hasUserCRUDPermission } from '../../../../../common/utils/privileges'; import type { AddPrebuiltRulesTableActions } from './add_prebuilt_rules_table_context'; import { useAddPrebuiltRulesTableContext } from './add_prebuilt_rules_table_context'; import type { @@ -26,6 +24,7 @@ import type { } from '../../../../../../common/api/detection_engine/model/rule_schema'; import { getNormalizedSeverity } from '../helpers'; import { PrebuiltRulesInstallButton } from './add_prebuilt_rules_install_button'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; export type TableColumn = EuiBasicTableColumn; @@ -128,8 +127,7 @@ const createInstallButtonColumn = ( }); export const useAddPrebuiltRulesTableColumns = (): TableColumn[] => { - const [{ canUserCRUD }] = useUserData(); - const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const [showRelatedIntegrations] = useUiSetting$(SHOW_RELATED_INTEGRATIONS_SETTING); const { state: { loadingRules, isRefetching, isUpgradingSecurityPackages, isInstallingAllRules }, @@ -163,10 +161,10 @@ export const useAddPrebuiltRulesTableColumns = (): TableColumn[] => { truncateText: true, width: '12%', }, - ...(hasCRUDPermissions + ...(canEditRules ? [createInstallButtonColumn(installOneRule, loadingRules, isDisabled)] : []), ], - [hasCRUDPermissions, installOneRule, loadingRules, isDisabled, showRelatedIntegrations] + [showRelatedIntegrations, canEditRules, installOneRule, loadingRules, isDisabled] ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx index 2c06037005253..bbd1cf682cf19 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx @@ -27,6 +27,7 @@ import { NEW_FEATURES_TOUR_STORAGE_KEYS } from '../../../../../../common/constan import { useKibana } from '../../../../../common/lib/kibana'; import { useIsElementMounted } from '../rules_table/guided_onboarding/use_is_element_mounted'; import * as i18n from './translations'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; export interface RulesFeatureTourContextType { steps: EuiTourStepProps[]; @@ -76,7 +77,10 @@ export const RuleFeatureTour: FC = () => { }, [tourState, storage]); const isTourAnchorMounted = useIsElementMounted(CREATE_NEW_RULE_TOUR_ANCHOR); - const shouldShowRuleUpgradeTour = isTourAnchorMounted; + const canEditRules = useUserPrivileges().rulesPrivileges.edit; + // Display the tour only if the user has permissions to create/edit rules, + // otherwise they could not follow the tour steps + const shouldShowRuleUpgradeTour = isTourAnchorMounted && canEditRules; const enhancedSteps = useMemo( () => diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx index 0e2fa2c3f1c06..c2b62d8d9457e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx @@ -8,7 +8,6 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { NewChat } from '@kbn/elastic-assistant'; -import { useUserData } from '../../../../detections/components/user_info'; import { TabNavigation } from '../../../../common/components/navigation/tab_navigation'; import { usePrebuiltRulesStatus } from '../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_status'; import { useRuleManagementFilters } from '../../../rule_management/logic/use_rule_management_filters'; @@ -17,6 +16,7 @@ import { getPromptContextFromDetectionRules } from '../../../../assistant/helper import { useRulesTableContext } from './rules_table/rules_table_context'; import { useAssistantAvailability } from '../../../../assistant/use_assistant_availability'; import * as i18nAssistant from '../../../common/translations'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; export enum AllRulesTabs { management = 'management', @@ -28,14 +28,14 @@ export const RulesTableToolbar = React.memo(() => { const { data: ruleManagementFilters } = useRuleManagementFilters(); const { data: prebuiltRulesStatus } = usePrebuiltRulesStatus(); - const [{ loading, canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const installedTotal = (ruleManagementFilters?.rules_summary.custom_count ?? 0) + (ruleManagementFilters?.rules_summary.prebuilt_installed_count ?? 0); const updateTotal = prebuiltRulesStatus?.stats.num_prebuilt_rules_to_upgrade ?? 0; - const shouldDisplayRuleUpdatesTab = !loading && canUserCRUD && updateTotal > 0; + const shouldDisplayRuleUpdatesTab = canEditRules && updateTotal > 0; const ruleTabs = useMemo( () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx index 1d5de8c614236..faab5590007a1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx @@ -33,8 +33,6 @@ import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; import { AllRulesTabs } from './rules_table_toolbar'; import { RulesTableUtilityBar } from '../rules_table_utility_bar/rules_table_utility_bar'; import { useMonitoringColumns, useRulesColumns } from './use_columns'; -import { useUserData } from '../../../../detections/components/user_info'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { useBulkDuplicateExceptionsConfirmation } from './bulk_actions/use_bulk_duplicate_confirmation'; import { BulkActionDuplicateExceptionsConfirmation } from './bulk_actions/bulk_duplicate_exceptions_confirmation'; import { useStartMlJobs } from '../../../rule_management/logic/use_start_ml_jobs'; @@ -52,6 +50,7 @@ import { BulkActionEditTypeEnum } from '../../../../../common/api/detection_engi import { BulkFillRuleGapsModal } from '../../../rule_gaps/components/bulk_fill_rule_gaps'; import { useBulkFillRuleGapsConfirmation } from '../../../rule_gaps/components/bulk_fill_rule_gaps/use_bulk_fill_rule_gaps_confirmation'; import { BulkFillRuleGapsRuleLimitErrorModal } from './bulk_actions/bulk_schedule_gap_fills_rule_limit_error_modal'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const INITIAL_SORT_FIELD = 'enabled'; @@ -75,8 +74,7 @@ const NO_ITEMS_MESSAGE = ( export const RulesTables = React.memo(({ selectedTab }) => { const modalTitleId = useGeneratedHtmlId(); - const [{ canUserCRUD }] = useUserData(); - const hasPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages(); const rulesTableContext = useRulesTableContext(); @@ -199,7 +197,7 @@ export const RulesTables = React.memo(({ selectedTab }) => { const { loading: isLoadingJobs, jobs: mlJobs, startMlJobs } = useStartMlJobs(); const rulesColumns = useRulesColumns({ - hasCRUDPermissions: hasPermissions, + hasCRUDPermissions: canEditRules, isLoadingJobs, mlJobs, startMlJobs, @@ -209,7 +207,7 @@ export const RulesTables = React.memo(({ selectedTab }) => { }); const monitoringColumns = useMonitoringColumns({ - hasCRUDPermissions: hasPermissions, + hasCRUDPermissions: canEditRules, isLoadingJobs, mlJobs, startMlJobs, @@ -221,7 +219,7 @@ export const RulesTables = React.memo(({ selectedTab }) => { const isSelectAllCalled = useRef(false); const isTableSelectable = - hasPermissions && + canEditRules && (selectedTab === AllRulesTabs.management || selectedTab === AllRulesTabs.monitoring); const euiBasicTableSelectionProps = useMemo( @@ -375,7 +373,7 @@ export const RulesTables = React.memo(({ selectedTab }) => { )} 0; @@ -41,7 +40,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ ); const { selectedRulesButtonTooltip, allRulesButtonTooltip } = useBulkUpdateButtonsTooltipContent({ - canUserEditRules, + canUserEditRules: canEditRules, doAllSelectedRulesHaveConflicts, isPrebuiltRulesCustomizationEnabled: isRulesCustomizationEnabled, }); @@ -58,7 +57,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ <> @@ -75,7 +74,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ fill iconType="plusInCircle" onClick={upgradeAllRules} - disabled={!canUserEditRules || !hasRulesToUpgrade || isRequestInProgress} + disabled={!canEditRules || !hasRulesToUpgrade || isRequestInProgress} data-test-subj="upgradeAllRulesButton" > {i18n.UPDATE_ALL} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx index 3c24b60980e27..c405e4763e4d2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx @@ -23,16 +23,15 @@ import { SHOW_RELATED_INTEGRATIONS_SETTING } from '../../../../../../common/cons import type { RuleSignatureId } from '../../../../../../common/api/detection_engine/model/rule_schema'; import { PopoverItems } from '../../../../../common/components/popover_items'; import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; -import { hasUserCRUDPermission } from '../../../../../common/utils/privileges'; import { IntegrationsPopover } from '../../../../common/components/related_integrations/integrations_popover'; import { SeverityBadge } from '../../../../../common/components/severity_badge'; -import { useUserData } from '../../../../../detections/components/user_info'; import * as i18n from '../../../../common/translations'; import type { Rule } from '../../../../rule_management/logic'; import { getNormalizedSeverity } from '../helpers'; import type { UpgradePrebuiltRulesTableActions } from './upgrade_prebuilt_rules_table_context'; import { useUpgradePrebuiltRulesTableContext } from './upgrade_prebuilt_rules_table_context'; import { usePrebuiltRulesCustomizationStatus } from '../../../../rule_management/logic/prebuilt_rules/use_prebuilt_rules_customization_status'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; export type TableColumn = EuiBasicTableColumn; @@ -242,8 +241,7 @@ const createUpgradeButtonColumn = ( }); export const useUpgradePrebuiltRulesTableColumns = (): TableColumn[] => { - const [{ canUserCRUD }] = useUserData(); - const hasCRUDPermissions = hasUserCRUDPermission(canUserCRUD); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const [showRelatedIntegrations] = useUiSetting$(SHOW_RELATED_INTEGRATIONS_SETTING); const { state: { loadingRules, isRefetching, isUpgradingSecurityPackages }, @@ -281,7 +279,7 @@ export const useUpgradePrebuiltRulesTableColumns = (): TableColumn[] => { truncateText: true, width: '10%', }, - ...(hasCRUDPermissions + ...(canEditRules ? [ createUpgradeButtonColumn( upgradeRules, @@ -295,13 +293,13 @@ export const useUpgradePrebuiltRulesTableColumns = (): TableColumn[] => { : []), ], [ + isRulesCustomizationEnabled, showRelatedIntegrations, - hasCRUDPermissions, + canEditRules, upgradeRules, openRulePreview, loadingRules, isDisabled, - isRulesCustomizationEnabled, telemetry, ] ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx index 896a5c64ca9b2..44b1efa3bbcee 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx @@ -13,10 +13,11 @@ import { TestProviders } from '../../../../common/mock'; import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; import { CoverageOverviewMitreTechniquePanelPopover } from './technique_panel_popover'; import { useCoverageOverviewDashboardContext } from './coverage_overview_dashboard_context'; -import { useUserData } from '../../../../detections/components/user_info'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; +import { initialUserPrivilegesState } from '../../../../common/components/user_privileges/user_privileges_context'; jest.mock('./coverage_overview_dashboard_context'); -jest.mock('../../../../detections/components/user_info'); +jest.mock('../../../../common/components/user_privileges'); const mockEnableAllDisabled = jest.fn(); @@ -36,7 +37,10 @@ describe('CoverageOverviewMitreTechniquePanelPopover', () => { state: { showExpandedCells: false, filter: {} }, actions: { enableAllDisabled: mockEnableAllDisabled }, }); - (useUserData as jest.Mock).mockReturnValue([{ loading: false, canUserCRUD: true }]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); }); afterEach(() => { @@ -108,7 +112,10 @@ describe('CoverageOverviewMitreTechniquePanelPopover', () => { }); test('"Enable all disabled" button is disabled when user does not have CRUD permissions', async () => { - (useUserData as jest.Mock).mockReturnValue([{ loading: false, canUserCRUD: false }]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: false }, + }); const wrapper = renderTechniquePanelPopover(); act(() => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx index 9e026e9912b46..2e478ad1f5a7b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx @@ -21,7 +21,6 @@ import { } from '@elastic/eui'; import { css, cx } from '@emotion/css'; import React, { memo, useCallback, useMemo, useState } from 'react'; -import { useUserData } from '../../../../detections/components/user_info'; import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; import { CoverageOverviewRuleListHeader } from './shared_components/popover_list_header'; import { CoverageOverviewMitreTechniquePanel } from './technique_panel'; @@ -29,6 +28,7 @@ import * as i18n from './translations'; import { RuleLink } from '../../components/rules_table/use_columns'; import { useCoverageOverviewDashboardContext } from './coverage_overview_dashboard_context'; import { getNumOfCoveredSubtechniques } from '../../../rule_management/model/coverage_overview/mitre_subtechnique'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; export interface CoverageOverviewMitreTechniquePanelPopoverProps { technique: CoverageOverviewMitreTechnique; @@ -37,19 +37,16 @@ export interface CoverageOverviewMitreTechniquePanelPopoverProps { const CoverageOverviewMitreTechniquePanelPopoverComponent = ({ technique, }: CoverageOverviewMitreTechniquePanelPopoverProps) => { - const [{ loading: userInfoLoading, canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const closePopover = useCallback(() => setIsPopoverOpen(false), []); const isEnableButtonDisabled = useMemo( - () => !canUserCRUD || technique.disabledRules.length === 0, - [canUserCRUD, technique.disabledRules.length] + () => !canEditRules || technique.disabledRules.length === 0, + [canEditRules, technique.disabledRules.length] ); - const isEnableButtonLoading = useMemo( - () => isLoading || userInfoLoading, - [isLoading, userInfoLoading] - ); + const isEnableButtonLoading = isLoading; const { state: { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index 5929d988eb1f8..355e2643a4aa7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -16,7 +16,6 @@ import { getDetectionEngineUrl } from '../../../../common/components/link_to/red import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; import { useBoolState } from '../../../../common/hooks/use_bool_state'; import { useKibana } from '../../../../common/lib/kibana'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { MissingPrivilegesCallOut } from '../../../../common/components/missing_privileges'; import { MlJobCompatibilityCallout } from '../../components/ml_job_compatibility_callout'; @@ -38,6 +37,7 @@ import { CREATE_NEW_RULE_TOUR_ANCHOR, RuleFeatureTour, } from '../../components/rules_table/feature_tour/rules_feature_tour'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; const RulesPageComponent: React.FC = () => { const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState(); @@ -45,15 +45,9 @@ const RulesPageComponent: React.FC = () => { const kibanaServices = useKibana().services; const { navigateToApp } = kibanaServices.application; - const [ - { - loading: userInfoLoading, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - canUserCRUD, - }, - ] = useUserData(); + const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = + useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { loading: listsConfigLoading, canWriteIndex: canWriteListsIndex, @@ -88,7 +82,7 @@ const RulesPageComponent: React.FC = () => { // user still can import value lists, so button should not be disabled if user has enough other privileges const cantCreateNonExistentListIndex = needsListsIndex && !canCreateListsIndex; const isImportValueListDisabled = - cantCreateNonExistentListIndex || !canWriteListsIndex || !canUserCRUD || loading; + cantCreateNonExistentListIndex || !canWriteListsIndex || !canEditRules || loading; return ( <> @@ -106,7 +100,7 @@ const RulesPageComponent: React.FC = () => { - + { {i18n.IMPORT_RULE} @@ -142,7 +136,7 @@ const RulesPageComponent: React.FC = () => { data-test-subj="create-new-rule" fill iconType="plusInCircle" - isDisabled={!hasUserCRUDPermission(canUserCRUD) || loading} + isDisabled={!canEditRules || loading} deepLinkId={SecurityPageName.rulesCreate} > {i18n.ADD_NEW_RULE} diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx index c3557a7cefba3..474056b19c193 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -288,7 +288,7 @@ const AlertsTableComponent: FC> = ({ }, [isEventRenderedView]); const alertColumns = useMemo( - () => (columns.length ? columns : getColumns(license)), + () => (columns?.length ? columns : getColumns(license)), [columns, license] ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx index c780b146310a5..de2e4e18ad594 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx @@ -105,7 +105,7 @@ jest.mock('../../../../common/lib/kibana', () => { }); jest.mock('../../../containers/detection_engine/alerts/use_alerts_privileges', () => ({ - useAlertsPrivileges: jest.fn().mockReturnValue({ hasIndexWrite: true, hasKibanaCRUD: true }), + useAlertsPrivileges: jest.fn().mockReturnValue({ hasIndexWrite: true, hasSiemCRUD: true }), })); const actionMenuButton = 'timeline-context-menu-button'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx index 187e53bb7e1b2..ddbcdc71826b7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx @@ -119,7 +119,7 @@ export const useAddBulkToTimelineAction = ({ const esQueryConfig = useMemo(() => getEsQueryConfig(uiSettings), [uiSettings]); const timelineQuerySortField = useMemo(() => { - return sort.map(({ columnId, columnType, esTypes, sortDirection }) => ({ + return sort?.map(({ columnId, columnType, esTypes, sortDirection }) => ({ field: columnId, direction: sortDirection as Direction, esTypes: esTypes ?? [], diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx index c5478130f5550..19c37ee462796 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx @@ -9,11 +9,15 @@ import { renderHook } from '@testing-library/react'; import { TestProviders } from '../../../../common/mock'; import { useAlertExceptionActions } from './use_add_exception_actions'; import { useUserData } from '../../user_info'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; import { useEndpointExceptionsCapability } from '../../../../exceptions/hooks/use_endpoint_exceptions_capability'; jest.mock('../../user_info'); const mockUseUserData = useUserData as jest.Mock; +jest.mock('../../../../common/components/user_privileges'); +const mockUseUserPrivileges = useUserPrivileges as jest.Mock; + jest.mock('../../../../exceptions/hooks/use_endpoint_exceptions_capability'); const mockUseEndpointExceptionsCapability = useEndpointExceptionsCapability as jest.Mock; @@ -23,7 +27,8 @@ describe('useAlertExceptionActions', () => { }); it('should return both add rule exception and add endpoint exception menu items with all privileges', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: true, hasIndexWrite: true }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -41,7 +46,8 @@ describe('useAlertExceptionActions', () => { }); it('should disable adding endpoint exceptions when user has no endpoint exceptions ALL privilege', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: true, hasIndexWrite: true }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -59,7 +65,8 @@ describe('useAlertExceptionActions', () => { }); it('should disable adding endpoint exceptions when alert is not an endpoint alert', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: true, hasIndexWrite: true }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -78,7 +85,8 @@ describe('useAlertExceptionActions', () => { }); it('should disable adding rule exceptions when user has no security:ALL privilege', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: false, hasIndexWrite: true }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: false } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -96,7 +104,8 @@ describe('useAlertExceptionActions', () => { }); it('should disable adding rule exceptions when user has no index write privilege', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: true, hasIndexWrite: false }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -114,7 +123,8 @@ describe('useAlertExceptionActions', () => { }); it('should not return menu items when user has neither security:ALL nor endpoint exceptions ALL privilege', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: false, hasIndexWrite: true }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: false } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -126,7 +136,8 @@ describe('useAlertExceptionActions', () => { }); it('should not return menu items when user has neither index write and it is not an endpoint alert', () => { - mockUseUserData.mockReturnValue([{ canUserCRUD: true, hasIndexWrite: false }]); + mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx index d630ad2288964..4c28358df6848 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx @@ -12,6 +12,7 @@ import { useEndpointExceptionsCapability } from '../../../../exceptions/hooks/us import { useUserData } from '../../user_info'; import { ACTION_ADD_ENDPOINT_EXCEPTION, ACTION_ADD_EXCEPTION } from '../translations'; import type { AlertTableContextMenuItem } from '../types'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; export interface UseExceptionActionProps { isEndpointAlert: boolean; @@ -22,7 +23,8 @@ export const useAlertExceptionActions = ({ isEndpointAlert, onAddExceptionTypeClick, }: UseExceptionActionProps) => { - const [{ canUserCRUD, hasIndexWrite }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const [{ hasIndexWrite }] = useUserData(); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); const handleDetectionExceptionModal = useCallback(() => { @@ -34,7 +36,7 @@ export const useAlertExceptionActions = ({ }, [onAddExceptionTypeClick]); const disabledAddEndpointException = !canWriteEndpointExceptions || !isEndpointAlert; - const disabledAddException = !canUserCRUD || !hasIndexWrite; + const disabledAddException = !canEditRules || !hasIndexWrite; const exceptionActionItems: AlertTableContextMenuItem[] = useMemo( () => diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/__mocks__/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/__mocks__/index.tsx index efe4cade82b4b..a7dc53b4ce397 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/__mocks__/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/__mocks__/index.tsx @@ -10,8 +10,6 @@ export const initialState = { isSignalIndexExists: true, isAuthenticated: true, hasEncryptionKey: true, - canUserCRUD: true, - canUserREAD: true, hasIndexManage: true, hasIndexMaintenance: true, hasIndexWrite: true, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.test.tsx index af3d69508bc69..7e9249630a89b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.test.tsx @@ -44,8 +44,6 @@ describe('useUserInfo', () => { }); expect(result.current).toEqual({ - canUserCRUD: null, - canUserREAD: null, hasEncryptionKey: null, hasIndexManage: null, hasIndexMaintenance: null, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx index c72eb60f75344..2b0f410de9495 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/user_info/index.tsx @@ -13,8 +13,6 @@ import { useAlertsPrivileges } from '../../containers/detection_engine/alerts/us import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index'; export interface State { - canUserCRUD: boolean | null; - canUserREAD: boolean | null; hasIndexManage: boolean | null; hasIndexMaintenance: boolean | null; hasIndexWrite: boolean | null; @@ -29,8 +27,6 @@ export interface State { } export const initialState: State = { - canUserCRUD: null, - canUserREAD: null, hasIndexManage: null, hasIndexMaintenance: null, hasIndexWrite: null, @@ -85,14 +81,6 @@ export type Action = | { type: 'updateSignalIndexMappingOutdated'; signalIndexMappingOutdated: boolean | null; - } - | { - type: 'updateCanUserCRUD'; - canUserCRUD: boolean | null; - } - | { - type: 'updateCanUserREAD'; - canUserREAD: boolean | null; }; export const userInfoReducer = (state: State, action: Action): State => { @@ -163,18 +151,6 @@ export const userInfoReducer = (state: State, action: Action): State => { signalIndexMappingOutdated: action.signalIndexMappingOutdated, }; } - case 'updateCanUserCRUD': { - return { - ...state, - canUserCRUD: action.canUserCRUD, - }; - } - case 'updateCanUserREAD': { - return { - ...state, - canUserREAD: action.canUserREAD, - }; - } default: return state; } @@ -197,8 +173,6 @@ export const ManageUserInfo = ({ children }: ManageUserInfoProps) => ( export const useUserInfo = (): State => { const [ { - canUserCRUD, - canUserREAD, hasIndexManage, hasIndexMaintenance, hasIndexWrite, @@ -222,8 +196,6 @@ export const useUserInfo = (): State => { hasIndexUpdateDelete: hasApiIndexUpdateDelete, hasIndexWrite: hasApiIndexWrite, hasIndexRead: hasApiIndexRead, - hasKibanaCRUD, - hasKibanaREAD, } = useAlertsPrivileges(); const { loading: indexNameLoading, @@ -233,18 +205,6 @@ export const useUserInfo = (): State => { createDeSignalIndex: createSignalIndex, } = useSignalIndex(); - useEffect(() => { - if (!loading && canUserCRUD !== hasKibanaCRUD) { - dispatch({ type: 'updateCanUserCRUD', canUserCRUD: hasKibanaCRUD }); - } - }, [dispatch, loading, canUserCRUD, hasKibanaCRUD]); - - useEffect(() => { - if (!loading && canUserREAD !== hasKibanaREAD) { - dispatch({ type: 'updateCanUserREAD', canUserREAD: hasKibanaREAD }); - } - }, [dispatch, loading, canUserREAD, hasKibanaREAD]); - useEffect(() => { if (loading !== (privilegeLoading || indexNameLoading)) { dispatch({ type: 'updateLoading', loading: privilegeLoading || indexNameLoading }); @@ -359,8 +319,6 @@ export const useUserInfo = (): State => { isSignalIndexExists, isAuthenticated, hasEncryptionKey, - canUserCRUD, - canUserREAD, hasIndexManage, hasIndexMaintenance, hasIndexWrite, @@ -370,8 +328,6 @@ export const useUserInfo = (): State => { signalIndexMappingOutdated, }), [ - canUserCRUD, - canUserREAD, hasEncryptionKey, hasIndexMaintenance, hasIndexManage, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx index 667585c5f4e56..263edb0377c7e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx @@ -75,9 +75,10 @@ const userPrivilegesInitial: ReturnType = { canAccessEndpointManagement: false, canAccessFleet: false, }), - kibanaSecuritySolutionsPrivileges: { crud: true, read: true }, + siemPrivileges: { crud: true, read: true }, timelinePrivileges: { crud: true, read: true }, notesPrivileges: { crud: true, read: true }, + rulesPrivileges: { edit: true, read: true }, }; describe('useAlertsPrivileges', () => { @@ -100,8 +101,8 @@ describe('useAlertsPrivileges', () => { hasIndexMaintenance: null, hasIndexWrite: null, hasIndexUpdateDelete: null, - hasKibanaCRUD: false, - hasKibanaREAD: false, + hasSiemCRUD: false, + hasSiemRead: false, isAuthenticated: null, loading: false, }) @@ -122,8 +123,8 @@ describe('useAlertsPrivileges', () => { hasIndexRead: false, hasIndexWrite: false, hasIndexUpdateDelete: false, - hasKibanaCRUD: true, - hasKibanaREAD: true, + hasSiemCRUD: true, + hasSiemRead: true, isAuthenticated: false, loading: false, }) @@ -148,8 +149,8 @@ describe('useAlertsPrivileges', () => { hasIndexRead: true, hasIndexWrite: true, hasIndexUpdateDelete: true, - hasKibanaCRUD: true, - hasKibanaREAD: true, + hasSiemCRUD: true, + hasSiemRead: true, isAuthenticated: true, loading: false, }) @@ -171,18 +172,18 @@ describe('useAlertsPrivileges', () => { hasIndexRead: true, hasIndexWrite: true, hasIndexUpdateDelete: true, - hasKibanaCRUD: true, - hasKibanaREAD: true, + hasSiemCRUD: true, + hasSiemRead: true, isAuthenticated: true, loading: false, }) ); }); - test('returns "hasKibanaCRUD" as false if user does not have SIEM Kibana "all" privileges', async () => { + test('returns "hasSiemCRUD" as false if user does not have SIEM Kibana "all" privileges', async () => { const userPrivileges = produce(userPrivilegesInitial, (draft) => { draft.detectionEnginePrivileges.result = privilege; - draft.kibanaSecuritySolutionsPrivileges = { crud: false, read: true }; + draft.siemPrivileges = { crud: false, read: true }; }); useUserPrivilegesMock.mockReturnValue(userPrivileges); @@ -195,18 +196,18 @@ describe('useAlertsPrivileges', () => { hasIndexRead: true, hasIndexWrite: true, hasIndexUpdateDelete: true, - hasKibanaCRUD: false, - hasKibanaREAD: true, + hasSiemCRUD: false, + hasSiemRead: true, isAuthenticated: true, loading: false, }) ); }); - test('returns "hasKibanaREAD" as false if user does not have at least SIEM Kibana "read" privileges', async () => { + test('returns "hasSiemRead" as false if user does not have at least SIEM Kibana "read" privileges', async () => { const userPrivileges = produce(userPrivilegesInitial, (draft) => { draft.detectionEnginePrivileges.result = privilege; - draft.kibanaSecuritySolutionsPrivileges = { crud: false, read: false }; + draft.siemPrivileges = { crud: false, read: false }; }); useUserPrivilegesMock.mockReturnValue(userPrivileges); @@ -219,8 +220,8 @@ describe('useAlertsPrivileges', () => { hasIndexRead: true, hasIndexWrite: true, hasIndexUpdateDelete: true, - hasKibanaCRUD: false, - hasKibanaREAD: false, + hasSiemCRUD: false, + hasSiemRead: false, isAuthenticated: true, loading: false, }) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.tsx index 85105640f0817..b21bf63fe87cd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.tsx @@ -20,8 +20,8 @@ export interface AlertsPrivelegesState { hasIndexUpdateDelete: boolean | null; hasIndexMaintenance: boolean | null; hasIndexRead: boolean | null; - hasKibanaCRUD: boolean; - hasKibanaREAD: boolean; + hasSiemCRUD: boolean; + hasSiemRead: boolean; } /** * Hook to get user privilege from @@ -30,7 +30,7 @@ export interface AlertsPrivelegesState { export const useAlertsPrivileges = (): UseAlertsPrivelegesReturn => { const { detectionEnginePrivileges: { error, result, loading }, - kibanaSecuritySolutionsPrivileges: { crud: hasKibanaCRUD, read: hasKibanaREAD }, + siemPrivileges: { crud: hasSiemCRUD, read: hasSiemRead }, } = useUserPrivileges(); const indexName = useMemo(() => { @@ -50,8 +50,8 @@ export const useAlertsPrivileges = (): UseAlertsPrivelegesReturn => { hasIndexWrite: false, hasIndexUpdateDelete: false, hasIndexMaintenance: false, - hasKibanaCRUD, - hasKibanaREAD, + hasSiemCRUD, + hasSiemRead, }; } @@ -68,8 +68,8 @@ export const useAlertsPrivileges = (): UseAlertsPrivelegesReturn => { result.index[indexName].index || result.index[indexName].write, hasIndexUpdateDelete: result.index[indexName].write, - hasKibanaCRUD, - hasKibanaREAD, + hasSiemCRUD, + hasSiemRead, }; } @@ -81,10 +81,10 @@ export const useAlertsPrivileges = (): UseAlertsPrivelegesReturn => { hasIndexWrite: null, hasIndexUpdateDelete: null, hasIndexMaintenance: null, - hasKibanaCRUD: false, - hasKibanaREAD: false, + hasSiemCRUD: false, + hasSiemRead: false, }; - }, [error, result, indexName, hasKibanaCRUD, hasKibanaREAD]); + }, [error, result, indexName, hasSiemCRUD, hasSiemRead]); return { loading: loading ?? false, ...privileges }; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx index 83b518a904a7b..d95974439ac2a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx @@ -57,7 +57,7 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { canWriteIndex: null, }); - const { listPrivileges, kibanaSecuritySolutionsPrivileges } = useUserPrivileges(); + const { listPrivileges, siemPrivileges } = useUserPrivileges(); // handleReadResult useEffect(() => { @@ -72,16 +72,16 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { isAuthenticated, canReadIndex: canReadIndex(listsPrivileges) && canReadIndex(listItemsPrivileges), canManageIndex: - kibanaSecuritySolutionsPrivileges.crud && + siemPrivileges.crud && canManageIndex(listsPrivileges) && canManageIndex(listItemsPrivileges), canWriteIndex: - kibanaSecuritySolutionsPrivileges.crud && + siemPrivileges.crud && canWriteIndex(listsPrivileges) && canWriteIndex(listItemsPrivileges), }); } - }, [listPrivileges.result, kibanaSecuritySolutionsPrivileges.crud]); + }, [listPrivileges.result, siemPrivileges.crud]); // handleReadError useEffect(() => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts index 1e00e863f3db1..903f4e164bfbb 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts @@ -7,16 +7,16 @@ import { i18n } from '@kbn/i18n'; import { - ALERT_SUMMARY_PATH, - ALERTS_PATH, - SECURITY_FEATURE_ID, - SecurityPageName, -} from '../../common/constants'; + RULES_UI_DETECTIONS_PRIVILEGE, + RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE, + RULES_UI_READ_PRIVILEGE, +} from '@kbn/security-solution-features/constants'; +import { ALERT_SUMMARY_PATH, ALERTS_PATH, SecurityPageName } from '../../common/constants'; import { ALERT_SUMMARY, ALERTS } from '../app/translations'; import type { LinkItem } from '../common/links/types'; export const alertsLink: LinkItem = { - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, RULES_UI_DETECTIONS_PRIVILEGE]], globalNavPosition: 3, globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.alerts', { @@ -29,7 +29,7 @@ export const alertsLink: LinkItem = { }; export const alertSummaryLink: LinkItem = { - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.external_detections`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE]], globalNavPosition: 3, globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.alertSummary', { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx index 099028d34ffa6..ca068a9397376 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { ALERTS_PAGE_LOADING_TEST_ID, AlertsPage } from './alerts'; import { useUserData } from '../../components/user_info'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { useListsConfig } from '../../containers/detection_engine/lists/use_lists_config'; import { useSignalHelpers } from '../../../sourcerer/containers/use_signal_helpers'; import { TestProviders } from '../../../common/mock'; @@ -19,6 +20,7 @@ import { NEED_ADMIN_CALLOUT_TEST_ID } from '../../../detection_engine/rule_manag import { useMissingPrivileges } from '../../../common/hooks/use_missing_privileges'; jest.mock('../../components/user_info'); +jest.mock('../../../common/components/user_privileges'); jest.mock('../../containers/detection_engine/lists/use_lists_config'); jest.mock('../../../sourcerer/containers/use_signal_helpers'); jest.mock('../../../common/hooks/use_missing_privileges'); @@ -26,9 +28,19 @@ jest.mock('../../components/alerts/wrapper', () => ({ Wrapper: () =>
, })); +const doMockRulesPrivileges = ({ read = false }) => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + rulesPrivileges: { + read, + edit: false, + }, + }); +}; + describe('', () => { beforeEach(() => { jest.clearAllMocks(); + doMockRulesPrivileges({}); }); describe('showing loading spinner', () => { @@ -123,11 +135,11 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: true, hasIndexRead: true, hasEncryptionKey: false, }, ]); + doMockRulesPrivileges({ read: true }); (useListsConfig as jest.Mock).mockReturnValue({ loading: false, needsConfiguration: false, @@ -155,12 +167,12 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: true, hasIndexRead: true, signalIndexMappingOutdated: true, hasIndexManage: false, }, ]); + doMockRulesPrivileges({ read: true }); (useListsConfig as jest.Mock).mockReturnValue({ loading: false, needsConfiguration: false, @@ -188,10 +200,10 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: true, hasIndexRead: true, }, ]); + doMockRulesPrivileges({ read: true }); (useListsConfig as jest.Mock).mockReturnValue({ loading: false, needsConfiguration: false, @@ -221,7 +233,6 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: false, hasIndexRead: false, }, ]); @@ -253,10 +264,10 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: true, hasIndexRead: true, }, ]); + doMockRulesPrivileges({ read: true }); (useListsConfig as jest.Mock).mockReturnValue({ loading: false, needsConfiguration: false, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx index 63db499ea6990..8fd6acbd9e20c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx @@ -21,6 +21,7 @@ import { NeedAdminForUpdateRulesCallOut } from '../../../detection_engine/rule_m import { MissingPrivilegesCallOut } from '../../../common/components/missing_privileges'; import { NoPrivileges } from '../../../common/components/no_privileges'; import { HeaderPage } from '../../../common/components/header_page'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; export const ALERTS_PAGE_LOADING_TEST_ID = 'alerts-page-loading'; @@ -29,7 +30,8 @@ export const ALERTS_PAGE_LOADING_TEST_ID = 'alerts-page-loading'; * the actual content of the alerts page is rendered */ export const AlertsPage = memo(() => { - const [{ loading: userInfoLoading, isAuthenticated, canUserREAD, hasIndexRead }] = useUserData(); + const [{ loading: userInfoLoading, isAuthenticated, hasIndexRead }] = useUserData(); + const canReadAlerts = useUserPrivileges().rulesPrivileges.read; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { signalIndexNeedsInit } = useSignalHelpers(); @@ -47,8 +49,8 @@ export const AlertsPage = memo(() => { [needsListsConfiguration, signalIndexNeedsInit] ); const privilegesRequired: boolean = useMemo( - () => !signalIndexNeedsInit && (hasIndexRead === false || canUserREAD === false), - [canUserREAD, hasIndexRead, signalIndexNeedsInit] + () => !signalIndexNeedsInit && (hasIndexRead === false || canReadAlerts === false), + [canReadAlerts, hasIndexRead, signalIndexNeedsInit] ); if (loading) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts index ba064e1d57e0e..0641e85c5ce0e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts @@ -29,6 +29,7 @@ import { import { checkIfListCannotBeEdited, isAnExceptionListItem } from '../../utils/list.utils'; import * as i18n from '../../translations'; import { useInvalidateFetchRuleByIdQuery } from '../../../detection_engine/rule_management/api/hooks/use_fetch_rule_by_id_query'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { useEndpointExceptionsCapability } from '../use_endpoint_exceptions_capability'; interface ReferenceModalState { @@ -54,13 +55,14 @@ export const useListDetailsView = (exceptionListId: string) => { const { navigateToApp } = services.application; const { exportExceptionList, deleteExceptionList, duplicateExceptionList } = useApi(http); + const { read: canReadRules, edit: canEditRules } = useUserPrivileges().rulesPrivileges; - const [{ loading: userInfoLoading, canUserCRUD }] = useUserData(); + const [{ loading: userInfoLoading }] = useUserData(); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); const canUserWriteCurrentList = exceptionListId === ENDPOINT_ARTIFACT_LISTS.endpointExceptions.id ? canWriteEndpointExceptions - : canUserCRUD; + : canEditRules; const [isLoading, setIsLoading] = useState(); const [showManageButtonLoader, setShowManageButtonLoader] = useState(false); @@ -411,7 +413,7 @@ export const useListDetailsView = (exceptionListId: string) => { return { isLoading: isLoading || userInfoLoading, invalidListId, - isReadOnly: !canUserWriteCurrentList, + isReadOnly: !!(!canUserWriteCurrentList && canReadRules), list, listName: list?.name, listDescription: list?.description, diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx index 28e702e6425cf..0b9d71e243c8e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx @@ -47,13 +47,13 @@ import { ReferenceErrorModal } from '../../../common/components/reference_error_ import { patchRule } from '../../../detection_engine/rule_management/api/api'; import { getSearchFilters } from '../../../detection_engine/rule_management_ui/components/rules_table/helpers'; -import { useUserData } from '../../../detections/components/user_info'; import { useListsConfig } from '../../../detections/containers/detection_engine/lists/use_lists_config'; import { MissingPrivilegesCallOut } from '../../../common/components/missing_privileges'; import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../../../common/endpoint/service/artifacts/constants'; import { AddExceptionFlyout } from '../../../detection_engine/rule_exceptions/components/add_exception_flyout'; import { useEndpointExceptionsCapability } from '../../hooks/use_endpoint_exceptions_capability'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; export type Func = () => Promise; @@ -86,10 +86,10 @@ const ExceptionsTable = styled(EuiFlexGroup)` `; export const SharedLists = React.memo(() => { - const [{ loading: userInfoLoading, canUserCRUD, canUserREAD }] = useUserData(); + const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges; const { loading: listsConfigLoading } = useListsConfig(); - const loading = userInfoLoading || listsConfigLoading; + const loading = listsConfigLoading; const canAccessEndpointExceptions = useEndpointExceptionsCapability('showEndpointExceptions'); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); @@ -445,9 +445,7 @@ export const SharedLists = React.memo(() => { }; const onCreateExceptionListOpenClick = () => setDisplayCreateSharedListFlyout(true); - const isReadOnly = useMemo(() => { - return (canUserREAD && !canUserCRUD) ?? true; - }, [canUserREAD, canUserCRUD]); + const isReadOnly = canReadRules && !canEditRules; useEffect(() => { if (isSearchingExceptions && hasNoExceptions) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx index 88ada09653b8d..d44de617cd579 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { TestProviders } from '../../../common/mock'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; -import { useUserData } from '../../../detections/components/user_info'; import { SharedLists } from '.'; import { useApi, useExceptionLists } from '@kbn/securitysolution-list-hooks'; @@ -17,9 +16,11 @@ import { useAllExceptionLists } from '../../hooks/use_all_exception_lists'; import { useHistory } from 'react-router-dom'; import { generateHistoryMock } from '../../../common/utils/route/mocks'; import { fireEvent, render, waitFor } from '@testing-library/react'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; +import { initialUserPrivilegesState } from '../../../common/components/user_privileges/user_privileges_context'; import { useEndpointExceptionsCapability } from '../../hooks/use_endpoint_exceptions_capability'; -jest.mock('../../../detections/components/user_info'); +jest.mock('../../../common/components/user_privileges'); jest.mock('../../../common/utils/route/mocks'); jest.mock('../../hooks/use_all_exception_lists'); jest.mock('@kbn/securitysolution-list-hooks'); @@ -89,13 +90,9 @@ describe('SharedLists', () => { }, ]); - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: false, - canUserREAD: false, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + }); (useEndpointExceptionsCapability as jest.Mock).mockReturnValue(true); }); @@ -232,13 +229,10 @@ describe('SharedLists', () => { }); it('renders overflow card button as disabled if user is read only', async () => { - (useUserData as jest.Mock).mockReturnValue([ - { - loading: false, - canUserCRUD: false, - canUserREAD: true, - }, - ]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: false }, + }); const wrapper = render( diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/pages/details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/pages/details/index.tsx index 73d8effd822e8..50ea93b83b5f8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/pages/details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/hosts/pages/details/index.tsx @@ -189,7 +189,7 @@ const HostDetailsComponent: React.FC = ({ detailName, hostDeta dispatch(setHostDetailsTablesActivePageToZero()); }, [dispatch, detailName]); - const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const { hasSiemRead: hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); const canReadAlerts = hasKibanaREAD && hasIndexRead; const entityFilter = useMemo( diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts b/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts index 74cb9b2b10939..9476a8c0c3e34 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { HOSTS_PATH, NETWORK_PATH, @@ -34,7 +35,7 @@ const networkLinks: LinkItem = { defaultMessage: 'Network', }), ], - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [SECURITY_UI_SHOW_PRIVILEGE], links: [ { id: SecurityPageName.networkFlows, @@ -97,7 +98,7 @@ const usersLinks: LinkItem = { defaultMessage: 'Users', }), ], - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [SECURITY_UI_SHOW_PRIVILEGE], links: [ { id: SecurityPageName.usersAll, @@ -152,7 +153,7 @@ const hostsLinks: LinkItem = { defaultMessage: 'Hosts', }), ], - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [SECURITY_UI_SHOW_PRIVILEGE], links: [ { id: SecurityPageName.hostsAll, @@ -209,7 +210,7 @@ export const exploreLinks: LinkItem = { title: EXPLORE, path: EXPLORE_PATH, globalNavPosition: 8, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${SECURITY_FEATURE_ID}.detections`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.explore', { defaultMessage: 'Explore', diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/network/pages/details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/network/pages/details/index.tsx index 66782b07e8332..827ba45d1316b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/network/pages/details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/network/pages/details/index.tsx @@ -83,7 +83,7 @@ const NetworkDetailsComponent: React.FC = () => { ); const { signalIndexName } = useSignalIndex(); - const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const { hasSiemRead: hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); const canReadAlerts = hasKibanaREAD && hasIndexRead; const query = useDeepEqualSelector(getGlobalQuerySelector); diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/users/pages/details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/users/pages/details/index.tsx index 21e531d6f4cdc..ca874b47337be 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/explore/users/pages/details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/explore/users/pages/details/index.tsx @@ -95,7 +95,7 @@ const UsersDetailsComponent: React.FC = ({ const globalFilters = useDeepEqualSelector(getGlobalFiltersQuerySelector); const { signalIndexName } = useSignalIndex(); - const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const { hasSiemRead: hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); const canReadAlerts = hasKibanaREAD && hasIndexRead; const { to, from, deleteQuery, setQuery, isInitializing } = useGlobalTime(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx index e9161ba909ec6..f5f3b13c0be08 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/right/components/status_popover_button.test.tsx @@ -52,11 +52,11 @@ const props = { type AlertsPriveleges = Partial>; -const writePriveleges: AlertsPriveleges = { hasIndexWrite: true, hasKibanaCRUD: true }; +const writePriveleges: AlertsPriveleges = { hasIndexWrite: true, hasSiemCRUD: true }; const readPriveleges: AlertsPriveleges = { hasIndexWrite: false, - hasKibanaCRUD: false, - hasKibanaREAD: true, + hasSiemCRUD: false, + hasSiemRead: true, hasIndexRead: true, }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index 8baf348af1e24..d0881c462065a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -38,7 +38,7 @@ jest.mock('../../../../common/components/user_privileges'); jest.mock('../../../../exceptions/hooks/use_endpoint_exceptions_capability'); jest.mock('../../../../detections/components/user_info', () => ({ - useUserData: jest.fn().mockReturnValue([{ canUserCRUD: true, hasIndexWrite: true }]), + useUserData: jest.fn().mockReturnValue([{ hasIndexWrite: true }]), })); jest.mock('../../../../common/lib/kibana'); @@ -46,7 +46,7 @@ jest.mock('../../../../common/lib/kibana'); jest.mock( '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges', () => ({ - useAlertsPrivileges: jest.fn().mockReturnValue({ hasIndexWrite: true, hasKibanaCRUD: true }), + useAlertsPrivileges: jest.fn().mockReturnValue({ hasIndexWrite: true, hasSiemCRUD: true }), }) ); jest.mock('../../../../cases/components/use_insert_timeline'); @@ -157,6 +157,7 @@ describe('take action dropdown', () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...getUserPrivilegesMockDefaultValue(), timelinePrivileges: { read: true }, + rulesPrivileges: { read: true, edit: true }, }); wrapper = mount( diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx index bfa299a6e19ab..c99bdd13f1b4d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx @@ -13,10 +13,11 @@ import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_lice import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; import type { RuleResponse } from '../../../../../common/api/detection_engine'; import { - LACK_OF_KIBANA_SECURITY_PRIVILEGES, + LACK_OF_KIBANA_RULES_FEATURE_PRIVILEGES, ML_RULES_DISABLED_MESSAGE, } from '../../../../detection_engine/common/translations'; -import { useUserData } from '../../../../detections/components/user_info'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; +import { getUserPrivilegesMockDefaultValue } from '../../../../common/components/user_privileges/__mocks__'; jest.mock('../../../../common/components/ml/hooks/use_ml_capabilities'); jest.mock( @@ -25,6 +26,7 @@ jest.mock( jest.mock('../../../../../common/machine_learning/has_ml_license'); jest.mock('../../../../../common/machine_learning/has_ml_admin_permissions'); jest.mock('../../../../detections/components/user_info'); +jest.mock('../../../../common/components/user_privileges'); const defaultProps = { rule: {} as RuleResponse, @@ -37,7 +39,10 @@ const renderUseHighlightedFieldsPrivilege = (props: UseHighlightedFieldsPrivileg describe('useHighlightedFieldsPrivilege', () => { beforeEach(() => { jest.clearAllMocks(); - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: true }]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...getUserPrivilegesMockDefaultValue(), + rulesPrivileges: { read: true, edit: true }, + }); (hasMlAdminPermissions as jest.Mock).mockReturnValue(false); (hasMlLicense as jest.Mock).mockReturnValue(false); (usePrebuiltRuleCustomizationUpsellingMessage as jest.Mock).mockReturnValue(undefined); @@ -64,10 +69,13 @@ describe('useHighlightedFieldsPrivilege', () => { }); it('should return isDisabled as true when user does not have CRUD privileges', () => { - (useUserData as jest.Mock).mockReturnValue([{ canUserCRUD: false }]); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...getUserPrivilegesMockDefaultValue(), + rulesPrivileges: { read: true, edit: false }, + }); const { result } = renderUseHighlightedFieldsPrivilege(defaultProps); expect(result.current.isDisabled).toBe(true); - expect(result.current.tooltipContent).toContain(LACK_OF_KIBANA_SECURITY_PRIVILEGES); + expect(result.current.tooltipContent).toContain(LACK_OF_KIBANA_RULES_FEATURE_PRIVILEGES); }); describe('when rule is machine learning rule', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx index 1f9422c8da7ec..d9d73d47edef1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx @@ -5,19 +5,16 @@ * 2.0. */ -import { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; -import { usePrebuiltRuleCustomizationUpsellingMessage } from '../../../../detection_engine/rule_management/logic/prebuilt_rules/use_prebuilt_rule_customization_upselling_message'; -import { - explainLackOfPermission, - hasUserCRUDPermission, -} from '../../../../common/utils/privileges'; -import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { useMemo } from 'react'; +import type { RuleResponse } from '../../../../../common/api/detection_engine'; import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; -import { useUserData } from '../../../../detections/components/user_info'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; import { isMlRule } from '../../../../../common/machine_learning/helpers'; -import type { RuleResponse } from '../../../../../common/api/detection_engine'; +import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; +import { explainLackOfPermission } from '../../../../common/utils/privileges'; +import { usePrebuiltRuleCustomizationUpsellingMessage } from '../../../../detection_engine/rule_management/logic/prebuilt_rules/use_prebuilt_rule_customization_upselling_message'; export interface UseHighlightedFieldsPrivilegeParams { /** @@ -48,15 +45,12 @@ export const useHighlightedFieldsPrivilege = ({ rule, isExistingRule, }: UseHighlightedFieldsPrivilegeParams): UseHighlightedFieldsPrivilegeResult => { - const [{ canUserCRUD }] = useUserData(); + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const mlCapabilities = useMlCapabilities(); const hasMlPermissions = hasMlLicense(mlCapabilities) && hasMlAdminPermissions(mlCapabilities); const isEditRuleDisabled = - !rule || - !isExistingRule || - !hasUserCRUDPermission(canUserCRUD) || - (isMlRule(rule?.type) && !hasMlPermissions); + !rule || !isExistingRule || !canEditRules || (isMlRule(rule?.type) && !hasMlPermissions); const upsellingMessage = usePrebuiltRuleCustomizationUpsellingMessage( 'prebuilt_rule_customization' @@ -69,7 +63,7 @@ export const useHighlightedFieldsPrivilege = ({ rule, hasMlPermissions, true, // default true because we don't need the message for lack of action privileges - canUserCRUD + canEditRules ); if (isEditRuleDisabled && explanation) { @@ -94,7 +88,7 @@ export const useHighlightedFieldsPrivilege = ({ 'xpack.securitySolution.flyout.right.investigation.highlightedFields.editHighlightedFieldsButtonTooltip', { defaultMessage: 'Edit highlighted fields' } ); - }, [canUserCRUD, hasMlPermissions, isEditRuleDisabled, isExistingRule, rule, upsellingMessage]); + }, [canEditRules, hasMlPermissions, isEditRuleDisabled, isExistingRule, rule, upsellingMessage]); return useMemo( () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts b/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts index 3141578680a20..c46a531d9e63e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts @@ -5,15 +5,21 @@ * 2.0. */ import type { Capabilities } from '@kbn/core/public'; +import { RULES_UI_READ } from '@kbn/security-solution-features/constants'; import { SECURITY_FEATURE_ID, CASES_FEATURE_ID } from '../common/constants'; export function hasAccessToSecuritySolution(capabilities: Capabilities): boolean { return Boolean( capabilities[SECURITY_FEATURE_ID]?.show || - capabilities.securitySolutionAttackDiscovery?.['attack-discovery'] + capabilities.securitySolutionAttackDiscovery?.['attack-discovery'] || + hasAccessToRules(capabilities) ); } +export function hasAccessToRules(capabilities: Capabilities): boolean { + return Boolean(capabilities.securitySolutionRulesV1?.[RULES_UI_READ]); +} + export function hasAccessToCases(capabilities: Capabilities): boolean { return Boolean(capabilities[CASES_FEATURE_ID]?.read_cases); } diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/common/constants.ts index 2855db950522b..76019dbba9e09 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/common/constants.ts @@ -31,9 +31,10 @@ export const SIEM_VERSIONS = [ 'siem', 'siemV2', 'siemV3', + 'siemV4', // actual version, should equal to SECURITY_FEATURE_ID - 'siemV4', + 'siemV5', ] as const; export type SiemVersion = (typeof SIEM_VERSIONS)[number]; diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/links.ts b/x-pack/solutions/security/plugins/security_solution/public/management/links.ts index fcffe1c2357e5..33e323971ad95 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/links.ts @@ -8,6 +8,7 @@ import type { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { checkArtifactHasData } from './services/exceptions_list/check_artifact_has_data'; import { calculateEndpointAuthz, @@ -100,7 +101,7 @@ export const links: LinkItem = { skipUrlState: true, hideTimeline: true, globalNavPosition: 12, - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [SECURITY_UI_SHOW_PRIVILEGE], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.manage', { defaultMessage: 'Manage', diff --git a/x-pack/solutions/security/plugins/security_solution/public/notes/links.ts b/x-pack/solutions/security/plugins/security_solution/public/notes/links.ts index e954826354579..5d20c4876014c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/notes/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/notes/links.ts @@ -6,12 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import { - NOTES_FEATURE_ID, - NOTES_PATH, - SECURITY_FEATURE_ID, - SecurityPageName, -} from '../../common/constants'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { NOTES_PATH, SecurityPageName, NOTES_FEATURE_ID } from '../../common/constants'; import { NOTES } from '../app/translations'; import type { LinkItem } from '../common/links/types'; @@ -24,7 +20,7 @@ export const links: LinkItem = { 'Oversee, revise, and revisit the notes attached to alerts, events and Timelines.', }), // It only makes sense to show this link when the user is also granted access to security solution - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${NOTES_FEATURE_ID}.read`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${NOTES_FEATURE_ID}.read`]], landingIcon: 'filebeatApp', skipUrlState: true, hideTimeline: false, diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations_external_detections/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations_external_detections/index.ts index 8135d225de5f4..0faa6bc895b3c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations_external_detections/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations_external_detections/index.ts @@ -7,12 +7,12 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; +import { RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { IconIntegrations } from '../../../../../common/icons/integrations'; import type { OnboardingCardConfig } from '../../../../types'; import type { ExternalIntegrationCardMetadata } from './integrations_check_complete'; import { checkIntegrationsCardComplete } from './integrations_check_complete'; import { OnboardingCardId } from '../../../../constants'; -import { SECURITY_FEATURE_ID } from '../../../../../../common/constants'; export const integrationsExternalDetectionsCardConfig: OnboardingCardConfig = { @@ -32,5 +32,5 @@ export const integrationsExternalDetectionsCardConfig: OnboardingCardConfig ({ })); const defaultUseAlertsPrivilegesReturn = { - hasKibanaREAD: true, + hasSiemRead: true, hasIndexRead: true, }; @@ -174,7 +174,7 @@ describe('DetectionResponse', () => { it('should not render alerts data sections if user has not index read permission', () => { mockUseAlertsPrivileges.mockReturnValue({ hasIndexRead: false, - hasKibanaREAD: true, + hasSiemRead: true, }); const result = render( @@ -198,7 +198,7 @@ describe('DetectionResponse', () => { it('should not render alerts data sections if user has not kibana read permission', () => { mockUseAlertsPrivileges.mockReturnValue({ hasIndexRead: true, - hasKibanaREAD: false, + hasSiemRead: false, }); const result = render( @@ -243,7 +243,7 @@ describe('DetectionResponse', () => { it('should render page permissions message if the user does not have read permission', () => { mockCanUseCases.mockReturnValue(noCasesPermissions()); mockUseAlertsPrivileges.mockReturnValue({ - hasKibanaREAD: true, + hasSiemRead: true, hasIndexRead: false, }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/pages/detection_response.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/pages/detection_response.tsx index e70b7554fe662..f26953b5c8796 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/pages/detection_response.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/pages/detection_response.tsx @@ -54,7 +54,7 @@ const DetectionResponseComponent = () => { const isSourcererLoading = newDataViewPickerEnabled ? status !== 'ready' : oldIsSourcererLoading; const { signalIndexName } = useSignalIndex(); - const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const { hasSiemRead: hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); const userCasesPermissions = cases.helpers.canUseCases([APP_ID]); const canReadCases = userCasesPermissions.read; const canReadAlerts = hasKibanaREAD && hasIndexRead; diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/pages/overview.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/pages/overview.tsx index c7764653c86b7..9225d2ffd70b0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/overview/pages/overview.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/overview/pages/overview.tsx @@ -90,7 +90,7 @@ const OverviewComponent = () => { const { endpointPrivileges: { canAccessFleet }, } = useUserPrivileges(); - const { hasIndexRead, hasKibanaREAD } = useAlertsPrivileges(); + const { hasIndexRead, hasSiemRead: hasKibanaREAD } = useAlertsPrivileges(); const { tiDataSources: allTiDataSources, isInitiallyLoaded: isTiLoaded } = useAllTiDataSources(); if (newDataViewPickerEnabled && status === 'pristine') { diff --git a/x-pack/solutions/security/plugins/security_solution/public/reports/links.ts b/x-pack/solutions/security/plugins/security_solution/public/reports/links.ts index 76337ee6e2034..0a188e7eede0b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/reports/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/reports/links.ts @@ -5,17 +5,17 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; import type { CoreStart } from '@kbn/core/public'; -import type { StartPlugins } from '../types'; +import { i18n } from '@kbn/i18n'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { - SecurityPageName, - SECURITY_FEATURE_ID, - ATTACK_DISCOVERY_FEATURE_ID, AI_VALUE_PATH, + ATTACK_DISCOVERY_FEATURE_ID, + SecurityPageName, } from '../../common/constants'; import { AI_VALUE_DASHBOARD } from '../app/translations'; import type { LinkItem } from '../common/links/types'; +import type { StartPlugins } from '../types'; export const aiValueLinks: LinkItem = { id: SecurityPageName.aiValue, @@ -24,9 +24,7 @@ export const aiValueLinks: LinkItem = { defaultMessage: 'See ROI for Security AI features', }), path: AI_VALUE_PATH, - capabilities: [ - [`${SECURITY_FEATURE_ID}.show`, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], - ], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.aiValue', { defaultMessage: 'AI Value', diff --git a/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.test.tsx index c7067bd60c212..8feadd668e792 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.test.tsx @@ -147,10 +147,10 @@ describe('AIValue', () => { sourcererDataView: {} as Record, }); mockUseAlertsPrivileges.mockReturnValue({ - hasKibanaREAD: true, + hasSiemRead: true, hasIndexRead: true, hasIndexUpdateDelete: false, - hasKibanaCRUD: false, + hasSiemCRUD: false, loading: false, isAuthenticated: true, hasEncryptionKey: true, @@ -238,10 +238,10 @@ describe('AIValue', () => { it('shows no privileges when user lacks alert read privileges', () => { mockUseAlertsPrivileges.mockReturnValue({ - hasKibanaREAD: false, + hasSiemRead: false, hasIndexRead: true, hasIndexUpdateDelete: false, - hasKibanaCRUD: false, + hasSiemCRUD: false, loading: false, isAuthenticated: true, hasEncryptionKey: true, @@ -261,10 +261,10 @@ describe('AIValue', () => { it('shows no privileges when user lacks index read privileges', () => { mockUseAlertsPrivileges.mockReturnValue({ - hasKibanaREAD: true, + hasSiemRead: true, hasIndexRead: false, hasIndexUpdateDelete: false, - hasKibanaCRUD: false, + hasSiemCRUD: false, loading: false, isAuthenticated: true, hasEncryptionKey: true, diff --git a/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.tsx b/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.tsx index 6e18555c8ce86..0fab49ab90b12 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/reports/pages/ai_value.tsx @@ -53,7 +53,7 @@ const AIValueComponent = () => { const isSourcererLoading = newDataViewPickerEnabled ? status !== 'ready' : oldIsSourcererLoading; - const { hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); + const { hasSiemRead: hasKibanaREAD, hasIndexRead } = useAlertsPrivileges(); const canReadAlerts = hasKibanaREAD && hasIndexRead; const { hasRequiredRole, isLoading: isRoleCheckLoading } = useAiValueRoleCheck(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts index b0e42dee2affa..3ebd5ba1ca4aa 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts @@ -6,6 +6,11 @@ */ import { i18n } from '@kbn/i18n'; +import { + RULES_UI_DETECTIONS_PRIVILEGE, + RULES_UI_READ_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, +} from '@kbn/security-solution-features/constants'; import { COVERAGE_OVERVIEW_PATH, EXCEPTIONS_PATH, @@ -13,7 +18,6 @@ import { RULES_CREATE_PATH, RULES_LANDING_PATH, RULES_PATH, - SECURITY_FEATURE_ID, } from '../../common/constants'; import { ADD_RULES, @@ -37,7 +41,7 @@ export const links: LinkItem = { hideTimeline: true, skipUrlState: true, globalNavPosition: 2, - capabilities: `${SECURITY_FEATURE_ID}.show`, + capabilities: [RULES_UI_READ_PRIVILEGE, SECURITY_UI_SHOW_PRIVILEGE], links: [ { id: SecurityPageName.rules, @@ -52,7 +56,7 @@ export const links: LinkItem = { defaultMessage: 'SIEM Rules', }), ], - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, RULES_UI_DETECTIONS_PRIVILEGE]], links: [ { id: SecurityPageName.rulesAdd, @@ -79,7 +83,7 @@ export const links: LinkItem = { }), landingIcon: IconConsoleCloud, path: EXCEPTIONS_PATH, - capabilities: [`${SECURITY_FEATURE_ID}.show`], + capabilities: [RULES_UI_READ_PRIVILEGE], skipUrlState: true, hideTimeline: true, globalSearchKeywords: [ @@ -100,7 +104,7 @@ export const links: LinkItem = { } ), path: COVERAGE_OVERVIEW_PATH, - capabilities: `${SECURITY_FEATURE_ID}.detections`, + capabilities: RULES_UI_READ_PRIVILEGE, globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.coverageOverviewDashboard', { defaultMessage: 'MITRE ATT&CK Coverage', diff --git a/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx index 9df1950da3359..cc4974a44ae5a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx @@ -9,12 +9,15 @@ import { Redirect } from 'react-router-dom'; import { Routes, Route } from '@kbn/shared-ux-router'; import type { Capabilities } from '@kbn/core-capabilities-common'; +import { + RULES_UI_EDIT_PRIVILEGE, + RULES_UI_READ_PRIVILEGE, +} from '@kbn/security-solution-features/constants'; import * as i18n from './translations'; import { COVERAGE_OVERVIEW_PATH, RULES_LANDING_PATH, RULES_PATH, - SECURITY_FEATURE_ID, SecurityPageName, } from '../../common/constants'; import { NotFoundPage } from '../app/404'; @@ -36,11 +39,11 @@ import { hasCapabilities } from '../common/lib/capabilities'; import { useKibana } from '../common/lib/kibana/kibana_react'; const getRulesSubRoutes = (capabilities: Capabilities) => [ - ...(hasCapabilities(capabilities, `${SECURITY_FEATURE_ID}.detections`) // regular detection rules are enabled + ...(hasCapabilities(capabilities, RULES_UI_READ_PRIVILEGE) // regular detection rules are enabled ? [ { - path: '/rules/id/:detailName/edit', - main: EditRulePage, + path: `/rules/id/:detailName/:tabName(${RuleDetailTabs.alerts}|${RuleDetailTabs.exceptions}|${RuleDetailTabs.endpointExceptions}|${RuleDetailTabs.executionResults}|${RuleDetailTabs.executionEvents})`, + main: RuleDetailsPage, exact: true, }, { @@ -50,32 +53,29 @@ const getRulesSubRoutes = (capabilities: Capabilities) => [ }, ] : []), - ...(hasCapabilities(capabilities, [ - `${SECURITY_FEATURE_ID}.detections`, - `${SECURITY_FEATURE_ID}.external_detections`, - ]) // some detection capability is enabled + ...(hasCapabilities(capabilities, RULES_UI_EDIT_PRIVILEGE) ? [ { - path: `/rules/id/:detailName/:tabName(${RuleDetailTabs.alerts}|${RuleDetailTabs.exceptions}|${RuleDetailTabs.endpointExceptions}|${RuleDetailTabs.executionResults}|${RuleDetailTabs.executionEvents})`, - main: RuleDetailsPage, + path: '/rules/id/:detailName/edit', + main: EditRulePage, + exact: true, + }, + { + path: '/rules/create', + main: withSecurityRoutePageWrapper(CreateRulePage, SecurityPageName.rulesCreate, { + omitSpyRoute: true, + }), + exact: true, + }, + { + path: '/rules/add_rules', + main: withSecurityRoutePageWrapper(AddRulesPage, SecurityPageName.rulesAdd, { + omitSpyRoute: true, + }), exact: true, }, ] : []), - { - path: '/rules/create', - main: withSecurityRoutePageWrapper(CreateRulePage, SecurityPageName.rulesCreate, { - omitSpyRoute: true, - }), - exact: true, - }, - { - path: '/rules/add_rules', - main: withSecurityRoutePageWrapper(AddRulesPage, SecurityPageName.rulesAdd, { - omitSpyRoute: true, - }), - exact: true, - }, ]; const RulesContainerComponent: React.FC = () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts index a7803c41b0433..46aff57c13d59 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts @@ -6,10 +6,13 @@ */ import type { Capabilities } from '@kbn/core/public'; -import { SIEM_MIGRATIONS_FEATURE_ID } from '@kbn/security-solution-features/constants'; +import { + SECURITY_UI_CRUD_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, + SIEM_MIGRATIONS_FEATURE_ID, +} from '@kbn/security-solution-features/constants'; import { i18n } from '@kbn/i18n'; import { CapabilitiesChecker } from '../../../common/lib/capabilities'; -import { SECURITY_FEATURE_ID } from '../../../../common/constants'; export interface MissingCapability { capability: string; @@ -18,7 +21,7 @@ export interface MissingCapability { const minimumCapabilities: MissingCapability[] = [ { - capability: `${SECURITY_FEATURE_ID}.show`, + capability: SECURITY_UI_SHOW_PRIVILEGE, description: i18n.translate( 'xpack.securitySolution.siemMigrations.service.capabilities.securityAll', { defaultMessage: 'Security > Security: Read' } @@ -35,7 +38,7 @@ const minimumCapabilities: MissingCapability[] = [ const allCapabilities: MissingCapability[] = [ { - capability: `${SECURITY_FEATURE_ID}.crud`, + capability: SECURITY_UI_CRUD_PRIVILEGE, description: i18n.translate( 'xpack.securitySolution.siemMigrations.service.capabilities.securityAll', { defaultMessage: 'Security > Security: All' } diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 979b0b045408b..8157338eb1d41 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -6,13 +6,16 @@ */ import { i18n } from '@kbn/i18n'; -import { SIEM_MIGRATIONS_FEATURE_ID } from '@kbn/security-solution-features/constants'; import { - SecurityPageName, + RULES_UI_READ_PRIVILEGE, + SIEM_MIGRATIONS_FEATURE_ID, +} from '@kbn/security-solution-features/constants'; +import { SECURITY_FEATURE_ID, - SIEM_MIGRATIONS_RULES_PATH, SIEM_MIGRATIONS_DASHBOARDS_PATH, SIEM_MIGRATIONS_LANDING_PATH, + SIEM_MIGRATIONS_RULES_PATH, + SecurityPageName, } from '../../common/constants'; import type { LinkItem } from '../common/links/types'; import { IconDashboards } from '../common/icons/dashboards'; @@ -67,7 +70,7 @@ export const links: LinkItem = { defaultMessage: 'Migrations', }), path: SIEM_MIGRATIONS_LANDING_PATH, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.migrations', { defaultMessage: 'Migrations', diff --git a/x-pack/solutions/security/plugins/security_solution/public/timelines/containers/local_storage/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/timelines/containers/local_storage/index.tsx index 8092539c7c971..a2128aebd5272 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/timelines/containers/local_storage/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/timelines/containers/local_storage/index.tsx @@ -108,7 +108,7 @@ export const migrateAlertTableStateToTriggerActionsState = ( return { [newKey]: { columns: legacyDataTableState[tableKey].columns, - sort: legacyDataTableState[tableKey].sort.map((sortCandidate) => ({ + sort: legacyDataTableState[tableKey].sort?.map((sortCandidate) => ({ [sortCandidate.columnId]: { order: sortCandidate.sortDirection }, })), visibleColumns: legacyDataTableState[tableKey].columns, diff --git a/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts b/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts index fa30a91d82ad6..d3537fbe584a2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts @@ -6,12 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import { - SECURITY_FEATURE_ID, - SecurityPageName, - TIMELINE_FEATURE_ID, - TIMELINES_PATH, -} from '../../common/constants'; +import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { SecurityPageName, TIMELINE_FEATURE_ID, TIMELINES_PATH } from '../../common/constants'; import { TIMELINES } from '../app/translations'; import type { LinkItem } from '../common/links/types'; @@ -21,7 +17,7 @@ export const links: LinkItem = { path: TIMELINES_PATH, globalNavPosition: 9, // It only makes sense to show this link when the user is also granted access to security solution - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${TIMELINE_FEATURE_ID}.read`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.timelines', { defaultMessage: 'Timelines', @@ -35,7 +31,7 @@ export const links: LinkItem = { }), path: `${TIMELINES_PATH}/template`, sideNavDisabled: true, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${TIMELINE_FEATURE_ID}.read`]], + capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`]], }, ], }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts b/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts index d48855b397105..018fb479a2ae0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts @@ -9,7 +9,7 @@ import { useEffect } from 'react'; import * as i18n from './translations'; import { useKibana } from './common/lib/kibana'; -import { useAlertsPrivileges } from './detections/containers/detection_engine/alerts/use_alerts_privileges'; +import { useUserPrivileges } from './common/components/user_privileges'; /** * This component places a read-only icon badge in the header @@ -17,11 +17,11 @@ import { useAlertsPrivileges } from './detections/containers/detection_engine/al * privileges */ export function useReadonlyHeader(tooltip: string) { - const { hasKibanaREAD, hasKibanaCRUD } = useAlertsPrivileges(); + const { rulesPrivileges } = useUserPrivileges(); const chrome = useKibana().services.chrome; useEffect(() => { - if (hasKibanaREAD && !hasKibanaCRUD) { + if (rulesPrivileges.read && !rulesPrivileges.edit) { chrome.setBadge({ text: i18n.READ_ONLY_BADGE_TEXT, tooltip, @@ -33,5 +33,5 @@ export function useReadonlyHeader(tooltip: string) { return () => { chrome.setBadge(); }; - }, [chrome, hasKibanaREAD, hasKibanaCRUD, tooltip]); + }, [chrome, tooltip, rulesPrivileges.read, rulesPrivileges.edit]); } diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_all_integrations/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_all_integrations/route.ts index 9bfbda7735692..3b9e37695ea73 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_all_integrations/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_all_integrations/route.ts @@ -8,6 +8,7 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { SO_SEARCH_LIMIT } from '@kbn/fleet-plugin/common/constants'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { PREBUILT_RULES_PACKAGE_NAME } from '../../../../../../common/detection_engine/constants'; import { buildSiemResponse } from '../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -29,7 +30,7 @@ export const getAllIntegrationsRoute = (router: SecuritySolutionPluginRouter, lo path: GET_ALL_INTEGRATIONS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts index 006cc0afc17d5..9cbf98d088f59 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts @@ -7,6 +7,7 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { buildSiemResponse } from '../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -29,7 +30,7 @@ export const getInstalledIntegrationsRoute = ( path: GET_INSTALLED_INTEGRATIONS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.ts index fb39e0cec41b1..30b0c0f80b326 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules.ts @@ -6,6 +6,7 @@ */ import type { Logger } from '@kbn/core/server'; +import { INITIALIZE_SECURITY_SOLUTION } from '@kbn/security-solution-features/constants'; import { BOOTSTRAP_PREBUILT_RULES_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { PREBUILT_RULES_OPERATION_SOCKET_TIMEOUT_MS } from '../../constants'; @@ -22,7 +23,7 @@ export const bootstrapPrebuiltRulesRoute = ( path: BOOTSTRAP_PREBUILT_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [INITIALIZE_SECURITY_SOLUTION], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules_handler.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules_handler.ts index a90534a0f7147..3426f02692561 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules_handler.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/bootstrap_prebuilt_rules/bootstrap_prebuilt_rules_handler.ts @@ -11,7 +11,7 @@ import type { KibanaRequest, KibanaResponseFactory, } from '@kbn/core/server'; -import { ProductFeatureSecurityKey } from '@kbn/security-solution-features/keys'; +import { ProductFeatureRulesKey } from '@kbn/security-solution-features/keys'; import { transformError } from '@kbn/securitysolution-es-utils'; import { installSecurityAiPromptsPackage } from '../../logic/integrations/install_ai_prompts'; import type { @@ -47,7 +47,7 @@ export const bootstrapPrebuiltRulesHandler = async ( const productFeatureService = securityContext.getProductFeatureService(); const isExternalDetectionsEnabled = productFeatureService.isEnabled( - ProductFeatureSecurityKey.externalDetections + ProductFeatureRulesKey.externalDetections ); const packageResults: PackageInstallStatus[] = []; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rule_base_version/get_prebuilt_rule_base_version_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rule_base_version/get_prebuilt_rule_base_version_route.ts index 8e4812e8619d2..4445ab132f163 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rule_base_version/get_prebuilt_rule_base_version_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rule_base_version/get_prebuilt_rule_base_version_route.ts @@ -6,6 +6,7 @@ */ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { GET_PREBUILT_RULES_BASE_VERSION_URL, GetPrebuiltRuleBaseVersionRequest, @@ -20,7 +21,7 @@ export const getPrebuiltRuleBaseVersion = (router: SecuritySolutionPluginRouter) path: GET_PREBUILT_RULES_BASE_VERSION_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts index 3794f33278c7e..fa4b1c056cf9f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts @@ -7,6 +7,7 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { InstallPrepackedTimelinesRequestBody } from '../../../../../../common/api/timeline'; import { buildSiemResponse } from '../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -36,7 +37,7 @@ export const getPrebuiltRulesAndTimelinesStatusRoute = ( path: PREBUILT_RULES_STATUS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts index e1fa7d9dc13c9..d5c5debd11df7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts @@ -6,6 +6,7 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { GET_PREBUILT_RULES_STATUS_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import type { GetPrebuiltRulesStatusResponseBody } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -21,7 +22,7 @@ export const getPrebuiltRulesStatusRoute = (router: SecuritySolutionPluginRouter path: GET_PREBUILT_RULES_STATUS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts index 711518ad91d46..c87e3682bff55 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/install_prebuilt_rules_and_timelines_route.ts @@ -7,6 +7,7 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import { PREBUILT_RULES_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { buildSiemResponse } from '../../../routes/utils'; @@ -25,7 +26,7 @@ export const installPrebuiltRulesAndTimelinesRoute = ( path: PREBUILT_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts index 269f02111373b..c732242a4de0c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts @@ -6,6 +6,7 @@ */ import type { Logger } from '@kbn/core/server'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import { PERFORM_RULE_INSTALLATION_URL, PerformRuleInstallationRequestBody, @@ -29,7 +30,7 @@ export const performRuleInstallationRoute = ( path: PERFORM_RULE_INSTALLATION_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts index 9b8c38d5990a2..8eb591f297560 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -7,6 +7,7 @@ import type { Logger } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import { PERFORM_RULE_UPGRADE_URL, PerformRuleUpgradeRequestBody, @@ -26,7 +27,7 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter, lo path: PERFORM_RULE_UPGRADE_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/revert_prebuilt_rule/revert_prebuilt_rule_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/revert_prebuilt_rule/revert_prebuilt_rule_route.ts index b57041074e7b1..e797082e07335 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/revert_prebuilt_rule/revert_prebuilt_rule_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/revert_prebuilt_rule/revert_prebuilt_rule_route.ts @@ -6,6 +6,7 @@ */ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import { REVERT_PREBUILT_RULES_URL, RevertPrebuiltRulesRequest, @@ -21,7 +22,7 @@ export const revertPrebuiltRule = (router: SecuritySolutionPluginRouter) => { path: REVERT_PREBUILT_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts index 7ae1e70c43a7d..ae5f1b29eae08 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_installation/review_rule_installation_route.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { REVIEW_RULE_INSTALLATION_URL } from '../../../../../../common/api/detection_engine/prebuilt_rules'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { routeLimitedConcurrencyTag } from '../../../../../utils/route_limited_concurrency_tag'; @@ -21,7 +22,7 @@ export const reviewRuleInstallationRoute = (router: SecuritySolutionPluginRouter path: REVIEW_RULE_INSTALLATION_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts index 24b3865fc5ea0..f40dfc641f541 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/review_rule_upgrade/review_rule_upgrade_route.ts @@ -6,6 +6,7 @@ */ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { REVIEW_RULE_UPGRADE_URL, ReviewRuleUpgradeRequestBody, @@ -25,7 +26,7 @@ export const reviewRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) => path: REVIEW_RULE_UPGRADE_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts index 5337c1333fbde..ac292a565a4dd 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/create_index_route.ts @@ -15,6 +15,7 @@ import { setPolicy, createBootstrapIndex, } from '@kbn/securitysolution-es-utils'; +import { INITIALIZE_SECURITY_SOLUTION } from '@kbn/security-solution-features/constants'; import type { CreateAlertsIndexResponse } from '../../../../../common/api/detection_engine/index_management'; import type { SecuritySolutionApiRequestHandlerContext, @@ -42,7 +43,7 @@ export const createIndexRoute = (router: SecuritySolutionPluginRouter) => { access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [INITIALIZE_SECURITY_SOLUTION], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts index 08f975c023851..3d5305e5117d2 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/delete_index_route.ts @@ -14,6 +14,7 @@ import { } from '@kbn/securitysolution-es-utils'; import type { IKibanaResponse } from '@kbn/core/server'; +import { ALERTS_API_ALL } from '@kbn/security-solution-features/constants'; import type { DeleteAlertsIndexResponse } from '../../../../../common/api/detection_engine/index_management'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_INDEX_URL } from '../../../../../common/constants'; @@ -37,7 +38,7 @@ export const deleteIndexRoute = (router: SecuritySolutionPluginRouter) => { access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [ALERTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts index 2f5131d1abf8b..e6401534689d9 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/index/read_index_route.ts @@ -8,6 +8,7 @@ import { transformError, getBootstrapIndexExists } from '@kbn/securitysolution-es-utils'; import type { RuleDataPluginService } from '@kbn/rule-registry-plugin/server'; import type { IKibanaResponse } from '@kbn/core/server'; +import { INITIALIZE_SECURITY_SOLUTION } from '@kbn/security-solution-features/constants'; import type { ReadAlertsIndexResponse } from '../../../../../common/api/detection_engine/index_management'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_INDEX_URL } from '../../../../../common/constants'; @@ -28,7 +29,7 @@ export const readIndexRoute = ( access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [INITIALIZE_SECURITY_SOLUTION], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts index 22c031d5d5eb5..f4fb9b15fa573 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/privileges/read_privileges_route.ts @@ -9,6 +9,7 @@ import { merge } from 'lodash/fp'; import { readPrivileges, transformError } from '@kbn/securitysolution-es-utils'; import type { IKibanaResponse } from '@kbn/core/server'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_PRIVILEGES_URL } from '../../../../../common/constants'; import { buildSiemResponse } from '../utils'; @@ -24,7 +25,7 @@ export const readPrivilegesRoute = ( access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [{ anyRequired: [RULES_API_READ, 'securitySolution'] }], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index 8a84180c997ae..f7399d3c46a2d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -15,6 +15,7 @@ import { } from '@kbn/rule-data-utils'; import type { AuthenticatedUser, ElasticsearchClient, Logger } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { ALERTS_API_ALL, ALERTS_API_READ } from '@kbn/security-solution-features/constants'; import { SetAlertsStatusRequestBody } from '../../../../../common/api/detection_engine/signals'; import { AlertStatusEnum } from '../../../../../common/api/model'; import type { SecuritySolutionPluginRouter } from '../../../../types'; @@ -41,7 +42,7 @@ export const setSignalsStatusRoute = ( access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [ALERTS_API_ALL, ALERTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts index 2092ff935a52b..780357683cbd3 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -13,6 +13,7 @@ import type { import { transformError } from '@kbn/securitysolution-es-utils'; import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { ALERTS_API_READ } from '@kbn/security-solution-features/constants'; import { SearchAlertsRequestBody } from '../../../../../common/api/detection_engine/signals'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_QUERY_SIGNALS_URL } from '../../../../../common/constants'; @@ -28,7 +29,7 @@ export const querySignalsRoute = ( access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [ALERTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_assignees_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_assignees_route.ts index 5fee6554a1400..8fe1f0390ac22 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_assignees_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_assignees_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { uniq } from 'lodash/fp'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { ALERTS_API_READ } from '@kbn/security-solution-features/constants'; import { SetAlertAssigneesRequestBody } from '../../../../../common/api/detection_engine/alert_assignees'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { @@ -24,7 +25,8 @@ export const setAlertAssigneesRoute = (router: SecuritySolutionPluginRouter) => access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + // a t1_analyst, who has read only access, should be able to assign alerts + requiredPrivileges: [ALERTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts index 19b7f309ce126..33632cace64e7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { uniq } from 'lodash/fp'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { ALERTS_API_ALL } from '@kbn/security-solution-features/constants'; import { SetAlertTagsRequestBody } from '../../../../../common/api/detection_engine/alert_tags'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { @@ -24,7 +25,7 @@ export const setAlertTagsRoute = (router: SecuritySolutionPluginRouter) => { access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [ALERTS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/users/suggest_user_profiles_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/users/suggest_user_profiles_route.ts index 2b8f65af12ca5..2bcd65fca12db 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/users/suggest_user_profiles_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/users/suggest_user_profiles_route.ts @@ -9,6 +9,7 @@ import type { IKibanaResponse, StartServicesAccessor } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import type { UserProfileWithAvatar } from '@kbn/user-profile-components'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { USERS_API_READ } from '@kbn/security-solution-features/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_ALERT_SUGGEST_USERS_URL } from '../../../../../common/constants'; import { buildSiemResponse } from '../utils'; @@ -25,7 +26,7 @@ export const suggestUserProfilesRoute = ( access: 'internal', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [USERS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts index b178d912ccf27..1fa1cbc468c44 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts @@ -22,6 +22,7 @@ import { CreateRuleExceptionListItemsResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import { CREATE_RULE_EXCEPTIONS_URL } from '../../../../../../common/api/detection_engine/rule_exceptions'; import { readRules } from '../../../rule_management/logic/detection_rules_client/read_rules'; @@ -38,7 +39,7 @@ export const createRuleExceptionsRoute = (router: SecuritySolutionPluginRouter) access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts index db890c7104e58..476c5b8264dd1 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { getSavedObjectType } from '@kbn/securitysolution-list-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import { buildRouteValidation } from '../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; @@ -31,7 +32,7 @@ export const findRuleExceptionReferencesRoute = (router: SecuritySolutionPluginR access: 'internal', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts index e6e9070303bbd..08cda67183005 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts @@ -10,6 +10,7 @@ import { AbortError } from '@kbn/kibana-utils-plugin/common'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import type { BulkActionSkipResult } from '@kbn/alerting-plugin/common'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import type { PerformRulesBulkActionResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { BulkActionTypeEnum, @@ -108,7 +109,7 @@ export const performBulkActionRoute = ( path: DETECTION_ENGINE_RULES_BULK_ACTION, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts index a3c6a07e0b8be..9a807ab2669df 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/coverage_overview/route.ts @@ -7,6 +7,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { IKibanaResponse } from '@kbn/core/server'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { CoverageOverviewResponse } from '../../../../../../../common/api/detection_engine'; import { CoverageOverviewRequestBody, @@ -24,7 +25,7 @@ export const getCoverageOverviewRoute = (router: SecuritySolutionPluginRouter) = path: RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts index dbeaed85db055..0907680c68b1f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import type { CreateRuleResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { CreateRuleRequestBody, @@ -29,7 +30,7 @@ export const createRuleRoute = (router: SecuritySolutionPluginRouter): void => { security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts index 3e5ef8aa8ab7a..e85c29950e58d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import type { DeleteRuleResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { DeleteRuleRequestQuery, @@ -26,7 +27,7 @@ export const deleteRuleRoute = (router: SecuritySolutionPluginRouter) => { path: DETECTION_ENGINE_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts index f0abe3bd75a50..77b0bf45ecba2 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { Logger } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; import { ExportRulesRequestBody, @@ -32,7 +33,7 @@ export const exportRulesRoute = ( path: `${DETECTION_ENGINE_RULES_URL}/_export`, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts index 6496c6edc2a87..a72fcf236bdc4 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/filters/route.ts @@ -9,6 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { RulesClient } from '@kbn/alerting-plugin/server'; import type { IKibanaResponse } from '@kbn/core/server'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { GetRuleManagementFiltersResponse, RULE_MANAGEMENT_FILTERS_URL, @@ -58,7 +59,7 @@ export const getRuleManagementFilters = (router: SecuritySolutionPluginRouter) = path: RULE_MANAGEMENT_FILTERS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts index 26460605c08a3..f86acb0f51190 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts @@ -9,6 +9,7 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { gapStatus } from '@kbn/alerting-plugin/common'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { DETECTION_ENGINE_RULES_URL_FIND } from '../../../../../../../common/constants'; import type { FindRulesResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { @@ -27,7 +28,7 @@ export const findRulesRoute = (router: SecuritySolutionPluginRouter, logger: Log path: DETECTION_ENGINE_RULES_URL_FIND, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts index 67030218b9419..7f3eaf2a0ea61 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts @@ -11,6 +11,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { chunk, partition } from 'lodash/fp'; import { extname } from 'path'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import { ImportRulesRequestQuery, ImportRulesResponse, @@ -53,7 +54,7 @@ export const importRulesRoute = ( path: DETECTION_ENGINE_RULES_IMPORT_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts index 6971628a780d9..ca4d6b2f67c47 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import type { PatchRuleResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { PatchRuleRequestBody, @@ -28,7 +29,7 @@ export const patchRuleRoute = (router: SecuritySolutionPluginRouter) => { path: DETECTION_ENGINE_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts index 53b8ca4085209..3a829cc0f9ebe 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { ReadRuleResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { ReadRuleRequestQuery, @@ -26,7 +27,7 @@ export const readRuleRoute = (router: SecuritySolutionPluginRouter, logger: Logg path: DETECTION_ENGINE_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts index 8a83aae938d6f..7ca159b2109f0 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; import type { UpdateRuleResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { UpdateRuleRequestBody, @@ -29,7 +30,7 @@ export const updateRuleRoute = (router: SecuritySolutionPluginRouter) => { path: DETECTION_ENGINE_RULES_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts index 0332dfe024964..04d7941d0ee79 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts @@ -7,6 +7,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { ReadTagsResponse } from '../../../../../../../common/api/detection_engine'; import { DETECTION_ENGINE_TAGS_URL } from '../../../../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -20,7 +21,7 @@ export const readTagsRoute = (router: SecuritySolutionPluginRouter) => { path: DETECTION_ENGINE_TAGS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health/get_cluster_health_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health/get_cluster_health_route.ts index d6d9e6843e5a2..d05a1547d42b5 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health/get_cluster_health_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_cluster_health/get_cluster_health_route.ts @@ -7,6 +7,7 @@ import type { IKibanaResponse, KibanaResponseFactory } from '@kbn/core-http-server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -38,7 +39,7 @@ export const getClusterHealthRoute = (router: SecuritySolutionPluginRouter) => { path: GET_CLUSTER_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) @@ -66,7 +67,7 @@ export const getClusterHealthRoute = (router: SecuritySolutionPluginRouter) => { path: GET_CLUSTER_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health/get_rule_health_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health/get_rule_health_route.ts index 401040b33faa5..58fe1a81becef 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health/get_rule_health_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_rule_health/get_rule_health_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { IKibanaResponse } from '@kbn/core/server'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { GetRuleHealthResponse } from '../../../../../../../common/api/detection_engine/rule_monitoring'; import { GetRuleHealthRequestBody, @@ -35,7 +36,7 @@ export const getRuleHealthRoute = (router: SecuritySolutionPluginRouter) => { path: GET_RULE_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health/get_space_health_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health/get_space_health_route.ts index 772de5aead760..055ec5383c50f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health/get_space_health_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/get_space_health/get_space_health_route.ts @@ -7,6 +7,7 @@ import type { IKibanaResponse, KibanaResponseFactory } from '@kbn/core-http-server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -38,7 +39,7 @@ export const getSpaceHealthRoute = (router: SecuritySolutionPluginRouter) => { path: GET_SPACE_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) @@ -66,7 +67,7 @@ export const getSpaceHealthRoute = (router: SecuritySolutionPluginRouter) => { path: GET_SPACE_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts index 0e8e5e5b676fa..6e9febcf0659c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts @@ -7,6 +7,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { SETUP_HEALTH_URL } from '../../../../../../../common/api/detection_engine/rule_monitoring'; import type { SetupHealthResponse } from '../../../../../../../common/api/detection_engine'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -24,7 +25,7 @@ export const setupHealthRoute = (router: SecuritySolutionPluginRouter) => { path: SETUP_HEALTH_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts index fc3c485710c1a..4120b6fe78cf8 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.ts @@ -8,6 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { IKibanaResponse } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { buildSiemResponse } from '../../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -29,7 +30,7 @@ export const getRuleExecutionEventsRoute = (router: SecuritySolutionPluginRouter path: GET_RULE_EXECUTION_EVENTS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts index c23396e139afc..95d5bc4b37446 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.ts @@ -8,6 +8,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildSiemResponse } from '../../../../routes/utils'; @@ -29,7 +30,7 @@ export const getRuleExecutionResultsRoute = (router: SecuritySolutionPluginRoute path: GET_RULE_EXECUTION_RESULTS_URL, security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts index 78a39cca72f04..a686057345e6b 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts @@ -18,6 +18,7 @@ import type { } from '@kbn/alerting-plugin/common'; import { parseDuration, DISABLE_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; import { wrapAsyncSearchClient } from '@kbn/alerting-plugin/server/lib'; import { DEFAULT_PREVIEW_INDEX, @@ -90,7 +91,7 @@ export const previewRulesRoute = ( access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [RULES_API_READ], }, }, options: { diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts index f641f85e48038..d855b805f48e0 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts @@ -38,6 +38,11 @@ jest.mock('@kbn/security-solution-features/product_features', () => ({ baseKibanaSubFeatureIds: [], subFeaturesMap: new Map(), })), + getSecurityV5Feature: jest.fn(() => ({ + baseKibanaFeature: {}, + baseKibanaSubFeatureIds: [], + subFeaturesMap: new Map(), + })), getCasesFeature: jest.fn(() => ({ baseKibanaFeature: {}, baseKibanaSubFeatureIds: [], @@ -78,6 +83,11 @@ jest.mock('@kbn/security-solution-features/product_features', () => ({ baseKibanaSubFeatureIds: [], subFeaturesMap: new Map(), })), + getRulesFeature: jest.fn(() => ({ + baseKibanaFeature: {}, + baseKibanaSubFeatureIds: [], + subFeaturesMap: new Map(), + })), })); export const createProductFeaturesServiceMock = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts index eed604167f1a9..0001428c8469c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts @@ -41,6 +41,8 @@ jest.mock('@kbn/security-solution-features/product_features', () => ({ getSecurityV2Feature: () => mockGetFeature(), getSecurityV3Feature: () => mockGetFeature(), getSecurityV4Feature: () => mockGetFeature(), + getSecurityV5Feature: () => mockGetFeature(), + getRulesFeature: () => mockGetFeature(), getCasesFeature: () => mockGetFeature(), getCasesV2Feature: () => mockGetFeature(), getCasesV3Feature: () => mockGetFeature(), diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts index 88b637fe2c5e6..ee1ac46fb6c45 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts @@ -20,19 +20,25 @@ import { getSecurityV2Feature, getSecurityV3Feature, getSecurityV4Feature, + getSecurityV5Feature, getTimelineFeature, getNotesFeature, getSiemMigrationsFeature, + getRulesFeature, } from '@kbn/security-solution-features/product_features'; import { API_ACTION_PREFIX } from '@kbn/security-solution-features/actions'; import type { ExperimentalFeatures } from '../../../common'; import { ProductFeatures } from './product_features'; import { casesProductFeatureParams } from './cases_product_feature_params'; import { - securityDefaultSavedObjects, + rulesSavedObjects, securityNotesSavedObjects, securityTimelineSavedObjects, securityV1SavedObjects, + securityV2SavedObjects, + securityV3SavedObjects, + securityV4SavedObjects, + securityV5SavedObjects, } from './security_saved_objects'; import { registerApiAccessControl } from './product_features_api_access_control'; import type { @@ -52,9 +58,10 @@ export class ProductFeaturesService { const securityFeatureParams = { experimentalFeatures }; this.productFeaturesRegistry.create('security', [ getSecurityFeature({ ...securityFeatureParams, savedObjects: securityV1SavedObjects }), - getSecurityV2Feature({ ...securityFeatureParams, savedObjects: securityDefaultSavedObjects }), - getSecurityV3Feature({ ...securityFeatureParams, savedObjects: securityDefaultSavedObjects }), - getSecurityV4Feature({ ...securityFeatureParams, savedObjects: securityDefaultSavedObjects }), + getSecurityV2Feature({ ...securityFeatureParams, savedObjects: securityV2SavedObjects }), + getSecurityV3Feature({ ...securityFeatureParams, savedObjects: securityV3SavedObjects }), + getSecurityV4Feature({ ...securityFeatureParams, savedObjects: securityV4SavedObjects }), + getSecurityV5Feature({ ...securityFeatureParams, savedObjects: securityV5SavedObjects }), ]); this.productFeaturesRegistry.create('cases', [ getCasesFeature(casesProductFeatureParams), @@ -73,6 +80,9 @@ export class ProductFeaturesService { this.productFeaturesRegistry.create('notes', [ getNotesFeature({ ...securityFeatureParams, savedObjects: securityNotesSavedObjects }), ]); + this.productFeaturesRegistry.create('rules', [ + getRulesFeature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), + ]); if (!experimentalFeatures.siemMigrationsDisabled) { this.productFeaturesRegistry.create('siemMigrations', [getSiemMigrationsFeature()]); } diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts index 369f1a55e9a5f..c4adb4181d41b 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts @@ -8,11 +8,12 @@ import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/common'; import { EXCEPTION_LIST_NAMESPACE_AGNOSTIC } from '@kbn/securitysolution-list-constants'; import { - savedObjectTypesWithoutTimelineAndWithoutNotes, timelineSavedObjectTypes, notesSavedObjectTypes, savedObjectTypes, } from '../../saved_objects'; +import { noteType, pinnedEventType, timelineType } from '../timeline/saved_object_mappings'; +import { prebuiltRuleAssetType } from '../detection_engine/prebuilt_rules'; // Same as the saved-object type for rules defined by Cloud Security Posture const CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE = 'csp_rule'; @@ -20,18 +21,57 @@ const CLOUD_SECURITY_POSTURE_SETTINGS = 'cloud-security-posture-settings'; // Benchmark Rule Templates installed by the Cloud Security Posture package stored as Saved Objects: const CLOUD_SECURITY_POSTURE_BENCHMARK_RULE_TEMPLATE = 'csp-rule-template'; -export const securityDefaultSavedObjects = [ +export const securityV1SavedObjects = [ 'exception-list', EXCEPTION_LIST_NAMESPACE_AGNOSTIC, DATA_VIEW_SAVED_OBJECT_TYPE, - ...savedObjectTypesWithoutTimelineAndWithoutNotes, CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE, CLOUD_SECURITY_POSTURE_SETTINGS, CLOUD_SECURITY_POSTURE_BENCHMARK_RULE_TEMPLATE, + ...savedObjectTypes, ]; -export const securityV1SavedObjects = [...securityDefaultSavedObjects, ...savedObjectTypes]; +export const securityV2SavedObjects = [ + 'exception-list', + EXCEPTION_LIST_NAMESPACE_AGNOSTIC, + DATA_VIEW_SAVED_OBJECT_TYPE, + CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE, + CLOUD_SECURITY_POSTURE_SETTINGS, + CLOUD_SECURITY_POSTURE_BENCHMARK_RULE_TEMPLATE, + ...savedObjectTypes.filter( + (type) => ![noteType.name, pinnedEventType.name, timelineType.name].includes(type) + ), +]; + +export const securityV3SavedObjects = [...securityV2SavedObjects]; + +export const securityV4SavedObjects = [...securityV3SavedObjects]; // TODO: is this right? + +export const securityV5SavedObjects = [ + // The difference between v4 and v5 is that v4 removes the exceptions list SO + // type and prebuilt rules which are now managed by the rules product feature + DATA_VIEW_SAVED_OBJECT_TYPE, + CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE, + CLOUD_SECURITY_POSTURE_SETTINGS, + CLOUD_SECURITY_POSTURE_BENCHMARK_RULE_TEMPLATE, + EXCEPTION_LIST_NAMESPACE_AGNOSTIC, + ...savedObjectTypes.filter( + (type) => + ![ + noteType.name, + pinnedEventType.name, + timelineType.name, + prebuiltRuleAssetType.name, + ].includes(type) + ), +]; export const securityTimelineSavedObjects = timelineSavedObjectTypes; export const securityNotesSavedObjects = notesSavedObjectTypes; + +export const rulesSavedObjects = [ + 'exception-list', + EXCEPTION_LIST_NAMESPACE_AGNOSTIC, + prebuiltRuleAssetType.name, +]; diff --git a/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts index 5aa9a45609e44..c860be2cbbbb9 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts @@ -49,17 +49,6 @@ const types = [ export const savedObjectTypes = types.map((type) => type.name); -export const savedObjectTypesWithoutTimelineAndWithoutNotes = savedObjectTypes.filter((type) => { - switch (type) { - case noteType.name: - case pinnedEventType.name: - case timelineType.name: - return false; - default: - return true; - } -}); - export const timelineSavedObjectTypes = [timelineType.name, pinnedEventType.name]; export const notesSavedObjectTypes = [noteType.name]; diff --git a/x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts b/x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts index 0d0bfcd80d70d..926cd0aee061e 100644 --- a/x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution_ess/common/constants.ts @@ -9,11 +9,12 @@ import type { ProductFeatureKeyType } from '@kbn/security-solution-features/keys import { ALL_PRODUCT_FEATURE_KEYS, ProductFeatureSecurityKey, + ProductFeatureRulesKey, } from '@kbn/security-solution-features/keys'; // List of product features that are disabled in different offering (eg. Serverless). const DISABLED_PRODUCT_FEATURES: ProductFeatureKeyType[] = [ - ProductFeatureSecurityKey.externalDetections, + ProductFeatureRulesKey.externalDetections, ProductFeatureSecurityKey.configurations, ]; diff --git a/x-pack/solutions/security/test/cloud_security_posture_api/routes/helper/user_roles_utilites.ts b/x-pack/solutions/security/test/cloud_security_posture_api/routes/helper/user_roles_utilites.ts index 4138d5260d538..1b1a7b588dd9a 100644 --- a/x-pack/solutions/security/test/cloud_security_posture_api/routes/helper/user_roles_utilites.ts +++ b/x-pack/solutions/security/test/cloud_security_posture_api/routes/helper/user_roles_utilites.ts @@ -14,7 +14,10 @@ import { BENCHMARK_SCORE_INDEX_PATTERN, ALERTS_INDEX_PATTERN, } from '@kbn/cloud-security-posture-plugin/common/constants'; -import { SECURITY_FEATURE_ID } from '@kbn/security-solution-plugin/common/constants'; +import { + RULES_FEATURE_ID, + SECURITY_FEATURE_ID, +} from '@kbn/security-solution-plugin/common/constants'; import type { FtrProviderContext } from '../../ftr_provider_context'; const alertsSecurityUserIndices = [ @@ -142,6 +145,7 @@ export function CspSecurityCommonProvider(providerContext: FtrProviderContext) { base: [], feature: { [SECURITY_FEATURE_ID]: ['all'], + [RULES_FEATURE_ID]: ['all'], fleet: ['all'], fleetv2: ['all'], savedObjectsManagement: ['all'], diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/document_level_security.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/document_level_security.ts index 4c0f1a545e9c9..4c6de5000d65f 100644 --- a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/document_level_security.ts +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/document_level_security.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { DETECTION_ENGINE_QUERY_SIGNALS_URL, + RULES_FEATURE_ID, SECURITY_FEATURE_ID, } from '@kbn/security-solution-plugin/common/constants'; import type { FtrProviderContext } from '../../../../../ftr_provider_context'; @@ -29,6 +30,7 @@ const roleToAccessSecuritySolution = { { feature: { [SECURITY_FEATURE_ID]: ['all'], + [RULES_FEATURE_ID]: ['all'], }, spaces: ['*'], }, @@ -52,6 +54,7 @@ const roleToAccessSecuritySolutionWithDls = { { feature: { [SECURITY_FEATURE_ID]: ['all'], + [RULES_FEATURE_ID]: ['all'], }, spaces: ['*'], }, diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts index b72433f329a2f..ce529668fefd6 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts @@ -97,8 +97,8 @@ describe('Capabilities', { tags: '@serverless' }, () => { }, }, { - name: 'User with siem v4 role', - loginAs: 'siemV4', + name: 'User with siem v5 role', + loginAs: 'siemV5', setup: () => { cy.task('createServerlessCustomRole', { roleDescriptor: { @@ -107,16 +107,16 @@ describe('Capabilities', { tags: '@serverless' }, () => { }, kibana: [ { - feature: { siemV4: ['all'], fleet: ['all'] }, + feature: { siemV5: ['all'], securitySolutionRulesV1: ['all'], fleet: ['all'] }, spaces: ['*'], }, ], }, - roleName: 'siemV4', + roleName: 'siemV5', }); }, teardown: () => { - cy.task('deleteServerlessCustomRole', 'siemV4'); + cy.task('deleteServerlessCustomRole', 'siemV5'); }, }, ]; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts index db83b42ce4122..f36c4128d8615 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts @@ -39,6 +39,7 @@ import { UPGRADE_ALL_RULES_BUTTON, } from '../../../../../screens/alerts_detection_rules'; import { login } from '../../../../../tasks/login'; +import { NOT_FOUND } from '../../../../../screens/common/page'; // Rule to test update const RULE_1_ID = 'rule_1'; @@ -101,11 +102,7 @@ describe( // and assert that rules cannot be selected and all // installation buttons are disabled cy.visit(`${APP_PATH}${RULES_ADD_PATH}`); - cy.get(INSTALL_ALL_RULES_BUTTON).should('be.disabled'); - cy.get(getInstallSingleRuleButtonByRuleId(UPDATED_RULE_1['security-rule'].rule_id)).should( - 'not.exist' - ); - cy.get(RULE_CHECKBOX).should('not.exist'); + cy.get(NOT_FOUND).should('exist'); }); it('should not be able to upgrade prebuilt rules', () => { diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts index 32e1978689e25..b0caea059577c 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts @@ -62,7 +62,8 @@ export const secAll: Role = { kibana: [ { feature: { - siemV4: ['all'], + siemV5: ['all'], + rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -100,7 +101,8 @@ export const secReadCasesAll: Role = { kibana: [ { feature: { - siemV4: ['read'], + siemV5: ['read'], + rules: ['read'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -137,7 +139,8 @@ export const secAllCasesOnlyReadDelete: Role = { kibana: [ { feature: { - siemV4: ['all'], + siemV5: ['all'], + rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -174,7 +177,8 @@ export const secAllCasesNoDelete: Role = { kibana: [ { feature: { - siemV4: ['all'], + siemV5: ['all'], + rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], diff --git a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts index 79ed16e5d9eef..a4fb526e76409 100644 --- a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts +++ b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts @@ -43,6 +43,7 @@ export default function ({ getService }: FtrProviderContext) { 'siemV2', 'siemV3', 'siemV4', + 'siemV5', ]; const features = Object.fromEntries( @@ -239,14 +240,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readActionsLogManagement", "ui:siem/writeActionsLogManagement", "ui:siem/readActionsLogManagement", - "ui:siemV4/writeActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/writeActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "actions_log_management_read": Array [ "login:", "api:securitySolution-readActionsLogManagement", "ui:siem/readActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "all": Array [ "login:", @@ -254,17 +255,23 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:rac", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:timeline_write", "api:timeline_read", "api:notes_write", "api:notes_read", - "api:bulkGetUserProfiles", "api:securitySolution-entity-analytics", + "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:securitySolution-writeGlobalArtifacts", "api:securitySolution-showEndpointExceptions", @@ -325,6 +332,66 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-note/create", + "saved_object:siem-ui-timeline-note/bulk_create", + "saved_object:siem-ui-timeline-note/update", + "saved_object:siem-ui-timeline-note/bulk_update", + "saved_object:siem-ui-timeline-note/delete", + "saved_object:siem-ui-timeline-note/bulk_delete", + "saved_object:siem-ui-timeline-note/share_to_space", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/create", + "saved_object:siem-ui-timeline-pinned-event/bulk_create", + "saved_object:siem-ui-timeline-pinned-event/update", + "saved_object:siem-ui-timeline-pinned-event/bulk_update", + "saved_object:siem-ui-timeline-pinned-event/delete", + "saved_object:siem-ui-timeline-pinned-event/bulk_delete", + "saved_object:siem-ui-timeline-pinned-event/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -349,6 +416,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security-rule/delete", "saved_object:security-rule/bulk_delete", "saved_object:security-rule/share_to_space", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:siem-ui-timeline/create", + "saved_object:siem-ui-timeline/bulk_create", + "saved_object:siem-ui-timeline/update", + "saved_object:siem-ui-timeline/bulk_update", + "saved_object:siem-ui-timeline/delete", + "saved_object:siem-ui-timeline/bulk_delete", + "saved_object:siem-ui-timeline/share_to_space", "saved_object:endpoint:user-artifact-manifest/bulk_get", "saved_object:endpoint:user-artifact-manifest/get", "saved_object:endpoint:user-artifact-manifest/find", @@ -481,78 +560,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", - "saved_object:siem-ui-timeline-note/bulk_get", - "saved_object:siem-ui-timeline-note/get", - "saved_object:siem-ui-timeline-note/find", - "saved_object:siem-ui-timeline-note/open_point_in_time", - "saved_object:siem-ui-timeline-note/close_point_in_time", - "saved_object:siem-ui-timeline-note/create", - "saved_object:siem-ui-timeline-note/bulk_create", - "saved_object:siem-ui-timeline-note/update", - "saved_object:siem-ui-timeline-note/bulk_update", - "saved_object:siem-ui-timeline-note/delete", - "saved_object:siem-ui-timeline-note/bulk_delete", - "saved_object:siem-ui-timeline-note/share_to_space", - "saved_object:siem-ui-timeline-pinned-event/bulk_get", - "saved_object:siem-ui-timeline-pinned-event/get", - "saved_object:siem-ui-timeline-pinned-event/find", - "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/create", - "saved_object:siem-ui-timeline-pinned-event/bulk_create", - "saved_object:siem-ui-timeline-pinned-event/update", - "saved_object:siem-ui-timeline-pinned-event/bulk_update", - "saved_object:siem-ui-timeline-pinned-event/delete", - "saved_object:siem-ui-timeline-pinned-event/bulk_delete", - "saved_object:siem-ui-timeline-pinned-event/share_to_space", - "saved_object:siem-ui-timeline/bulk_get", - "saved_object:siem-ui-timeline/get", - "saved_object:siem-ui-timeline/find", - "saved_object:siem-ui-timeline/open_point_in_time", - "saved_object:siem-ui-timeline/close_point_in_time", - "saved_object:siem-ui-timeline/create", - "saved_object:siem-ui-timeline/bulk_create", - "saved_object:siem-ui-timeline/update", - "saved_object:siem-ui-timeline/bulk_update", - "saved_object:siem-ui-timeline/delete", - "saved_object:siem-ui-timeline/bulk_delete", - "saved_object:siem-ui-timeline/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -1100,16 +1107,20 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/securitySolutionNotes", "ui:securitySolutionNotes/read", "ui:securitySolutionNotes/crud", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/writeGlobalArtifacts", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/writeGlobalArtifacts", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "blocklist_all": Array [ "login:", @@ -1133,9 +1144,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siem/writeBlocklist", "ui:siem/readBlocklist", - "ui:siemV4/writeBlocklist", - "ui:siemV4/readBlocklist", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeBlocklist", + "ui:siemV5/readBlocklist", + "ui:siemV5/writeGlobalArtifacts", ], "blocklist_read": Array [ "login:", @@ -1143,7 +1154,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readBlocklist", "ui:siem/readBlocklist", - "ui:siemV4/readBlocklist", + "ui:siemV5/readBlocklist", ], "endpoint_exceptions_all": Array [ "login:", @@ -1167,9 +1178,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siem/showEndpointExceptions", "ui:siem/crudEndpointExceptions", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + "ui:siemV5/writeGlobalArtifacts", ], "endpoint_exceptions_read": Array [ "login:", @@ -1177,7 +1188,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-showEndpointExceptions", "ui:siem/showEndpointExceptions", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/showEndpointExceptions", ], "endpoint_list_all": Array [ "login:", @@ -1185,14 +1196,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readEndpointList", "ui:siem/writeEndpointList", "ui:siem/readEndpointList", - "ui:siemV4/writeEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/writeEndpointList", + "ui:siemV5/readEndpointList", ], "endpoint_list_read": Array [ "login:", "api:securitySolution-readEndpointList", "ui:siem/readEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/readEndpointList", ], "event_filters_all": Array [ "login:", @@ -1216,9 +1227,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siem/writeEventFilters", "ui:siem/readEventFilters", - "ui:siemV4/writeEventFilters", - "ui:siemV4/readEventFilters", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeEventFilters", + "ui:siemV5/readEventFilters", + "ui:siemV5/writeGlobalArtifacts", ], "event_filters_read": Array [ "login:", @@ -1226,19 +1237,19 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readEventFilters", "ui:siem/readEventFilters", - "ui:siemV4/readEventFilters", + "ui:siemV5/readEventFilters", ], "execute_operations_all": Array [ "login:", "api:securitySolution-writeExecuteOperations", "ui:siem/writeExecuteOperations", - "ui:siemV4/writeExecuteOperations", + "ui:siemV5/writeExecuteOperations", ], "file_operations_all": Array [ "login:", "api:securitySolution-writeFileOperations", "ui:siem/writeFileOperations", - "ui:siemV4/writeFileOperations", + "ui:siemV5/writeFileOperations", ], "host_isolation_all": Array [ "login:", @@ -1246,8 +1257,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-writeHostIsolation", "ui:siem/writeHostIsolationRelease", "ui:siem/writeHostIsolation", - "ui:siemV4/writeHostIsolationRelease", - "ui:siemV4/writeHostIsolation", + "ui:siemV5/writeHostIsolationRelease", + "ui:siemV5/writeHostIsolation", ], "host_isolation_exceptions_all": Array [ "login:", @@ -1275,11 +1286,11 @@ export default function ({ getService }: FtrProviderContext) { "ui:siem/deleteHostIsolationExceptions", "ui:siem/accessHostIsolationExceptions", "ui:siem/writeHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/deleteHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", - "ui:siemV4/writeHostIsolationExceptions", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/deleteHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + "ui:siemV5/writeHostIsolationExceptions", + "ui:siemV5/writeGlobalArtifacts", ], "host_isolation_exceptions_read": Array [ "login:", @@ -1289,8 +1300,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-accessHostIsolationExceptions", "ui:siem/readHostIsolationExceptions", "ui:siem/accessHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", ], "minimal_all": Array [ "login:", @@ -1298,17 +1309,23 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:rac", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:timeline_write", "api:timeline_read", "api:notes_write", "api:notes_read", - "api:bulkGetUserProfiles", "api:securitySolution-entity-analytics", + "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:securitySolution-writeGlobalArtifacts", "app:securitySolution", @@ -1367,6 +1384,66 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-note/create", + "saved_object:siem-ui-timeline-note/bulk_create", + "saved_object:siem-ui-timeline-note/update", + "saved_object:siem-ui-timeline-note/bulk_update", + "saved_object:siem-ui-timeline-note/delete", + "saved_object:siem-ui-timeline-note/bulk_delete", + "saved_object:siem-ui-timeline-note/share_to_space", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/create", + "saved_object:siem-ui-timeline-pinned-event/bulk_create", + "saved_object:siem-ui-timeline-pinned-event/update", + "saved_object:siem-ui-timeline-pinned-event/bulk_update", + "saved_object:siem-ui-timeline-pinned-event/delete", + "saved_object:siem-ui-timeline-pinned-event/bulk_delete", + "saved_object:siem-ui-timeline-pinned-event/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -1391,15 +1468,27 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security-rule/delete", "saved_object:security-rule/bulk_delete", "saved_object:security-rule/share_to_space", - "saved_object:endpoint:user-artifact-manifest/bulk_get", - "saved_object:endpoint:user-artifact-manifest/get", - "saved_object:endpoint:user-artifact-manifest/find", - "saved_object:endpoint:user-artifact-manifest/open_point_in_time", - "saved_object:endpoint:user-artifact-manifest/close_point_in_time", - "saved_object:endpoint:user-artifact-manifest/create", - "saved_object:endpoint:user-artifact-manifest/bulk_create", - "saved_object:endpoint:user-artifact-manifest/update", - "saved_object:endpoint:user-artifact-manifest/bulk_update", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", + "saved_object:siem-ui-timeline/create", + "saved_object:siem-ui-timeline/bulk_create", + "saved_object:siem-ui-timeline/update", + "saved_object:siem-ui-timeline/bulk_update", + "saved_object:siem-ui-timeline/delete", + "saved_object:siem-ui-timeline/bulk_delete", + "saved_object:siem-ui-timeline/share_to_space", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/create", + "saved_object:endpoint:user-artifact-manifest/bulk_create", + "saved_object:endpoint:user-artifact-manifest/update", + "saved_object:endpoint:user-artifact-manifest/bulk_update", "saved_object:endpoint:user-artifact-manifest/delete", "saved_object:endpoint:user-artifact-manifest/bulk_delete", "saved_object:endpoint:user-artifact-manifest/share_to_space", @@ -1523,78 +1612,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", - "saved_object:siem-ui-timeline-note/bulk_get", - "saved_object:siem-ui-timeline-note/get", - "saved_object:siem-ui-timeline-note/find", - "saved_object:siem-ui-timeline-note/open_point_in_time", - "saved_object:siem-ui-timeline-note/close_point_in_time", - "saved_object:siem-ui-timeline-note/create", - "saved_object:siem-ui-timeline-note/bulk_create", - "saved_object:siem-ui-timeline-note/update", - "saved_object:siem-ui-timeline-note/bulk_update", - "saved_object:siem-ui-timeline-note/delete", - "saved_object:siem-ui-timeline-note/bulk_delete", - "saved_object:siem-ui-timeline-note/share_to_space", - "saved_object:siem-ui-timeline-pinned-event/bulk_get", - "saved_object:siem-ui-timeline-pinned-event/get", - "saved_object:siem-ui-timeline-pinned-event/find", - "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/create", - "saved_object:siem-ui-timeline-pinned-event/bulk_create", - "saved_object:siem-ui-timeline-pinned-event/update", - "saved_object:siem-ui-timeline-pinned-event/bulk_update", - "saved_object:siem-ui-timeline-pinned-event/delete", - "saved_object:siem-ui-timeline-pinned-event/bulk_delete", - "saved_object:siem-ui-timeline-pinned-event/share_to_space", - "saved_object:siem-ui-timeline/bulk_get", - "saved_object:siem-ui-timeline/get", - "saved_object:siem-ui-timeline/find", - "saved_object:siem-ui-timeline/open_point_in_time", - "saved_object:siem-ui-timeline/close_point_in_time", - "saved_object:siem-ui-timeline/create", - "saved_object:siem-ui-timeline/bulk_create", - "saved_object:siem-ui-timeline/update", - "saved_object:siem-ui-timeline/bulk_update", - "saved_object:siem-ui-timeline/delete", - "saved_object:siem-ui-timeline/bulk_delete", - "saved_object:siem-ui-timeline/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -2140,25 +2157,33 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/securitySolutionNotes", "ui:securitySolutionNotes/read", "ui:securitySolutionNotes/crud", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "minimal_read": Array [ "login:", "api:securitySolution", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:rac", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:timeline_read", "api:notes_read", - "api:bulkGetUserProfiles", "api:securitySolution-entity-analytics", + "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", "app:csp", @@ -2183,6 +2208,31 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -2193,6 +2243,11 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security-rule/find", "saved_object:security-rule/open_point_in_time", "saved_object:security-rule/close_point_in_time", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", "saved_object:endpoint:user-artifact-manifest/bulk_get", "saved_object:endpoint:user-artifact-manifest/get", "saved_object:endpoint:user-artifact-manifest/find", @@ -2248,36 +2303,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:siem-ui-timeline-note/bulk_get", - "saved_object:siem-ui-timeline-note/get", - "saved_object:siem-ui-timeline-note/find", - "saved_object:siem-ui-timeline-note/open_point_in_time", - "saved_object:siem-ui-timeline-note/close_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/bulk_get", - "saved_object:siem-ui-timeline-pinned-event/get", - "saved_object:siem-ui-timeline-pinned-event/find", - "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", - "saved_object:siem-ui-timeline/bulk_get", - "saved_object:siem-ui-timeline/get", - "saved_object:siem-ui-timeline/find", - "saved_object:siem-ui-timeline/open_point_in_time", - "saved_object:siem-ui-timeline/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -2547,12 +2572,15 @@ export default function ({ getService }: FtrProviderContext) { "ui:securitySolutionTimeline/read", "ui:navLinks/securitySolutionNotes", "ui:securitySolutionNotes/read", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "policy_management_all": Array [ "login:", @@ -2572,8 +2600,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/share_to_space", "ui:siem/writePolicyManagement", "ui:siem/readPolicyManagement", - "ui:siemV4/writePolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/writePolicyManagement", + "ui:siemV5/readPolicyManagement", ], "policy_management_read": Array [ "login:", @@ -2584,25 +2612,29 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/open_point_in_time", "saved_object:policy-settings-protection-updates-note/close_point_in_time", "ui:siem/readPolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/readPolicyManagement", ], "process_operations_all": Array [ "login:", "api:securitySolution-writeProcessOperations", "ui:siem/writeProcessOperations", - "ui:siemV4/writeProcessOperations", + "ui:siemV5/writeProcessOperations", ], "read": Array [ "login:", "api:securitySolution", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:rac", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:timeline_read", "api:notes_read", - "api:bulkGetUserProfiles", "api:securitySolution-entity-analytics", + "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:lists-summary", "api:securitySolution-showEndpointExceptions", @@ -2629,6 +2661,31 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:siem-ui-timeline-note/bulk_get", + "saved_object:siem-ui-timeline-note/get", + "saved_object:siem-ui-timeline-note/find", + "saved_object:siem-ui-timeline-note/open_point_in_time", + "saved_object:siem-ui-timeline-note/close_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/bulk_get", + "saved_object:siem-ui-timeline-pinned-event/get", + "saved_object:siem-ui-timeline-pinned-event/find", + "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", + "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -2639,6 +2696,11 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security-rule/find", "saved_object:security-rule/open_point_in_time", "saved_object:security-rule/close_point_in_time", + "saved_object:siem-ui-timeline/bulk_get", + "saved_object:siem-ui-timeline/get", + "saved_object:siem-ui-timeline/find", + "saved_object:siem-ui-timeline/open_point_in_time", + "saved_object:siem-ui-timeline/close_point_in_time", "saved_object:endpoint:user-artifact-manifest/bulk_get", "saved_object:endpoint:user-artifact-manifest/get", "saved_object:endpoint:user-artifact-manifest/find", @@ -2694,36 +2756,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:siem-ui-timeline-note/bulk_get", - "saved_object:siem-ui-timeline-note/get", - "saved_object:siem-ui-timeline-note/find", - "saved_object:siem-ui-timeline-note/open_point_in_time", - "saved_object:siem-ui-timeline-note/close_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/bulk_get", - "saved_object:siem-ui-timeline-pinned-event/get", - "saved_object:siem-ui-timeline-pinned-event/find", - "saved_object:siem-ui-timeline-pinned-event/open_point_in_time", - "saved_object:siem-ui-timeline-pinned-event/close_point_in_time", - "saved_object:siem-ui-timeline/bulk_get", - "saved_object:siem-ui-timeline/get", - "saved_object:siem-ui-timeline/find", - "saved_object:siem-ui-timeline/open_point_in_time", - "saved_object:siem-ui-timeline/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -2994,19 +3026,22 @@ export default function ({ getService }: FtrProviderContext) { "ui:securitySolutionTimeline/read", "ui:navLinks/securitySolutionNotes", "ui:securitySolutionNotes/read", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/showEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "scan_operations_all": Array [ "login:", "api:securitySolution-writeScanOperations", "ui:siem/writeScanOperations", - "ui:siemV4/writeScanOperations", + "ui:siemV5/writeScanOperations", ], "trusted_applications_all": Array [ "login:", @@ -3030,9 +3065,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siem/writeTrustedApplications", "ui:siem/readTrustedApplications", - "ui:siemV4/writeTrustedApplications", - "ui:siemV4/readTrustedApplications", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeTrustedApplications", + "ui:siemV5/readTrustedApplications", + "ui:siemV5/writeGlobalArtifacts", ], "trusted_applications_read": Array [ "login:", @@ -3040,7 +3075,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedApplications", "ui:siem/readTrustedApplications", - "ui:siemV4/readTrustedApplications", + "ui:siemV5/readTrustedApplications", ], }, "siemV2": Object { @@ -3050,14 +3085,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readActionsLogManagement", "ui:siemV2/writeActionsLogManagement", "ui:siemV2/readActionsLogManagement", - "ui:siemV4/writeActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/writeActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "actions_log_management_read": Array [ "login:", "api:securitySolution-readActionsLogManagement", "ui:siemV2/readActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "all": Array [ "login:", @@ -3066,11 +3101,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:securitySolution-writeGlobalArtifacts", @@ -3132,13 +3173,49 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", - "saved_object:siem-detection-engine-rule-actions/bulk_get", - "saved_object:siem-detection-engine-rule-actions/get", - "saved_object:siem-detection-engine-rule-actions/find", - "saved_object:siem-detection-engine-rule-actions/open_point_in_time", - "saved_object:siem-detection-engine-rule-actions/close_point_in_time", - "saved_object:siem-detection-engine-rule-actions/create", - "saved_object:siem-detection-engine-rule-actions/bulk_create", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/create", + "saved_object:siem-detection-engine-rule-actions/bulk_create", "saved_object:siem-detection-engine-rule-actions/update", "saved_object:siem-detection-engine-rule-actions/bulk_update", "saved_object:siem-detection-engine-rule-actions/delete", @@ -3288,42 +3365,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -3849,16 +3890,20 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/writeGlobalArtifacts", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/writeGlobalArtifacts", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "blocklist_all": Array [ "login:", @@ -3882,9 +3927,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV2/writeBlocklist", "ui:siemV2/readBlocklist", - "ui:siemV4/writeBlocklist", - "ui:siemV4/readBlocklist", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeBlocklist", + "ui:siemV5/readBlocklist", + "ui:siemV5/writeGlobalArtifacts", ], "blocklist_read": Array [ "login:", @@ -3892,7 +3937,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readBlocklist", "ui:siemV2/readBlocklist", - "ui:siemV4/readBlocklist", + "ui:siemV5/readBlocklist", ], "endpoint_exceptions_all": Array [ "login:", @@ -3916,9 +3961,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV2/showEndpointExceptions", "ui:siemV2/crudEndpointExceptions", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + "ui:siemV5/writeGlobalArtifacts", ], "endpoint_exceptions_read": Array [ "login:", @@ -3926,7 +3971,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-showEndpointExceptions", "ui:siemV2/showEndpointExceptions", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/showEndpointExceptions", ], "endpoint_list_all": Array [ "login:", @@ -3934,14 +3979,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readEndpointList", "ui:siemV2/writeEndpointList", "ui:siemV2/readEndpointList", - "ui:siemV4/writeEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/writeEndpointList", + "ui:siemV5/readEndpointList", ], "endpoint_list_read": Array [ "login:", "api:securitySolution-readEndpointList", "ui:siemV2/readEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/readEndpointList", ], "event_filters_all": Array [ "login:", @@ -3965,9 +4010,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV2/writeEventFilters", "ui:siemV2/readEventFilters", - "ui:siemV4/writeEventFilters", - "ui:siemV4/readEventFilters", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeEventFilters", + "ui:siemV5/readEventFilters", + "ui:siemV5/writeGlobalArtifacts", ], "event_filters_read": Array [ "login:", @@ -3975,25 +4020,25 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readEventFilters", "ui:siemV2/readEventFilters", - "ui:siemV4/readEventFilters", + "ui:siemV5/readEventFilters", ], "execute_operations_all": Array [ "login:", "api:securitySolution-writeExecuteOperations", "ui:siemV2/writeExecuteOperations", - "ui:siemV4/writeExecuteOperations", + "ui:siemV5/writeExecuteOperations", ], "file_operations_all": Array [ "login:", "api:securitySolution-writeFileOperations", "ui:siemV2/writeFileOperations", - "ui:siemV4/writeFileOperations", + "ui:siemV5/writeFileOperations", ], "global_artifact_management_all": Array [ "login:", "api:securitySolution-writeGlobalArtifacts", "ui:siemV2/writeGlobalArtifacts", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeGlobalArtifacts", ], "host_isolation_all": Array [ "login:", @@ -4001,8 +4046,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-writeHostIsolation", "ui:siemV2/writeHostIsolationRelease", "ui:siemV2/writeHostIsolation", - "ui:siemV4/writeHostIsolationRelease", - "ui:siemV4/writeHostIsolation", + "ui:siemV5/writeHostIsolationRelease", + "ui:siemV5/writeHostIsolation", ], "host_isolation_exceptions_all": Array [ "login:", @@ -4030,11 +4075,11 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV2/deleteHostIsolationExceptions", "ui:siemV2/accessHostIsolationExceptions", "ui:siemV2/writeHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/deleteHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", - "ui:siemV4/writeHostIsolationExceptions", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/deleteHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + "ui:siemV5/writeHostIsolationExceptions", + "ui:siemV5/writeGlobalArtifacts", ], "host_isolation_exceptions_read": Array [ "login:", @@ -4044,8 +4089,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-accessHostIsolationExceptions", "ui:siemV2/readHostIsolationExceptions", "ui:siemV2/accessHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", ], "minimal_all": Array [ "login:", @@ -4054,11 +4099,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:securitySolution-writeGlobalArtifacts", @@ -4118,6 +4169,42 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -4274,42 +4361,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -4833,22 +4884,30 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "minimal_read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -4874,6 +4933,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -4939,21 +5013,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -5212,12 +5271,15 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "policy_management_all": Array [ "login:", @@ -5237,8 +5299,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/share_to_space", "ui:siemV2/writePolicyManagement", "ui:siemV2/readPolicyManagement", - "ui:siemV4/writePolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/writePolicyManagement", + "ui:siemV5/readPolicyManagement", ], "policy_management_read": Array [ "login:", @@ -5249,22 +5311,26 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/open_point_in_time", "saved_object:policy-settings-protection-updates-note/close_point_in_time", "ui:siemV2/readPolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/readPolicyManagement", ], "process_operations_all": Array [ "login:", "api:securitySolution-writeProcessOperations", "ui:siemV2/writeProcessOperations", - "ui:siemV4/writeProcessOperations", + "ui:siemV5/writeProcessOperations", ], "read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:lists-summary", @@ -5292,6 +5358,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -5357,21 +5438,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -5631,19 +5697,22 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/showEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "scan_operations_all": Array [ "login:", "api:securitySolution-writeScanOperations", "ui:siemV2/writeScanOperations", - "ui:siemV4/writeScanOperations", + "ui:siemV5/writeScanOperations", ], "trusted_applications_all": Array [ "login:", @@ -5667,9 +5736,9 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV2/writeTrustedApplications", "ui:siemV2/readTrustedApplications", - "ui:siemV4/writeTrustedApplications", - "ui:siemV4/readTrustedApplications", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeTrustedApplications", + "ui:siemV5/readTrustedApplications", + "ui:siemV5/writeGlobalArtifacts", ], "trusted_applications_read": Array [ "login:", @@ -5677,7 +5746,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedApplications", "ui:siemV2/readTrustedApplications", - "ui:siemV4/readTrustedApplications", + "ui:siemV5/readTrustedApplications", ], "workflow_insights_all": Array [ "login:", @@ -5685,14 +5754,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readWorkflowInsights", "ui:siemV2/writeWorkflowInsights", "ui:siemV2/readWorkflowInsights", - "ui:siemV4/writeWorkflowInsights", - "ui:siemV4/readWorkflowInsights", + "ui:siemV5/writeWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], "workflow_insights_read": Array [ "login:", "api:securitySolution-readWorkflowInsights", "ui:siemV2/readWorkflowInsights", - "ui:siemV4/readWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], }, "siemV3": Object { @@ -5702,14 +5771,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readActionsLogManagement", "ui:siemV3/writeActionsLogManagement", "ui:siemV3/readActionsLogManagement", - "ui:siemV4/writeActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/writeActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "actions_log_management_read": Array [ "login:", "api:securitySolution-readActionsLogManagement", "ui:siemV3/readActionsLogManagement", - "ui:siemV4/readActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "all": Array [ "login:", @@ -5718,11 +5787,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:securitySolution-showEndpointExceptions", @@ -5783,6 +5858,42 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -5939,42 +6050,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -6500,15 +6575,19 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "blocklist_all": Array [ "login:", @@ -6531,8 +6610,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV3/writeBlocklist", "ui:siemV3/readBlocklist", - "ui:siemV4/writeBlocklist", - "ui:siemV4/readBlocklist", + "ui:siemV5/writeBlocklist", + "ui:siemV5/readBlocklist", ], "blocklist_read": Array [ "login:", @@ -6540,7 +6619,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readBlocklist", "ui:siemV3/readBlocklist", - "ui:siemV4/readBlocklist", + "ui:siemV5/readBlocklist", ], "endpoint_exceptions_all": Array [ "login:", @@ -6563,8 +6642,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV3/showEndpointExceptions", "ui:siemV3/crudEndpointExceptions", - "ui:siemV4/showEndpointExceptions", - "ui:siemV4/crudEndpointExceptions", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", ], "endpoint_exceptions_read": Array [ "login:", @@ -6572,7 +6651,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-showEndpointExceptions", "ui:siemV3/showEndpointExceptions", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/showEndpointExceptions", ], "endpoint_list_all": Array [ "login:", @@ -6580,14 +6659,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readEndpointList", "ui:siemV3/writeEndpointList", "ui:siemV3/readEndpointList", - "ui:siemV4/writeEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/writeEndpointList", + "ui:siemV5/readEndpointList", ], "endpoint_list_read": Array [ "login:", "api:securitySolution-readEndpointList", "ui:siemV3/readEndpointList", - "ui:siemV4/readEndpointList", + "ui:siemV5/readEndpointList", ], "event_filters_all": Array [ "login:", @@ -6610,8 +6689,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV3/writeEventFilters", "ui:siemV3/readEventFilters", - "ui:siemV4/writeEventFilters", - "ui:siemV4/readEventFilters", + "ui:siemV5/writeEventFilters", + "ui:siemV5/readEventFilters", ], "event_filters_read": Array [ "login:", @@ -6619,25 +6698,25 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readEventFilters", "ui:siemV3/readEventFilters", - "ui:siemV4/readEventFilters", + "ui:siemV5/readEventFilters", ], "execute_operations_all": Array [ "login:", "api:securitySolution-writeExecuteOperations", "ui:siemV3/writeExecuteOperations", - "ui:siemV4/writeExecuteOperations", + "ui:siemV5/writeExecuteOperations", ], "file_operations_all": Array [ "login:", "api:securitySolution-writeFileOperations", "ui:siemV3/writeFileOperations", - "ui:siemV4/writeFileOperations", + "ui:siemV5/writeFileOperations", ], "global_artifact_management_all": Array [ "login:", "api:securitySolution-writeGlobalArtifacts", "ui:siemV3/writeGlobalArtifacts", - "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeGlobalArtifacts", ], "host_isolation_all": Array [ "login:", @@ -6645,8 +6724,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-writeHostIsolation", "ui:siemV3/writeHostIsolationRelease", "ui:siemV3/writeHostIsolation", - "ui:siemV4/writeHostIsolationRelease", - "ui:siemV4/writeHostIsolation", + "ui:siemV5/writeHostIsolationRelease", + "ui:siemV5/writeHostIsolation", ], "host_isolation_exceptions_all": Array [ "login:", @@ -6673,10 +6752,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV3/deleteHostIsolationExceptions", "ui:siemV3/accessHostIsolationExceptions", "ui:siemV3/writeHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/deleteHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", - "ui:siemV4/writeHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/deleteHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + "ui:siemV5/writeHostIsolationExceptions", ], "host_isolation_exceptions_read": Array [ "login:", @@ -6686,8 +6765,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-accessHostIsolationExceptions", "ui:siemV3/readHostIsolationExceptions", "ui:siemV3/accessHostIsolationExceptions", - "ui:siemV4/readHostIsolationExceptions", - "ui:siemV4/accessHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", ], "minimal_all": Array [ "login:", @@ -6696,11 +6775,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -6759,6 +6844,42 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -6915,42 +7036,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -7474,22 +7559,30 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", - "ui:siemV4/show", - "ui:siemV4/crud", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "minimal_read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -7515,6 +7608,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -7580,21 +7688,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -7853,12 +7946,15 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "policy_management_all": Array [ "login:", @@ -7878,8 +7974,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/share_to_space", "ui:siemV3/writePolicyManagement", "ui:siemV3/readPolicyManagement", - "ui:siemV4/writePolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/writePolicyManagement", + "ui:siemV5/readPolicyManagement", ], "policy_management_read": Array [ "login:", @@ -7890,22 +7986,26 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/open_point_in_time", "saved_object:policy-settings-protection-updates-note/close_point_in_time", "ui:siemV3/readPolicyManagement", - "ui:siemV4/readPolicyManagement", + "ui:siemV5/readPolicyManagement", ], "process_operations_all": Array [ "login:", "api:securitySolution-writeProcessOperations", "ui:siemV3/writeProcessOperations", - "ui:siemV4/writeProcessOperations", + "ui:siemV5/writeProcessOperations", ], "read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "api:lists-summary", @@ -7933,12 +8033,27 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", - "saved_object:siem-detection-engine-rule-actions/bulk_get", - "saved_object:siem-detection-engine-rule-actions/get", - "saved_object:siem-detection-engine-rule-actions/find", - "saved_object:siem-detection-engine-rule-actions/open_point_in_time", - "saved_object:siem-detection-engine-rule-actions/close_point_in_time", - "saved_object:security-rule/bulk_get", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:security-rule/bulk_get", "saved_object:security-rule/get", "saved_object:security-rule/find", "saved_object:security-rule/open_point_in_time", @@ -7998,21 +8113,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -8272,19 +8372,22 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", - "ui:siemV4/show", - "ui:siemV4/entity-analytics", - "ui:siemV4/detections", - "ui:siemV4/investigation-guide", - "ui:siemV4/investigation-guide-interactions", - "ui:siemV4/threat-intelligence", - "ui:siemV4/showEndpointExceptions", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:siemV5/showEndpointExceptions", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "scan_operations_all": Array [ "login:", "api:securitySolution-writeScanOperations", "ui:siemV3/writeScanOperations", - "ui:siemV4/writeScanOperations", + "ui:siemV5/writeScanOperations", ], "trusted_applications_all": Array [ "login:", @@ -8307,8 +8410,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV3/writeTrustedApplications", "ui:siemV3/readTrustedApplications", - "ui:siemV4/writeTrustedApplications", - "ui:siemV4/readTrustedApplications", + "ui:siemV5/writeTrustedApplications", + "ui:siemV5/readTrustedApplications", ], "trusted_applications_read": Array [ "login:", @@ -8316,7 +8419,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedApplications", "ui:siemV3/readTrustedApplications", - "ui:siemV4/readTrustedApplications", + "ui:siemV5/readTrustedApplications", ], "trusted_devices_all": Array [ "login:", @@ -8339,8 +8442,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV3/writeTrustedDevices", "ui:siemV3/readTrustedDevices", - "ui:siemV4/writeTrustedDevices", - "ui:siemV4/readTrustedDevices", + "ui:siemV5/writeTrustedDevices", + "ui:siemV5/readTrustedDevices", ], "trusted_devices_read": Array [ "login:", @@ -8348,7 +8451,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedDevices", "ui:siemV3/readTrustedDevices", - "ui:siemV4/readTrustedDevices", + "ui:siemV5/readTrustedDevices", ], "workflow_insights_all": Array [ "login:", @@ -8356,14 +8459,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readWorkflowInsights", "ui:siemV3/writeWorkflowInsights", "ui:siemV3/readWorkflowInsights", - "ui:siemV4/writeWorkflowInsights", - "ui:siemV4/readWorkflowInsights", + "ui:siemV5/writeWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], "workflow_insights_read": Array [ "login:", "api:securitySolution-readWorkflowInsights", "ui:siemV3/readWorkflowInsights", - "ui:siemV4/readWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], }, "siemV4": Object { @@ -8373,11 +8476,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readActionsLogManagement", "ui:siemV4/writeActionsLogManagement", "ui:siemV4/readActionsLogManagement", + "ui:siemV5/writeActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "actions_log_management_read": Array [ "login:", "api:securitySolution-readActionsLogManagement", "ui:siemV4/readActionsLogManagement", + "ui:siemV5/readActionsLogManagement", ], "all": Array [ "login:", @@ -8386,11 +8492,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -8449,6 +8561,42 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -8605,42 +8753,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -9164,6 +9276,17 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "blocklist_all": Array [ "login:", @@ -9186,6 +9309,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV4/writeBlocklist", "ui:siemV4/readBlocklist", + "ui:siemV5/writeBlocklist", + "ui:siemV5/readBlocklist", ], "blocklist_read": Array [ "login:", @@ -9193,6 +9318,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readBlocklist", "ui:siemV4/readBlocklist", + "ui:siemV5/readBlocklist", ], "endpoint_exceptions_all": Array [ "login:", @@ -9215,6 +9341,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV4/showEndpointExceptions", "ui:siemV4/crudEndpointExceptions", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", ], "endpoint_exceptions_read": Array [ "login:", @@ -9222,6 +9350,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-showEndpointExceptions", "ui:siemV4/showEndpointExceptions", + "ui:siemV5/showEndpointExceptions", ], "endpoint_list_all": Array [ "login:", @@ -9229,11 +9358,14 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readEndpointList", "ui:siemV4/writeEndpointList", "ui:siemV4/readEndpointList", + "ui:siemV5/writeEndpointList", + "ui:siemV5/readEndpointList", ], "endpoint_list_read": Array [ "login:", "api:securitySolution-readEndpointList", "ui:siemV4/readEndpointList", + "ui:siemV5/readEndpointList", ], "event_filters_all": Array [ "login:", @@ -9256,6 +9388,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV4/writeEventFilters", "ui:siemV4/readEventFilters", + "ui:siemV5/writeEventFilters", + "ui:siemV5/readEventFilters", ], "event_filters_read": Array [ "login:", @@ -9263,21 +9397,25 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readEventFilters", "ui:siemV4/readEventFilters", + "ui:siemV5/readEventFilters", ], "execute_operations_all": Array [ "login:", "api:securitySolution-writeExecuteOperations", "ui:siemV4/writeExecuteOperations", + "ui:siemV5/writeExecuteOperations", ], "file_operations_all": Array [ "login:", "api:securitySolution-writeFileOperations", "ui:siemV4/writeFileOperations", + "ui:siemV5/writeFileOperations", ], "global_artifact_management_all": Array [ "login:", "api:securitySolution-writeGlobalArtifacts", "ui:siemV4/writeGlobalArtifacts", + "ui:siemV5/writeGlobalArtifacts", ], "host_isolation_all": Array [ "login:", @@ -9285,6 +9423,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-writeHostIsolation", "ui:siemV4/writeHostIsolationRelease", "ui:siemV4/writeHostIsolation", + "ui:siemV5/writeHostIsolationRelease", + "ui:siemV5/writeHostIsolation", ], "host_isolation_exceptions_all": Array [ "login:", @@ -9311,6 +9451,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV4/deleteHostIsolationExceptions", "ui:siemV4/accessHostIsolationExceptions", "ui:siemV4/writeHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/deleteHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + "ui:siemV5/writeHostIsolationExceptions", ], "host_isolation_exceptions_read": Array [ "login:", @@ -9320,6 +9464,8 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-accessHostIsolationExceptions", "ui:siemV4/readHostIsolationExceptions", "ui:siemV4/accessHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", ], "minimal_all": Array [ "login:", @@ -9328,11 +9474,17 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-all", "api:lists-read", "api:lists-summary", + "api:rules-all", + "api:rules-read", + "api:alerts-all", + "api:alerts-read", + "api:exceptions-all", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-all", "api:cloud-security-posture-read", - "api:cloud-defend-all", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -9391,6 +9543,42 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/delete", "saved_object:index-pattern/bulk_delete", "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -9547,42 +9735,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/delete", "saved_object:security:reference-data/bulk_delete", "saved_object:security:reference-data/share_to_space", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:csp_rule/create", - "saved_object:csp_rule/bulk_create", - "saved_object:csp_rule/update", - "saved_object:csp_rule/bulk_update", - "saved_object:csp_rule/delete", - "saved_object:csp_rule/bulk_delete", - "saved_object:csp_rule/share_to_space", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:cloud-security-posture-settings/create", - "saved_object:cloud-security-posture-settings/bulk_create", - "saved_object:cloud-security-posture-settings/update", - "saved_object:cloud-security-posture-settings/bulk_update", - "saved_object:cloud-security-posture-settings/delete", - "saved_object:cloud-security-posture-settings/bulk_delete", - "saved_object:cloud-security-posture-settings/share_to_space", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", - "saved_object:csp-rule-template/create", - "saved_object:csp-rule-template/bulk_create", - "saved_object:csp-rule-template/update", - "saved_object:csp-rule-template/bulk_update", - "saved_object:csp-rule-template/delete", - "saved_object:csp-rule-template/bulk_delete", - "saved_object:csp-rule-template/share_to_space", "saved_object:telemetry/bulk_get", "saved_object:telemetry/get", "saved_object:telemetry/find", @@ -9643,6 +9795,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.notifications/siem/rule/delete", "alerting:siem.notifications/siem/rule/update", "alerting:siem.notifications/siem/rule/updateApiKey", + "alerting:siem.notifications/siem/rule/enable", + "alerting:siem.notifications/siem/rule/disable", "alerting:siem.notifications/siem/rule/muteAll", "alerting:siem.notifications/siem/rule/unmuteAll", "alerting:siem.notifications/siem/rule/muteAlert", @@ -9650,15 +9804,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.notifications/siem/rule/snooze", "alerting:siem.notifications/siem/rule/bulkEdit", "alerting:siem.notifications/siem/rule/bulkDelete", - "alerting:siem.notifications/siem/rule/unsnooze", - "alerting:siem.notifications/siem/rule/runSoon", - "alerting:siem.notifications/siem/rule/enable", - "alerting:siem.notifications/siem/rule/disable", "alerting:siem.notifications/siem/rule/bulkEnable", "alerting:siem.notifications/siem/rule/bulkDisable", + "alerting:siem.notifications/siem/rule/unsnooze", + "alerting:siem.notifications/siem/rule/runSoon", + "alerting:siem.notifications/siem/rule/scheduleBackfill", "alerting:siem.notifications/siem/rule/deleteBackfill", "alerting:siem.notifications/siem/rule/fillGaps", - "alerting:siem.notifications/siem/rule/scheduleBackfill", "alerting:siem.esqlRule/siem/rule/get", "alerting:siem.esqlRule/siem/rule/bulkGet", "alerting:siem.esqlRule/siem/rule/getRuleState", @@ -9675,6 +9827,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.esqlRule/siem/rule/delete", "alerting:siem.esqlRule/siem/rule/update", "alerting:siem.esqlRule/siem/rule/updateApiKey", + "alerting:siem.esqlRule/siem/rule/enable", + "alerting:siem.esqlRule/siem/rule/disable", "alerting:siem.esqlRule/siem/rule/muteAll", "alerting:siem.esqlRule/siem/rule/unmuteAll", "alerting:siem.esqlRule/siem/rule/muteAlert", @@ -9682,15 +9836,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.esqlRule/siem/rule/snooze", "alerting:siem.esqlRule/siem/rule/bulkEdit", "alerting:siem.esqlRule/siem/rule/bulkDelete", - "alerting:siem.esqlRule/siem/rule/unsnooze", - "alerting:siem.esqlRule/siem/rule/runSoon", - "alerting:siem.esqlRule/siem/rule/enable", - "alerting:siem.esqlRule/siem/rule/disable", "alerting:siem.esqlRule/siem/rule/bulkEnable", "alerting:siem.esqlRule/siem/rule/bulkDisable", + "alerting:siem.esqlRule/siem/rule/unsnooze", + "alerting:siem.esqlRule/siem/rule/runSoon", + "alerting:siem.esqlRule/siem/rule/scheduleBackfill", "alerting:siem.esqlRule/siem/rule/deleteBackfill", "alerting:siem.esqlRule/siem/rule/fillGaps", - "alerting:siem.esqlRule/siem/rule/scheduleBackfill", "alerting:siem.eqlRule/siem/rule/get", "alerting:siem.eqlRule/siem/rule/bulkGet", "alerting:siem.eqlRule/siem/rule/getRuleState", @@ -9707,6 +9859,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.eqlRule/siem/rule/delete", "alerting:siem.eqlRule/siem/rule/update", "alerting:siem.eqlRule/siem/rule/updateApiKey", + "alerting:siem.eqlRule/siem/rule/enable", + "alerting:siem.eqlRule/siem/rule/disable", "alerting:siem.eqlRule/siem/rule/muteAll", "alerting:siem.eqlRule/siem/rule/unmuteAll", "alerting:siem.eqlRule/siem/rule/muteAlert", @@ -9714,15 +9868,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.eqlRule/siem/rule/snooze", "alerting:siem.eqlRule/siem/rule/bulkEdit", "alerting:siem.eqlRule/siem/rule/bulkDelete", - "alerting:siem.eqlRule/siem/rule/unsnooze", - "alerting:siem.eqlRule/siem/rule/runSoon", - "alerting:siem.eqlRule/siem/rule/enable", - "alerting:siem.eqlRule/siem/rule/disable", "alerting:siem.eqlRule/siem/rule/bulkEnable", "alerting:siem.eqlRule/siem/rule/bulkDisable", + "alerting:siem.eqlRule/siem/rule/unsnooze", + "alerting:siem.eqlRule/siem/rule/runSoon", + "alerting:siem.eqlRule/siem/rule/scheduleBackfill", "alerting:siem.eqlRule/siem/rule/deleteBackfill", "alerting:siem.eqlRule/siem/rule/fillGaps", - "alerting:siem.eqlRule/siem/rule/scheduleBackfill", "alerting:siem.indicatorRule/siem/rule/get", "alerting:siem.indicatorRule/siem/rule/bulkGet", "alerting:siem.indicatorRule/siem/rule/getRuleState", @@ -9739,6 +9891,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.indicatorRule/siem/rule/delete", "alerting:siem.indicatorRule/siem/rule/update", "alerting:siem.indicatorRule/siem/rule/updateApiKey", + "alerting:siem.indicatorRule/siem/rule/enable", + "alerting:siem.indicatorRule/siem/rule/disable", "alerting:siem.indicatorRule/siem/rule/muteAll", "alerting:siem.indicatorRule/siem/rule/unmuteAll", "alerting:siem.indicatorRule/siem/rule/muteAlert", @@ -9746,15 +9900,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.indicatorRule/siem/rule/snooze", "alerting:siem.indicatorRule/siem/rule/bulkEdit", "alerting:siem.indicatorRule/siem/rule/bulkDelete", - "alerting:siem.indicatorRule/siem/rule/unsnooze", - "alerting:siem.indicatorRule/siem/rule/runSoon", - "alerting:siem.indicatorRule/siem/rule/enable", - "alerting:siem.indicatorRule/siem/rule/disable", "alerting:siem.indicatorRule/siem/rule/bulkEnable", "alerting:siem.indicatorRule/siem/rule/bulkDisable", + "alerting:siem.indicatorRule/siem/rule/unsnooze", + "alerting:siem.indicatorRule/siem/rule/runSoon", + "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", "alerting:siem.indicatorRule/siem/rule/deleteBackfill", "alerting:siem.indicatorRule/siem/rule/fillGaps", - "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", "alerting:siem.mlRule/siem/rule/get", "alerting:siem.mlRule/siem/rule/bulkGet", "alerting:siem.mlRule/siem/rule/getRuleState", @@ -9771,6 +9923,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.mlRule/siem/rule/delete", "alerting:siem.mlRule/siem/rule/update", "alerting:siem.mlRule/siem/rule/updateApiKey", + "alerting:siem.mlRule/siem/rule/enable", + "alerting:siem.mlRule/siem/rule/disable", "alerting:siem.mlRule/siem/rule/muteAll", "alerting:siem.mlRule/siem/rule/unmuteAll", "alerting:siem.mlRule/siem/rule/muteAlert", @@ -9778,15 +9932,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.mlRule/siem/rule/snooze", "alerting:siem.mlRule/siem/rule/bulkEdit", "alerting:siem.mlRule/siem/rule/bulkDelete", - "alerting:siem.mlRule/siem/rule/unsnooze", - "alerting:siem.mlRule/siem/rule/runSoon", - "alerting:siem.mlRule/siem/rule/enable", - "alerting:siem.mlRule/siem/rule/disable", "alerting:siem.mlRule/siem/rule/bulkEnable", "alerting:siem.mlRule/siem/rule/bulkDisable", + "alerting:siem.mlRule/siem/rule/unsnooze", + "alerting:siem.mlRule/siem/rule/runSoon", + "alerting:siem.mlRule/siem/rule/scheduleBackfill", "alerting:siem.mlRule/siem/rule/deleteBackfill", "alerting:siem.mlRule/siem/rule/fillGaps", - "alerting:siem.mlRule/siem/rule/scheduleBackfill", "alerting:siem.queryRule/siem/rule/get", "alerting:siem.queryRule/siem/rule/bulkGet", "alerting:siem.queryRule/siem/rule/getRuleState", @@ -9803,6 +9955,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.queryRule/siem/rule/delete", "alerting:siem.queryRule/siem/rule/update", "alerting:siem.queryRule/siem/rule/updateApiKey", + "alerting:siem.queryRule/siem/rule/enable", + "alerting:siem.queryRule/siem/rule/disable", "alerting:siem.queryRule/siem/rule/muteAll", "alerting:siem.queryRule/siem/rule/unmuteAll", "alerting:siem.queryRule/siem/rule/muteAlert", @@ -9810,15 +9964,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.queryRule/siem/rule/snooze", "alerting:siem.queryRule/siem/rule/bulkEdit", "alerting:siem.queryRule/siem/rule/bulkDelete", - "alerting:siem.queryRule/siem/rule/unsnooze", - "alerting:siem.queryRule/siem/rule/runSoon", - "alerting:siem.queryRule/siem/rule/enable", - "alerting:siem.queryRule/siem/rule/disable", "alerting:siem.queryRule/siem/rule/bulkEnable", "alerting:siem.queryRule/siem/rule/bulkDisable", + "alerting:siem.queryRule/siem/rule/unsnooze", + "alerting:siem.queryRule/siem/rule/runSoon", + "alerting:siem.queryRule/siem/rule/scheduleBackfill", "alerting:siem.queryRule/siem/rule/deleteBackfill", "alerting:siem.queryRule/siem/rule/fillGaps", - "alerting:siem.queryRule/siem/rule/scheduleBackfill", "alerting:siem.savedQueryRule/siem/rule/get", "alerting:siem.savedQueryRule/siem/rule/bulkGet", "alerting:siem.savedQueryRule/siem/rule/getRuleState", @@ -9835,6 +9987,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.savedQueryRule/siem/rule/delete", "alerting:siem.savedQueryRule/siem/rule/update", "alerting:siem.savedQueryRule/siem/rule/updateApiKey", + "alerting:siem.savedQueryRule/siem/rule/enable", + "alerting:siem.savedQueryRule/siem/rule/disable", "alerting:siem.savedQueryRule/siem/rule/muteAll", "alerting:siem.savedQueryRule/siem/rule/unmuteAll", "alerting:siem.savedQueryRule/siem/rule/muteAlert", @@ -9842,15 +9996,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.savedQueryRule/siem/rule/snooze", "alerting:siem.savedQueryRule/siem/rule/bulkEdit", "alerting:siem.savedQueryRule/siem/rule/bulkDelete", - "alerting:siem.savedQueryRule/siem/rule/unsnooze", - "alerting:siem.savedQueryRule/siem/rule/runSoon", - "alerting:siem.savedQueryRule/siem/rule/enable", - "alerting:siem.savedQueryRule/siem/rule/disable", "alerting:siem.savedQueryRule/siem/rule/bulkEnable", "alerting:siem.savedQueryRule/siem/rule/bulkDisable", + "alerting:siem.savedQueryRule/siem/rule/unsnooze", + "alerting:siem.savedQueryRule/siem/rule/runSoon", + "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", "alerting:siem.savedQueryRule/siem/rule/fillGaps", - "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", "alerting:siem.thresholdRule/siem/rule/get", "alerting:siem.thresholdRule/siem/rule/bulkGet", "alerting:siem.thresholdRule/siem/rule/getRuleState", @@ -9867,6 +10019,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.thresholdRule/siem/rule/delete", "alerting:siem.thresholdRule/siem/rule/update", "alerting:siem.thresholdRule/siem/rule/updateApiKey", + "alerting:siem.thresholdRule/siem/rule/enable", + "alerting:siem.thresholdRule/siem/rule/disable", "alerting:siem.thresholdRule/siem/rule/muteAll", "alerting:siem.thresholdRule/siem/rule/unmuteAll", "alerting:siem.thresholdRule/siem/rule/muteAlert", @@ -9874,15 +10028,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.thresholdRule/siem/rule/snooze", "alerting:siem.thresholdRule/siem/rule/bulkEdit", "alerting:siem.thresholdRule/siem/rule/bulkDelete", - "alerting:siem.thresholdRule/siem/rule/unsnooze", - "alerting:siem.thresholdRule/siem/rule/runSoon", - "alerting:siem.thresholdRule/siem/rule/enable", - "alerting:siem.thresholdRule/siem/rule/disable", "alerting:siem.thresholdRule/siem/rule/bulkEnable", "alerting:siem.thresholdRule/siem/rule/bulkDisable", + "alerting:siem.thresholdRule/siem/rule/unsnooze", + "alerting:siem.thresholdRule/siem/rule/runSoon", + "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", "alerting:siem.thresholdRule/siem/rule/deleteBackfill", "alerting:siem.thresholdRule/siem/rule/fillGaps", - "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", "alerting:siem.newTermsRule/siem/rule/get", "alerting:siem.newTermsRule/siem/rule/bulkGet", "alerting:siem.newTermsRule/siem/rule/getRuleState", @@ -9899,6 +10051,8 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.newTermsRule/siem/rule/delete", "alerting:siem.newTermsRule/siem/rule/update", "alerting:siem.newTermsRule/siem/rule/updateApiKey", + "alerting:siem.newTermsRule/siem/rule/enable", + "alerting:siem.newTermsRule/siem/rule/disable", "alerting:siem.newTermsRule/siem/rule/muteAll", "alerting:siem.newTermsRule/siem/rule/unmuteAll", "alerting:siem.newTermsRule/siem/rule/muteAlert", @@ -9906,15 +10060,13 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.newTermsRule/siem/rule/snooze", "alerting:siem.newTermsRule/siem/rule/bulkEdit", "alerting:siem.newTermsRule/siem/rule/bulkDelete", - "alerting:siem.newTermsRule/siem/rule/unsnooze", - "alerting:siem.newTermsRule/siem/rule/runSoon", - "alerting:siem.newTermsRule/siem/rule/enable", - "alerting:siem.newTermsRule/siem/rule/disable", "alerting:siem.newTermsRule/siem/rule/bulkEnable", "alerting:siem.newTermsRule/siem/rule/bulkDisable", + "alerting:siem.newTermsRule/siem/rule/unsnooze", + "alerting:siem.newTermsRule/siem/rule/runSoon", + "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", "alerting:siem.newTermsRule/siem/rule/deleteBackfill", "alerting:siem.newTermsRule/siem/rule/fillGaps", - "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", "alerting:siem.notifications/siem/alert/get", "alerting:siem.notifications/siem/alert/find", "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", @@ -10106,15 +10258,30 @@ export default function ({ getService }: FtrProviderContext) { "ui:visualize_v2/save", "ui:visualize_v2/createShortUrl", "ui:visualize_v2/generateScreenshot", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/edit_rules", + "ui:securitySolutionRulesV1/detections", ], "minimal_read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -10140,6 +10307,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -10205,21 +10387,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -10478,6 +10645,15 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "policy_management_all": Array [ "login:", @@ -10497,6 +10673,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/share_to_space", "ui:siemV4/writePolicyManagement", "ui:siemV4/readPolicyManagement", + "ui:siemV5/writePolicyManagement", + "ui:siemV5/readPolicyManagement", ], "policy_management_read": Array [ "login:", @@ -10507,20 +10685,26 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:policy-settings-protection-updates-note/open_point_in_time", "saved_object:policy-settings-protection-updates-note/close_point_in_time", "ui:siemV4/readPolicyManagement", + "ui:siemV5/readPolicyManagement", ], "process_operations_all": Array [ "login:", "api:securitySolution-writeProcessOperations", "ui:siemV4/writeProcessOperations", + "ui:siemV5/writeProcessOperations", ], "read": Array [ "login:", "api:securitySolution", "api:rac", "api:lists-read", + "api:rules-read", + "api:alerts-read", + "api:exceptions-read", + "api:users-read", + "api:initialize-security-solution", "api:securitySolution-entity-analytics", "api:cloud-security-posture-read", - "api:cloud-defend-read", "api:bulkGetUserProfiles", "api:securitySolution-threat-intelligence", "app:securitySolution", @@ -10546,6 +10730,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:index-pattern/find", "saved_object:index-pattern/open_point_in_time", "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", "saved_object:siem-detection-engine-rule-actions/bulk_get", "saved_object:siem-detection-engine-rule-actions/get", "saved_object:siem-detection-engine-rule-actions/find", @@ -10611,21 +10810,6 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:security:reference-data/find", "saved_object:security:reference-data/open_point_in_time", "saved_object:security:reference-data/close_point_in_time", - "saved_object:csp_rule/bulk_get", - "saved_object:csp_rule/get", - "saved_object:csp_rule/find", - "saved_object:csp_rule/open_point_in_time", - "saved_object:csp_rule/close_point_in_time", - "saved_object:cloud-security-posture-settings/bulk_get", - "saved_object:cloud-security-posture-settings/get", - "saved_object:cloud-security-posture-settings/find", - "saved_object:cloud-security-posture-settings/open_point_in_time", - "saved_object:cloud-security-posture-settings/close_point_in_time", - "saved_object:csp-rule-template/bulk_get", - "saved_object:csp-rule-template/get", - "saved_object:csp-rule-template/find", - "saved_object:csp-rule-template/open_point_in_time", - "saved_object:csp-rule-template/close_point_in_time", "saved_object:config/bulk_get", "saved_object:config/get", "saved_object:config/find", @@ -10884,11 +11068,21 @@ export default function ({ getService }: FtrProviderContext) { "ui:navLinks/lens", "ui:visualize_v2/show", "ui:visualize_v2/createShortUrl", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "ui:navLinks/securitySolutionRulesV1", + "ui:securitySolutionRulesV1/read_rules", + "ui:securitySolutionRulesV1/detections", ], "scan_operations_all": Array [ "login:", "api:securitySolution-writeScanOperations", "ui:siemV4/writeScanOperations", + "ui:siemV5/writeScanOperations", ], "trusted_applications_all": Array [ "login:", @@ -10911,6 +11105,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV4/writeTrustedApplications", "ui:siemV4/readTrustedApplications", + "ui:siemV5/writeTrustedApplications", + "ui:siemV5/readTrustedApplications", ], "trusted_applications_read": Array [ "login:", @@ -10918,6 +11114,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedApplications", "ui:siemV4/readTrustedApplications", + "ui:siemV5/readTrustedApplications", ], "trusted_devices_all": Array [ "login:", @@ -10940,6 +11137,8 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:exception-list-agnostic/share_to_space", "ui:siemV4/writeTrustedDevices", "ui:siemV4/readTrustedDevices", + "ui:siemV5/writeTrustedDevices", + "ui:siemV5/readTrustedDevices", ], "trusted_devices_read": Array [ "login:", @@ -10947,6 +11146,7 @@ export default function ({ getService }: FtrProviderContext) { "api:lists-summary", "api:securitySolution-readTrustedDevices", "ui:siemV4/readTrustedDevices", + "ui:siemV5/readTrustedDevices", ], "workflow_insights_all": Array [ "login:", @@ -10954,11 +11154,1900 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-readWorkflowInsights", "ui:siemV4/writeWorkflowInsights", "ui:siemV4/readWorkflowInsights", + "ui:siemV5/writeWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], "workflow_insights_read": Array [ "login:", "api:securitySolution-readWorkflowInsights", "ui:siemV4/readWorkflowInsights", + "ui:siemV5/readWorkflowInsights", + ], + }, + "siemV5": Object { + "actions_log_management_all": Array [ + "login:", + "api:securitySolution-writeActionsLogManagement", + "api:securitySolution-readActionsLogManagement", + "ui:siemV5/writeActionsLogManagement", + "ui:siemV5/readActionsLogManagement", + ], + "actions_log_management_read": Array [ + "login:", + "api:securitySolution-readActionsLogManagement", + "ui:siemV5/readActionsLogManagement", + ], + "all": Array [ + "login:", + "api:securitySolution", + "api:rac", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:users-read", + "api:initialize-security-solution", + "api:securitySolution-entity-analytics", + "api:cloud-security-posture-all", + "api:cloud-security-posture-read", + "api:bulkGetUserProfiles", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/kibana", + "saved_object:alert/bulk_get", + "saved_object:alert/get", + "saved_object:alert/find", + "saved_object:alert/open_point_in_time", + "saved_object:alert/close_point_in_time", + "saved_object:alert/create", + "saved_object:alert/bulk_create", + "saved_object:alert/update", + "saved_object:alert/bulk_update", + "saved_object:alert/delete", + "saved_object:alert/bulk_delete", + "saved_object:alert/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:index-pattern/create", + "saved_object:index-pattern/bulk_create", + "saved_object:index-pattern/update", + "saved_object:index-pattern/bulk_update", + "saved_object:index-pattern/delete", + "saved_object:index-pattern/bulk_delete", + "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/create", + "saved_object:siem-detection-engine-rule-actions/bulk_create", + "saved_object:siem-detection-engine-rule-actions/update", + "saved_object:siem-detection-engine-rule-actions/bulk_update", + "saved_object:siem-detection-engine-rule-actions/delete", + "saved_object:siem-detection-engine-rule-actions/bulk_delete", + "saved_object:siem-detection-engine-rule-actions/share_to_space", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/create", + "saved_object:endpoint:user-artifact-manifest/bulk_create", + "saved_object:endpoint:user-artifact-manifest/update", + "saved_object:endpoint:user-artifact-manifest/bulk_update", + "saved_object:endpoint:user-artifact-manifest/delete", + "saved_object:endpoint:user-artifact-manifest/bulk_delete", + "saved_object:endpoint:user-artifact-manifest/share_to_space", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/create", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_create", + "saved_object:endpoint:unified-user-artifact-manifest/update", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_update", + "saved_object:endpoint:unified-user-artifact-manifest/delete", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_delete", + "saved_object:endpoint:unified-user-artifact-manifest/share_to_space", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:security-solution-signals-migration/create", + "saved_object:security-solution-signals-migration/bulk_create", + "saved_object:security-solution-signals-migration/update", + "saved_object:security-solution-signals-migration/bulk_update", + "saved_object:security-solution-signals-migration/delete", + "saved_object:security-solution-signals-migration/bulk_delete", + "saved_object:security-solution-signals-migration/share_to_space", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:risk-engine-configuration/create", + "saved_object:risk-engine-configuration/bulk_create", + "saved_object:risk-engine-configuration/update", + "saved_object:risk-engine-configuration/bulk_update", + "saved_object:risk-engine-configuration/delete", + "saved_object:risk-engine-configuration/bulk_delete", + "saved_object:risk-engine-configuration/share_to_space", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:entity-engine-status/create", + "saved_object:entity-engine-status/bulk_create", + "saved_object:entity-engine-status/update", + "saved_object:entity-engine-status/bulk_update", + "saved_object:entity-engine-status/delete", + "saved_object:entity-engine-status/bulk_delete", + "saved_object:entity-engine-status/share_to_space", + "saved_object:privilege-monitoring-status/bulk_get", + "saved_object:privilege-monitoring-status/get", + "saved_object:privilege-monitoring-status/find", + "saved_object:privilege-monitoring-status/open_point_in_time", + "saved_object:privilege-monitoring-status/close_point_in_time", + "saved_object:privilege-monitoring-status/create", + "saved_object:privilege-monitoring-status/bulk_create", + "saved_object:privilege-monitoring-status/update", + "saved_object:privilege-monitoring-status/bulk_update", + "saved_object:privilege-monitoring-status/delete", + "saved_object:privilege-monitoring-status/bulk_delete", + "saved_object:privilege-monitoring-status/share_to_space", + "saved_object:privmon-api-key/bulk_get", + "saved_object:privmon-api-key/get", + "saved_object:privmon-api-key/find", + "saved_object:privmon-api-key/open_point_in_time", + "saved_object:privmon-api-key/close_point_in_time", + "saved_object:privmon-api-key/create", + "saved_object:privmon-api-key/bulk_create", + "saved_object:privmon-api-key/update", + "saved_object:privmon-api-key/bulk_update", + "saved_object:privmon-api-key/delete", + "saved_object:privmon-api-key/bulk_delete", + "saved_object:privmon-api-key/share_to_space", + "saved_object:entity-analytics-monitoring-entity-source/bulk_get", + "saved_object:entity-analytics-monitoring-entity-source/get", + "saved_object:entity-analytics-monitoring-entity-source/find", + "saved_object:entity-analytics-monitoring-entity-source/open_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/close_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/create", + "saved_object:entity-analytics-monitoring-entity-source/bulk_create", + "saved_object:entity-analytics-monitoring-entity-source/update", + "saved_object:entity-analytics-monitoring-entity-source/bulk_update", + "saved_object:entity-analytics-monitoring-entity-source/delete", + "saved_object:entity-analytics-monitoring-entity-source/bulk_delete", + "saved_object:entity-analytics-monitoring-entity-source/share_to_space", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "saved_object:security-ai-prompt/bulk_get", + "saved_object:security-ai-prompt/get", + "saved_object:security-ai-prompt/find", + "saved_object:security-ai-prompt/open_point_in_time", + "saved_object:security-ai-prompt/close_point_in_time", + "saved_object:security-ai-prompt/create", + "saved_object:security-ai-prompt/bulk_create", + "saved_object:security-ai-prompt/update", + "saved_object:security-ai-prompt/bulk_update", + "saved_object:security-ai-prompt/delete", + "saved_object:security-ai-prompt/bulk_delete", + "saved_object:security-ai-prompt/share_to_space", + "saved_object:security:reference-data/bulk_get", + "saved_object:security:reference-data/get", + "saved_object:security:reference-data/find", + "saved_object:security:reference-data/open_point_in_time", + "saved_object:security:reference-data/close_point_in_time", + "saved_object:security:reference-data/create", + "saved_object:security:reference-data/bulk_create", + "saved_object:security:reference-data/update", + "saved_object:security:reference-data/bulk_update", + "saved_object:security:reference-data/delete", + "saved_object:security:reference-data/bulk_delete", + "saved_object:security:reference-data/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:cloud/bulk_get", + "saved_object:cloud/get", + "saved_object:cloud/find", + "saved_object:cloud/open_point_in_time", + "saved_object:cloud/close_point_in_time", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:scheduled_report/bulk_get", + "saved_object:scheduled_report/get", + "saved_object:scheduled_report/find", + "saved_object:scheduled_report/open_point_in_time", + "saved_object:scheduled_report/close_point_in_time", + "saved_object:scheduled_report/create", + "saved_object:scheduled_report/bulk_create", + "saved_object:scheduled_report/update", + "saved_object:scheduled_report/bulk_update", + "saved_object:scheduled_report/delete", + "saved_object:scheduled_report/bulk_delete", + "saved_object:scheduled_report/share_to_space", + "ui:discover_v2/show", + "ui:discover_v2/save", + "ui:discover_v2/createShortUrl", + "ui:discover_v2/storeSearchSession", + "ui:discover_v2/generateCsv", + "api:dashboardUsageStats", + "api:downloadCsv", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:event-annotation-group/bulk_get", + "saved_object:event-annotation-group/get", + "saved_object:event-annotation-group/find", + "saved_object:event-annotation-group/open_point_in_time", + "saved_object:event-annotation-group/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "ui:dashboard_v2/createNew", + "ui:dashboard_v2/show", + "ui:dashboard_v2/showWriteControls", + "ui:dashboard_v2/createShortUrl", + "ui:dashboard_v2/storeSearchSession", + "ui:dashboard_v2/generateScreenshot", + "ui:dashboard_v2/downloadCsv", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps_v2/save", + "ui:maps_v2/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize_v2/show", + "ui:visualize_v2/delete", + "ui:visualize_v2/save", + "ui:visualize_v2/createShortUrl", + "ui:visualize_v2/generateScreenshot", + ], + "blocklist_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeBlocklist", + "api:securitySolution-readBlocklist", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/writeBlocklist", + "ui:siemV5/readBlocklist", + ], + "blocklist_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readBlocklist", + "ui:siemV5/readBlocklist", + ], + "endpoint_exceptions_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-showEndpointExceptions", + "api:securitySolution-crudEndpointExceptions", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/showEndpointExceptions", + "ui:siemV5/crudEndpointExceptions", + ], + "endpoint_exceptions_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-showEndpointExceptions", + "ui:siemV5/showEndpointExceptions", + ], + "endpoint_list_all": Array [ + "login:", + "api:securitySolution-writeEndpointList", + "api:securitySolution-readEndpointList", + "ui:siemV5/writeEndpointList", + "ui:siemV5/readEndpointList", + ], + "endpoint_list_read": Array [ + "login:", + "api:securitySolution-readEndpointList", + "ui:siemV5/readEndpointList", + ], + "event_filters_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeEventFilters", + "api:securitySolution-readEventFilters", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/writeEventFilters", + "ui:siemV5/readEventFilters", + ], + "event_filters_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readEventFilters", + "ui:siemV5/readEventFilters", + ], + "execute_operations_all": Array [ + "login:", + "api:securitySolution-writeExecuteOperations", + "ui:siemV5/writeExecuteOperations", + ], + "file_operations_all": Array [ + "login:", + "api:securitySolution-writeFileOperations", + "ui:siemV5/writeFileOperations", + ], + "global_artifact_management_all": Array [ + "login:", + "api:securitySolution-writeGlobalArtifacts", + "ui:siemV5/writeGlobalArtifacts", + ], + "host_isolation_all": Array [ + "login:", + "api:securitySolution-writeHostIsolationRelease", + "api:securitySolution-writeHostIsolation", + "ui:siemV5/writeHostIsolationRelease", + "ui:siemV5/writeHostIsolation", + ], + "host_isolation_exceptions_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-deleteHostIsolationExceptions", + "api:securitySolution-readHostIsolationExceptions", + "api:securitySolution-accessHostIsolationExceptions", + "api:securitySolution-writeHostIsolationExceptions", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/deleteHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + "ui:siemV5/writeHostIsolationExceptions", + ], + "host_isolation_exceptions_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readHostIsolationExceptions", + "api:securitySolution-accessHostIsolationExceptions", + "ui:siemV5/readHostIsolationExceptions", + "ui:siemV5/accessHostIsolationExceptions", + ], + "minimal_all": Array [ + "login:", + "api:securitySolution", + "api:rac", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:users-read", + "api:initialize-security-solution", + "api:securitySolution-entity-analytics", + "api:cloud-security-posture-all", + "api:cloud-security-posture-read", + "api:bulkGetUserProfiles", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/kibana", + "saved_object:alert/bulk_get", + "saved_object:alert/get", + "saved_object:alert/find", + "saved_object:alert/open_point_in_time", + "saved_object:alert/close_point_in_time", + "saved_object:alert/create", + "saved_object:alert/bulk_create", + "saved_object:alert/update", + "saved_object:alert/bulk_update", + "saved_object:alert/delete", + "saved_object:alert/bulk_delete", + "saved_object:alert/share_to_space", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:index-pattern/create", + "saved_object:index-pattern/bulk_create", + "saved_object:index-pattern/update", + "saved_object:index-pattern/bulk_update", + "saved_object:index-pattern/delete", + "saved_object:index-pattern/bulk_delete", + "saved_object:index-pattern/share_to_space", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:csp_rule/create", + "saved_object:csp_rule/bulk_create", + "saved_object:csp_rule/update", + "saved_object:csp_rule/bulk_update", + "saved_object:csp_rule/delete", + "saved_object:csp_rule/bulk_delete", + "saved_object:csp_rule/share_to_space", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:cloud-security-posture-settings/create", + "saved_object:cloud-security-posture-settings/bulk_create", + "saved_object:cloud-security-posture-settings/update", + "saved_object:cloud-security-posture-settings/bulk_update", + "saved_object:cloud-security-posture-settings/delete", + "saved_object:cloud-security-posture-settings/bulk_delete", + "saved_object:cloud-security-posture-settings/share_to_space", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:csp-rule-template/create", + "saved_object:csp-rule-template/bulk_create", + "saved_object:csp-rule-template/update", + "saved_object:csp-rule-template/bulk_update", + "saved_object:csp-rule-template/delete", + "saved_object:csp-rule-template/bulk_delete", + "saved_object:csp-rule-template/share_to_space", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/create", + "saved_object:siem-detection-engine-rule-actions/bulk_create", + "saved_object:siem-detection-engine-rule-actions/update", + "saved_object:siem-detection-engine-rule-actions/bulk_update", + "saved_object:siem-detection-engine-rule-actions/delete", + "saved_object:siem-detection-engine-rule-actions/bulk_delete", + "saved_object:siem-detection-engine-rule-actions/share_to_space", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/create", + "saved_object:endpoint:user-artifact-manifest/bulk_create", + "saved_object:endpoint:user-artifact-manifest/update", + "saved_object:endpoint:user-artifact-manifest/bulk_update", + "saved_object:endpoint:user-artifact-manifest/delete", + "saved_object:endpoint:user-artifact-manifest/bulk_delete", + "saved_object:endpoint:user-artifact-manifest/share_to_space", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/create", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_create", + "saved_object:endpoint:unified-user-artifact-manifest/update", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_update", + "saved_object:endpoint:unified-user-artifact-manifest/delete", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_delete", + "saved_object:endpoint:unified-user-artifact-manifest/share_to_space", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:security-solution-signals-migration/create", + "saved_object:security-solution-signals-migration/bulk_create", + "saved_object:security-solution-signals-migration/update", + "saved_object:security-solution-signals-migration/bulk_update", + "saved_object:security-solution-signals-migration/delete", + "saved_object:security-solution-signals-migration/bulk_delete", + "saved_object:security-solution-signals-migration/share_to_space", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:risk-engine-configuration/create", + "saved_object:risk-engine-configuration/bulk_create", + "saved_object:risk-engine-configuration/update", + "saved_object:risk-engine-configuration/bulk_update", + "saved_object:risk-engine-configuration/delete", + "saved_object:risk-engine-configuration/bulk_delete", + "saved_object:risk-engine-configuration/share_to_space", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:entity-engine-status/create", + "saved_object:entity-engine-status/bulk_create", + "saved_object:entity-engine-status/update", + "saved_object:entity-engine-status/bulk_update", + "saved_object:entity-engine-status/delete", + "saved_object:entity-engine-status/bulk_delete", + "saved_object:entity-engine-status/share_to_space", + "saved_object:privilege-monitoring-status/bulk_get", + "saved_object:privilege-monitoring-status/get", + "saved_object:privilege-monitoring-status/find", + "saved_object:privilege-monitoring-status/open_point_in_time", + "saved_object:privilege-monitoring-status/close_point_in_time", + "saved_object:privilege-monitoring-status/create", + "saved_object:privilege-monitoring-status/bulk_create", + "saved_object:privilege-monitoring-status/update", + "saved_object:privilege-monitoring-status/bulk_update", + "saved_object:privilege-monitoring-status/delete", + "saved_object:privilege-monitoring-status/bulk_delete", + "saved_object:privilege-monitoring-status/share_to_space", + "saved_object:privmon-api-key/bulk_get", + "saved_object:privmon-api-key/get", + "saved_object:privmon-api-key/find", + "saved_object:privmon-api-key/open_point_in_time", + "saved_object:privmon-api-key/close_point_in_time", + "saved_object:privmon-api-key/create", + "saved_object:privmon-api-key/bulk_create", + "saved_object:privmon-api-key/update", + "saved_object:privmon-api-key/bulk_update", + "saved_object:privmon-api-key/delete", + "saved_object:privmon-api-key/bulk_delete", + "saved_object:privmon-api-key/share_to_space", + "saved_object:entity-analytics-monitoring-entity-source/bulk_get", + "saved_object:entity-analytics-monitoring-entity-source/get", + "saved_object:entity-analytics-monitoring-entity-source/find", + "saved_object:entity-analytics-monitoring-entity-source/open_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/close_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/create", + "saved_object:entity-analytics-monitoring-entity-source/bulk_create", + "saved_object:entity-analytics-monitoring-entity-source/update", + "saved_object:entity-analytics-monitoring-entity-source/bulk_update", + "saved_object:entity-analytics-monitoring-entity-source/delete", + "saved_object:entity-analytics-monitoring-entity-source/bulk_delete", + "saved_object:entity-analytics-monitoring-entity-source/share_to_space", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "saved_object:security-ai-prompt/bulk_get", + "saved_object:security-ai-prompt/get", + "saved_object:security-ai-prompt/find", + "saved_object:security-ai-prompt/open_point_in_time", + "saved_object:security-ai-prompt/close_point_in_time", + "saved_object:security-ai-prompt/create", + "saved_object:security-ai-prompt/bulk_create", + "saved_object:security-ai-prompt/update", + "saved_object:security-ai-prompt/bulk_update", + "saved_object:security-ai-prompt/delete", + "saved_object:security-ai-prompt/bulk_delete", + "saved_object:security-ai-prompt/share_to_space", + "saved_object:security:reference-data/bulk_get", + "saved_object:security:reference-data/get", + "saved_object:security:reference-data/find", + "saved_object:security:reference-data/open_point_in_time", + "saved_object:security:reference-data/close_point_in_time", + "saved_object:security:reference-data/create", + "saved_object:security:reference-data/bulk_create", + "saved_object:security:reference-data/update", + "saved_object:security:reference-data/bulk_update", + "saved_object:security:reference-data/delete", + "saved_object:security:reference-data/bulk_delete", + "saved_object:security:reference-data/share_to_space", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:telemetry/create", + "saved_object:telemetry/bulk_create", + "saved_object:telemetry/update", + "saved_object:telemetry/bulk_update", + "saved_object:telemetry/delete", + "saved_object:telemetry/bulk_delete", + "saved_object:telemetry/share_to_space", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:cloud/bulk_get", + "saved_object:cloud/get", + "saved_object:cloud/find", + "saved_object:cloud/open_point_in_time", + "saved_object:cloud/close_point_in_time", + "ui:siemV5/show", + "ui:siemV5/crud", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "alerting:siem.notifications/siem/rule/get", + "alerting:siem.notifications/siem/rule/bulkGet", + "alerting:siem.notifications/siem/rule/getRuleState", + "alerting:siem.notifications/siem/rule/getAlertSummary", + "alerting:siem.notifications/siem/rule/getExecutionLog", + "alerting:siem.notifications/siem/rule/getActionErrorLog", + "alerting:siem.notifications/siem/rule/find", + "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", + "alerting:siem.notifications/siem/rule/getBackfill", + "alerting:siem.notifications/siem/rule/findBackfill", + "alerting:siem.notifications/siem/rule/findGaps", + "alerting:siem.notifications/siem/rule/bulkEditParams", + "alerting:siem.notifications/siem/rule/create", + "alerting:siem.notifications/siem/rule/delete", + "alerting:siem.notifications/siem/rule/update", + "alerting:siem.notifications/siem/rule/updateApiKey", + "alerting:siem.notifications/siem/rule/muteAll", + "alerting:siem.notifications/siem/rule/unmuteAll", + "alerting:siem.notifications/siem/rule/muteAlert", + "alerting:siem.notifications/siem/rule/unmuteAlert", + "alerting:siem.notifications/siem/rule/snooze", + "alerting:siem.notifications/siem/rule/bulkEdit", + "alerting:siem.notifications/siem/rule/bulkDelete", + "alerting:siem.notifications/siem/rule/unsnooze", + "alerting:siem.notifications/siem/rule/runSoon", + "alerting:siem.notifications/siem/rule/enable", + "alerting:siem.notifications/siem/rule/disable", + "alerting:siem.notifications/siem/rule/bulkEnable", + "alerting:siem.notifications/siem/rule/bulkDisable", + "alerting:siem.notifications/siem/rule/deleteBackfill", + "alerting:siem.notifications/siem/rule/fillGaps", + "alerting:siem.notifications/siem/rule/scheduleBackfill", + "alerting:siem.esqlRule/siem/rule/get", + "alerting:siem.esqlRule/siem/rule/bulkGet", + "alerting:siem.esqlRule/siem/rule/getRuleState", + "alerting:siem.esqlRule/siem/rule/getAlertSummary", + "alerting:siem.esqlRule/siem/rule/getExecutionLog", + "alerting:siem.esqlRule/siem/rule/getActionErrorLog", + "alerting:siem.esqlRule/siem/rule/find", + "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.esqlRule/siem/rule/getBackfill", + "alerting:siem.esqlRule/siem/rule/findBackfill", + "alerting:siem.esqlRule/siem/rule/findGaps", + "alerting:siem.esqlRule/siem/rule/bulkEditParams", + "alerting:siem.esqlRule/siem/rule/create", + "alerting:siem.esqlRule/siem/rule/delete", + "alerting:siem.esqlRule/siem/rule/update", + "alerting:siem.esqlRule/siem/rule/updateApiKey", + "alerting:siem.esqlRule/siem/rule/muteAll", + "alerting:siem.esqlRule/siem/rule/unmuteAll", + "alerting:siem.esqlRule/siem/rule/muteAlert", + "alerting:siem.esqlRule/siem/rule/unmuteAlert", + "alerting:siem.esqlRule/siem/rule/snooze", + "alerting:siem.esqlRule/siem/rule/bulkEdit", + "alerting:siem.esqlRule/siem/rule/bulkDelete", + "alerting:siem.esqlRule/siem/rule/unsnooze", + "alerting:siem.esqlRule/siem/rule/runSoon", + "alerting:siem.esqlRule/siem/rule/enable", + "alerting:siem.esqlRule/siem/rule/disable", + "alerting:siem.esqlRule/siem/rule/bulkEnable", + "alerting:siem.esqlRule/siem/rule/bulkDisable", + "alerting:siem.esqlRule/siem/rule/deleteBackfill", + "alerting:siem.esqlRule/siem/rule/fillGaps", + "alerting:siem.esqlRule/siem/rule/scheduleBackfill", + "alerting:siem.eqlRule/siem/rule/get", + "alerting:siem.eqlRule/siem/rule/bulkGet", + "alerting:siem.eqlRule/siem/rule/getRuleState", + "alerting:siem.eqlRule/siem/rule/getAlertSummary", + "alerting:siem.eqlRule/siem/rule/getExecutionLog", + "alerting:siem.eqlRule/siem/rule/getActionErrorLog", + "alerting:siem.eqlRule/siem/rule/find", + "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.eqlRule/siem/rule/getBackfill", + "alerting:siem.eqlRule/siem/rule/findBackfill", + "alerting:siem.eqlRule/siem/rule/findGaps", + "alerting:siem.eqlRule/siem/rule/bulkEditParams", + "alerting:siem.eqlRule/siem/rule/create", + "alerting:siem.eqlRule/siem/rule/delete", + "alerting:siem.eqlRule/siem/rule/update", + "alerting:siem.eqlRule/siem/rule/updateApiKey", + "alerting:siem.eqlRule/siem/rule/muteAll", + "alerting:siem.eqlRule/siem/rule/unmuteAll", + "alerting:siem.eqlRule/siem/rule/muteAlert", + "alerting:siem.eqlRule/siem/rule/unmuteAlert", + "alerting:siem.eqlRule/siem/rule/snooze", + "alerting:siem.eqlRule/siem/rule/bulkEdit", + "alerting:siem.eqlRule/siem/rule/bulkDelete", + "alerting:siem.eqlRule/siem/rule/unsnooze", + "alerting:siem.eqlRule/siem/rule/runSoon", + "alerting:siem.eqlRule/siem/rule/enable", + "alerting:siem.eqlRule/siem/rule/disable", + "alerting:siem.eqlRule/siem/rule/bulkEnable", + "alerting:siem.eqlRule/siem/rule/bulkDisable", + "alerting:siem.eqlRule/siem/rule/deleteBackfill", + "alerting:siem.eqlRule/siem/rule/fillGaps", + "alerting:siem.eqlRule/siem/rule/scheduleBackfill", + "alerting:siem.indicatorRule/siem/rule/get", + "alerting:siem.indicatorRule/siem/rule/bulkGet", + "alerting:siem.indicatorRule/siem/rule/getRuleState", + "alerting:siem.indicatorRule/siem/rule/getAlertSummary", + "alerting:siem.indicatorRule/siem/rule/getExecutionLog", + "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", + "alerting:siem.indicatorRule/siem/rule/find", + "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.indicatorRule/siem/rule/getBackfill", + "alerting:siem.indicatorRule/siem/rule/findBackfill", + "alerting:siem.indicatorRule/siem/rule/findGaps", + "alerting:siem.indicatorRule/siem/rule/bulkEditParams", + "alerting:siem.indicatorRule/siem/rule/create", + "alerting:siem.indicatorRule/siem/rule/delete", + "alerting:siem.indicatorRule/siem/rule/update", + "alerting:siem.indicatorRule/siem/rule/updateApiKey", + "alerting:siem.indicatorRule/siem/rule/muteAll", + "alerting:siem.indicatorRule/siem/rule/unmuteAll", + "alerting:siem.indicatorRule/siem/rule/muteAlert", + "alerting:siem.indicatorRule/siem/rule/unmuteAlert", + "alerting:siem.indicatorRule/siem/rule/snooze", + "alerting:siem.indicatorRule/siem/rule/bulkEdit", + "alerting:siem.indicatorRule/siem/rule/bulkDelete", + "alerting:siem.indicatorRule/siem/rule/unsnooze", + "alerting:siem.indicatorRule/siem/rule/runSoon", + "alerting:siem.indicatorRule/siem/rule/enable", + "alerting:siem.indicatorRule/siem/rule/disable", + "alerting:siem.indicatorRule/siem/rule/bulkEnable", + "alerting:siem.indicatorRule/siem/rule/bulkDisable", + "alerting:siem.indicatorRule/siem/rule/deleteBackfill", + "alerting:siem.indicatorRule/siem/rule/fillGaps", + "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", + "alerting:siem.mlRule/siem/rule/get", + "alerting:siem.mlRule/siem/rule/bulkGet", + "alerting:siem.mlRule/siem/rule/getRuleState", + "alerting:siem.mlRule/siem/rule/getAlertSummary", + "alerting:siem.mlRule/siem/rule/getExecutionLog", + "alerting:siem.mlRule/siem/rule/getActionErrorLog", + "alerting:siem.mlRule/siem/rule/find", + "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.mlRule/siem/rule/getBackfill", + "alerting:siem.mlRule/siem/rule/findBackfill", + "alerting:siem.mlRule/siem/rule/findGaps", + "alerting:siem.mlRule/siem/rule/bulkEditParams", + "alerting:siem.mlRule/siem/rule/create", + "alerting:siem.mlRule/siem/rule/delete", + "alerting:siem.mlRule/siem/rule/update", + "alerting:siem.mlRule/siem/rule/updateApiKey", + "alerting:siem.mlRule/siem/rule/muteAll", + "alerting:siem.mlRule/siem/rule/unmuteAll", + "alerting:siem.mlRule/siem/rule/muteAlert", + "alerting:siem.mlRule/siem/rule/unmuteAlert", + "alerting:siem.mlRule/siem/rule/snooze", + "alerting:siem.mlRule/siem/rule/bulkEdit", + "alerting:siem.mlRule/siem/rule/bulkDelete", + "alerting:siem.mlRule/siem/rule/unsnooze", + "alerting:siem.mlRule/siem/rule/runSoon", + "alerting:siem.mlRule/siem/rule/enable", + "alerting:siem.mlRule/siem/rule/disable", + "alerting:siem.mlRule/siem/rule/bulkEnable", + "alerting:siem.mlRule/siem/rule/bulkDisable", + "alerting:siem.mlRule/siem/rule/deleteBackfill", + "alerting:siem.mlRule/siem/rule/fillGaps", + "alerting:siem.mlRule/siem/rule/scheduleBackfill", + "alerting:siem.queryRule/siem/rule/get", + "alerting:siem.queryRule/siem/rule/bulkGet", + "alerting:siem.queryRule/siem/rule/getRuleState", + "alerting:siem.queryRule/siem/rule/getAlertSummary", + "alerting:siem.queryRule/siem/rule/getExecutionLog", + "alerting:siem.queryRule/siem/rule/getActionErrorLog", + "alerting:siem.queryRule/siem/rule/find", + "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.queryRule/siem/rule/getBackfill", + "alerting:siem.queryRule/siem/rule/findBackfill", + "alerting:siem.queryRule/siem/rule/findGaps", + "alerting:siem.queryRule/siem/rule/bulkEditParams", + "alerting:siem.queryRule/siem/rule/create", + "alerting:siem.queryRule/siem/rule/delete", + "alerting:siem.queryRule/siem/rule/update", + "alerting:siem.queryRule/siem/rule/updateApiKey", + "alerting:siem.queryRule/siem/rule/muteAll", + "alerting:siem.queryRule/siem/rule/unmuteAll", + "alerting:siem.queryRule/siem/rule/muteAlert", + "alerting:siem.queryRule/siem/rule/unmuteAlert", + "alerting:siem.queryRule/siem/rule/snooze", + "alerting:siem.queryRule/siem/rule/bulkEdit", + "alerting:siem.queryRule/siem/rule/bulkDelete", + "alerting:siem.queryRule/siem/rule/unsnooze", + "alerting:siem.queryRule/siem/rule/runSoon", + "alerting:siem.queryRule/siem/rule/enable", + "alerting:siem.queryRule/siem/rule/disable", + "alerting:siem.queryRule/siem/rule/bulkEnable", + "alerting:siem.queryRule/siem/rule/bulkDisable", + "alerting:siem.queryRule/siem/rule/deleteBackfill", + "alerting:siem.queryRule/siem/rule/fillGaps", + "alerting:siem.queryRule/siem/rule/scheduleBackfill", + "alerting:siem.savedQueryRule/siem/rule/get", + "alerting:siem.savedQueryRule/siem/rule/bulkGet", + "alerting:siem.savedQueryRule/siem/rule/getRuleState", + "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", + "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", + "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", + "alerting:siem.savedQueryRule/siem/rule/find", + "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.savedQueryRule/siem/rule/getBackfill", + "alerting:siem.savedQueryRule/siem/rule/findBackfill", + "alerting:siem.savedQueryRule/siem/rule/findGaps", + "alerting:siem.savedQueryRule/siem/rule/bulkEditParams", + "alerting:siem.savedQueryRule/siem/rule/create", + "alerting:siem.savedQueryRule/siem/rule/delete", + "alerting:siem.savedQueryRule/siem/rule/update", + "alerting:siem.savedQueryRule/siem/rule/updateApiKey", + "alerting:siem.savedQueryRule/siem/rule/muteAll", + "alerting:siem.savedQueryRule/siem/rule/unmuteAll", + "alerting:siem.savedQueryRule/siem/rule/muteAlert", + "alerting:siem.savedQueryRule/siem/rule/unmuteAlert", + "alerting:siem.savedQueryRule/siem/rule/snooze", + "alerting:siem.savedQueryRule/siem/rule/bulkEdit", + "alerting:siem.savedQueryRule/siem/rule/bulkDelete", + "alerting:siem.savedQueryRule/siem/rule/unsnooze", + "alerting:siem.savedQueryRule/siem/rule/runSoon", + "alerting:siem.savedQueryRule/siem/rule/enable", + "alerting:siem.savedQueryRule/siem/rule/disable", + "alerting:siem.savedQueryRule/siem/rule/bulkEnable", + "alerting:siem.savedQueryRule/siem/rule/bulkDisable", + "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", + "alerting:siem.savedQueryRule/siem/rule/fillGaps", + "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", + "alerting:siem.thresholdRule/siem/rule/get", + "alerting:siem.thresholdRule/siem/rule/bulkGet", + "alerting:siem.thresholdRule/siem/rule/getRuleState", + "alerting:siem.thresholdRule/siem/rule/getAlertSummary", + "alerting:siem.thresholdRule/siem/rule/getExecutionLog", + "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", + "alerting:siem.thresholdRule/siem/rule/find", + "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.thresholdRule/siem/rule/getBackfill", + "alerting:siem.thresholdRule/siem/rule/findBackfill", + "alerting:siem.thresholdRule/siem/rule/findGaps", + "alerting:siem.thresholdRule/siem/rule/bulkEditParams", + "alerting:siem.thresholdRule/siem/rule/create", + "alerting:siem.thresholdRule/siem/rule/delete", + "alerting:siem.thresholdRule/siem/rule/update", + "alerting:siem.thresholdRule/siem/rule/updateApiKey", + "alerting:siem.thresholdRule/siem/rule/muteAll", + "alerting:siem.thresholdRule/siem/rule/unmuteAll", + "alerting:siem.thresholdRule/siem/rule/muteAlert", + "alerting:siem.thresholdRule/siem/rule/unmuteAlert", + "alerting:siem.thresholdRule/siem/rule/snooze", + "alerting:siem.thresholdRule/siem/rule/bulkEdit", + "alerting:siem.thresholdRule/siem/rule/bulkDelete", + "alerting:siem.thresholdRule/siem/rule/unsnooze", + "alerting:siem.thresholdRule/siem/rule/runSoon", + "alerting:siem.thresholdRule/siem/rule/enable", + "alerting:siem.thresholdRule/siem/rule/disable", + "alerting:siem.thresholdRule/siem/rule/bulkEnable", + "alerting:siem.thresholdRule/siem/rule/bulkDisable", + "alerting:siem.thresholdRule/siem/rule/deleteBackfill", + "alerting:siem.thresholdRule/siem/rule/fillGaps", + "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", + "alerting:siem.newTermsRule/siem/rule/get", + "alerting:siem.newTermsRule/siem/rule/bulkGet", + "alerting:siem.newTermsRule/siem/rule/getRuleState", + "alerting:siem.newTermsRule/siem/rule/getAlertSummary", + "alerting:siem.newTermsRule/siem/rule/getExecutionLog", + "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", + "alerting:siem.newTermsRule/siem/rule/find", + "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", + "alerting:siem.newTermsRule/siem/rule/getBackfill", + "alerting:siem.newTermsRule/siem/rule/findBackfill", + "alerting:siem.newTermsRule/siem/rule/findGaps", + "alerting:siem.newTermsRule/siem/rule/bulkEditParams", + "alerting:siem.newTermsRule/siem/rule/create", + "alerting:siem.newTermsRule/siem/rule/delete", + "alerting:siem.newTermsRule/siem/rule/update", + "alerting:siem.newTermsRule/siem/rule/updateApiKey", + "alerting:siem.newTermsRule/siem/rule/muteAll", + "alerting:siem.newTermsRule/siem/rule/unmuteAll", + "alerting:siem.newTermsRule/siem/rule/muteAlert", + "alerting:siem.newTermsRule/siem/rule/unmuteAlert", + "alerting:siem.newTermsRule/siem/rule/snooze", + "alerting:siem.newTermsRule/siem/rule/bulkEdit", + "alerting:siem.newTermsRule/siem/rule/bulkDelete", + "alerting:siem.newTermsRule/siem/rule/unsnooze", + "alerting:siem.newTermsRule/siem/rule/runSoon", + "alerting:siem.newTermsRule/siem/rule/enable", + "alerting:siem.newTermsRule/siem/rule/disable", + "alerting:siem.newTermsRule/siem/rule/bulkEnable", + "alerting:siem.newTermsRule/siem/rule/bulkDisable", + "alerting:siem.newTermsRule/siem/rule/deleteBackfill", + "alerting:siem.newTermsRule/siem/rule/fillGaps", + "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", + "alerting:siem.notifications/siem/alert/get", + "alerting:siem.notifications/siem/alert/find", + "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.notifications/siem/alert/getAlertSummary", + "alerting:siem.notifications/siem/alert/update", + "alerting:siem.esqlRule/siem/alert/get", + "alerting:siem.esqlRule/siem/alert/find", + "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.esqlRule/siem/alert/getAlertSummary", + "alerting:siem.esqlRule/siem/alert/update", + "alerting:siem.eqlRule/siem/alert/get", + "alerting:siem.eqlRule/siem/alert/find", + "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.eqlRule/siem/alert/getAlertSummary", + "alerting:siem.eqlRule/siem/alert/update", + "alerting:siem.indicatorRule/siem/alert/get", + "alerting:siem.indicatorRule/siem/alert/find", + "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.indicatorRule/siem/alert/getAlertSummary", + "alerting:siem.indicatorRule/siem/alert/update", + "alerting:siem.mlRule/siem/alert/get", + "alerting:siem.mlRule/siem/alert/find", + "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.mlRule/siem/alert/getAlertSummary", + "alerting:siem.mlRule/siem/alert/update", + "alerting:siem.queryRule/siem/alert/get", + "alerting:siem.queryRule/siem/alert/find", + "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.queryRule/siem/alert/getAlertSummary", + "alerting:siem.queryRule/siem/alert/update", + "alerting:siem.savedQueryRule/siem/alert/get", + "alerting:siem.savedQueryRule/siem/alert/find", + "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", + "alerting:siem.savedQueryRule/siem/alert/update", + "alerting:siem.thresholdRule/siem/alert/get", + "alerting:siem.thresholdRule/siem/alert/find", + "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.thresholdRule/siem/alert/getAlertSummary", + "alerting:siem.thresholdRule/siem/alert/update", + "alerting:siem.newTermsRule/siem/alert/get", + "alerting:siem.newTermsRule/siem/alert/find", + "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", + "alerting:siem.newTermsRule/siem/alert/getAlertSummary", + "alerting:siem.newTermsRule/siem/alert/update", + "api:fileUpload:analyzeFile", + "api:store_search_session", + "api:generateReport", + "app:discover", + "ui:catalogue/discover", + "ui:management/kibana/search_sessions", + "ui:management/insightsAndAlerting/reporting", + "ui:navLinks/discover", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "saved_object:search/create", + "saved_object:search/bulk_create", + "saved_object:search/update", + "saved_object:search/bulk_update", + "saved_object:search/delete", + "saved_object:search/bulk_delete", + "saved_object:search/share_to_space", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search-session/bulk_get", + "saved_object:search-session/get", + "saved_object:search-session/find", + "saved_object:search-session/open_point_in_time", + "saved_object:search-session/close_point_in_time", + "saved_object:search-session/create", + "saved_object:search-session/bulk_create", + "saved_object:search-session/update", + "saved_object:search-session/bulk_update", + "saved_object:search-session/delete", + "saved_object:search-session/bulk_delete", + "saved_object:search-session/share_to_space", + "saved_object:scheduled_report/bulk_get", + "saved_object:scheduled_report/get", + "saved_object:scheduled_report/find", + "saved_object:scheduled_report/open_point_in_time", + "saved_object:scheduled_report/close_point_in_time", + "saved_object:scheduled_report/create", + "saved_object:scheduled_report/bulk_create", + "saved_object:scheduled_report/update", + "saved_object:scheduled_report/bulk_update", + "saved_object:scheduled_report/delete", + "saved_object:scheduled_report/bulk_delete", + "saved_object:scheduled_report/share_to_space", + "ui:discover_v2/show", + "ui:discover_v2/save", + "ui:discover_v2/createShortUrl", + "ui:discover_v2/storeSearchSession", + "ui:discover_v2/generateCsv", + "api:dashboardUsageStats", + "api:downloadCsv", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "saved_object:dashboard/create", + "saved_object:dashboard/bulk_create", + "saved_object:dashboard/update", + "saved_object:dashboard/bulk_update", + "saved_object:dashboard/delete", + "saved_object:dashboard/bulk_delete", + "saved_object:dashboard/share_to_space", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:event-annotation-group/bulk_get", + "saved_object:event-annotation-group/get", + "saved_object:event-annotation-group/find", + "saved_object:event-annotation-group/open_point_in_time", + "saved_object:event-annotation-group/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "ui:dashboard_v2/createNew", + "ui:dashboard_v2/show", + "ui:dashboard_v2/showWriteControls", + "ui:dashboard_v2/createShortUrl", + "ui:dashboard_v2/storeSearchSession", + "ui:dashboard_v2/generateScreenshot", + "ui:dashboard_v2/downloadCsv", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "saved_object:map/create", + "saved_object:map/bulk_create", + "saved_object:map/update", + "saved_object:map/bulk_update", + "saved_object:map/delete", + "saved_object:map/bulk_delete", + "saved_object:map/share_to_space", + "ui:maps_v2/save", + "ui:maps_v2/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "saved_object:visualization/create", + "saved_object:visualization/bulk_create", + "saved_object:visualization/update", + "saved_object:visualization/bulk_update", + "saved_object:visualization/delete", + "saved_object:visualization/bulk_delete", + "saved_object:visualization/share_to_space", + "saved_object:lens/create", + "saved_object:lens/bulk_create", + "saved_object:lens/update", + "saved_object:lens/bulk_update", + "saved_object:lens/delete", + "saved_object:lens/bulk_delete", + "saved_object:lens/share_to_space", + "ui:visualize_v2/show", + "ui:visualize_v2/delete", + "ui:visualize_v2/save", + "ui:visualize_v2/createShortUrl", + "ui:visualize_v2/generateScreenshot", + ], + "minimal_read": Array [ + "login:", + "api:securitySolution", + "api:rac", + "api:lists-read", + "api:users-read", + "api:initialize-security-solution", + "api:securitySolution-entity-analytics", + "api:cloud-security-posture-read", + "api:bulkGetUserProfiles", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:privilege-monitoring-status/bulk_get", + "saved_object:privilege-monitoring-status/get", + "saved_object:privilege-monitoring-status/find", + "saved_object:privilege-monitoring-status/open_point_in_time", + "saved_object:privilege-monitoring-status/close_point_in_time", + "saved_object:privmon-api-key/bulk_get", + "saved_object:privmon-api-key/get", + "saved_object:privmon-api-key/find", + "saved_object:privmon-api-key/open_point_in_time", + "saved_object:privmon-api-key/close_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/bulk_get", + "saved_object:entity-analytics-monitoring-entity-source/get", + "saved_object:entity-analytics-monitoring-entity-source/find", + "saved_object:entity-analytics-monitoring-entity-source/open_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:security-ai-prompt/bulk_get", + "saved_object:security-ai-prompt/get", + "saved_object:security-ai-prompt/find", + "saved_object:security-ai-prompt/open_point_in_time", + "saved_object:security-ai-prompt/close_point_in_time", + "saved_object:security:reference-data/bulk_get", + "saved_object:security:reference-data/get", + "saved_object:security:reference-data/find", + "saved_object:security:reference-data/open_point_in_time", + "saved_object:security:reference-data/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:cloud/bulk_get", + "saved_object:cloud/get", + "saved_object:cloud/find", + "saved_object:cloud/open_point_in_time", + "saved_object:cloud/close_point_in_time", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "app:discover", + "ui:catalogue/discover", + "ui:navLinks/discover", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "ui:discover_v2/show", + "ui:discover_v2/createShortUrl", + "api:dashboardUsageStats", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:event-annotation-group/bulk_get", + "saved_object:event-annotation-group/get", + "saved_object:event-annotation-group/find", + "saved_object:event-annotation-group/open_point_in_time", + "saved_object:event-annotation-group/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "ui:dashboard_v2/show", + "ui:dashboard_v2/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps_v2/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize_v2/show", + "ui:visualize_v2/createShortUrl", + ], + "policy_management_all": Array [ + "login:", + "api:securitySolution-writePolicyManagement", + "api:securitySolution-readPolicyManagement", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/create", + "saved_object:policy-settings-protection-updates-note/bulk_create", + "saved_object:policy-settings-protection-updates-note/update", + "saved_object:policy-settings-protection-updates-note/bulk_update", + "saved_object:policy-settings-protection-updates-note/delete", + "saved_object:policy-settings-protection-updates-note/bulk_delete", + "saved_object:policy-settings-protection-updates-note/share_to_space", + "ui:siemV5/writePolicyManagement", + "ui:siemV5/readPolicyManagement", + ], + "policy_management_read": Array [ + "login:", + "api:securitySolution-readPolicyManagement", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "ui:siemV5/readPolicyManagement", + ], + "process_operations_all": Array [ + "login:", + "api:securitySolution-writeProcessOperations", + "ui:siemV5/writeProcessOperations", + ], + "read": Array [ + "login:", + "api:securitySolution", + "api:rac", + "api:lists-read", + "api:users-read", + "api:initialize-security-solution", + "api:securitySolution-entity-analytics", + "api:cloud-security-posture-read", + "api:bulkGetUserProfiles", + "api:securitySolution-threat-intelligence", + "app:securitySolution", + "app:csp", + "app:kibana", + "ui:catalogue/securitySolution", + "ui:navLinks/securitySolution", + "ui:navLinks/csp", + "ui:navLinks/kibana", + "saved_object:index-pattern/bulk_get", + "saved_object:index-pattern/get", + "saved_object:index-pattern/find", + "saved_object:index-pattern/open_point_in_time", + "saved_object:index-pattern/close_point_in_time", + "saved_object:csp_rule/bulk_get", + "saved_object:csp_rule/get", + "saved_object:csp_rule/find", + "saved_object:csp_rule/open_point_in_time", + "saved_object:csp_rule/close_point_in_time", + "saved_object:cloud-security-posture-settings/bulk_get", + "saved_object:cloud-security-posture-settings/get", + "saved_object:cloud-security-posture-settings/find", + "saved_object:cloud-security-posture-settings/open_point_in_time", + "saved_object:cloud-security-posture-settings/close_point_in_time", + "saved_object:csp-rule-template/bulk_get", + "saved_object:csp-rule-template/get", + "saved_object:csp-rule-template/find", + "saved_object:csp-rule-template/open_point_in_time", + "saved_object:csp-rule-template/close_point_in_time", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:siem-detection-engine-rule-actions/bulk_get", + "saved_object:siem-detection-engine-rule-actions/get", + "saved_object:siem-detection-engine-rule-actions/find", + "saved_object:siem-detection-engine-rule-actions/open_point_in_time", + "saved_object:siem-detection-engine-rule-actions/close_point_in_time", + "saved_object:endpoint:user-artifact-manifest/bulk_get", + "saved_object:endpoint:user-artifact-manifest/get", + "saved_object:endpoint:user-artifact-manifest/find", + "saved_object:endpoint:user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:user-artifact-manifest/close_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/bulk_get", + "saved_object:endpoint:unified-user-artifact-manifest/get", + "saved_object:endpoint:unified-user-artifact-manifest/find", + "saved_object:endpoint:unified-user-artifact-manifest/open_point_in_time", + "saved_object:endpoint:unified-user-artifact-manifest/close_point_in_time", + "saved_object:security-solution-signals-migration/bulk_get", + "saved_object:security-solution-signals-migration/get", + "saved_object:security-solution-signals-migration/find", + "saved_object:security-solution-signals-migration/open_point_in_time", + "saved_object:security-solution-signals-migration/close_point_in_time", + "saved_object:risk-engine-configuration/bulk_get", + "saved_object:risk-engine-configuration/get", + "saved_object:risk-engine-configuration/find", + "saved_object:risk-engine-configuration/open_point_in_time", + "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:privilege-monitoring-status/bulk_get", + "saved_object:privilege-monitoring-status/get", + "saved_object:privilege-monitoring-status/find", + "saved_object:privilege-monitoring-status/open_point_in_time", + "saved_object:privilege-monitoring-status/close_point_in_time", + "saved_object:privmon-api-key/bulk_get", + "saved_object:privmon-api-key/get", + "saved_object:privmon-api-key/find", + "saved_object:privmon-api-key/open_point_in_time", + "saved_object:privmon-api-key/close_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/bulk_get", + "saved_object:entity-analytics-monitoring-entity-source/get", + "saved_object:entity-analytics-monitoring-entity-source/find", + "saved_object:entity-analytics-monitoring-entity-source/open_point_in_time", + "saved_object:entity-analytics-monitoring-entity-source/close_point_in_time", + "saved_object:policy-settings-protection-updates-note/bulk_get", + "saved_object:policy-settings-protection-updates-note/get", + "saved_object:policy-settings-protection-updates-note/find", + "saved_object:policy-settings-protection-updates-note/open_point_in_time", + "saved_object:policy-settings-protection-updates-note/close_point_in_time", + "saved_object:security-ai-prompt/bulk_get", + "saved_object:security-ai-prompt/get", + "saved_object:security-ai-prompt/find", + "saved_object:security-ai-prompt/open_point_in_time", + "saved_object:security-ai-prompt/close_point_in_time", + "saved_object:security:reference-data/bulk_get", + "saved_object:security:reference-data/get", + "saved_object:security:reference-data/find", + "saved_object:security:reference-data/open_point_in_time", + "saved_object:security:reference-data/close_point_in_time", + "saved_object:config/bulk_get", + "saved_object:config/get", + "saved_object:config/find", + "saved_object:config/open_point_in_time", + "saved_object:config/close_point_in_time", + "saved_object:config-global/bulk_get", + "saved_object:config-global/get", + "saved_object:config-global/find", + "saved_object:config-global/open_point_in_time", + "saved_object:config-global/close_point_in_time", + "saved_object:telemetry/bulk_get", + "saved_object:telemetry/get", + "saved_object:telemetry/find", + "saved_object:telemetry/open_point_in_time", + "saved_object:telemetry/close_point_in_time", + "saved_object:url/bulk_get", + "saved_object:url/get", + "saved_object:url/find", + "saved_object:url/open_point_in_time", + "saved_object:url/close_point_in_time", + "saved_object:tag/bulk_get", + "saved_object:tag/get", + "saved_object:tag/find", + "saved_object:tag/open_point_in_time", + "saved_object:tag/close_point_in_time", + "saved_object:cloud/bulk_get", + "saved_object:cloud/get", + "saved_object:cloud/find", + "saved_object:cloud/open_point_in_time", + "saved_object:cloud/close_point_in_time", + "ui:siemV5/show", + "ui:siemV5/entity-analytics", + "ui:siemV5/detections", + "ui:siemV5/investigation-guide", + "ui:siemV5/investigation-guide-interactions", + "ui:siemV5/threat-intelligence", + "app:discover", + "ui:catalogue/discover", + "ui:navLinks/discover", + "saved_object:url/create", + "saved_object:url/bulk_create", + "saved_object:url/update", + "saved_object:url/bulk_update", + "saved_object:url/delete", + "saved_object:url/bulk_delete", + "saved_object:url/share_to_space", + "saved_object:search/bulk_get", + "saved_object:search/get", + "saved_object:search/find", + "saved_object:search/open_point_in_time", + "saved_object:search/close_point_in_time", + "ui:discover_v2/show", + "ui:discover_v2/createShortUrl", + "api:dashboardUsageStats", + "app:dashboards", + "ui:catalogue/dashboard", + "ui:navLinks/dashboards", + "saved_object:visualization/bulk_get", + "saved_object:visualization/get", + "saved_object:visualization/find", + "saved_object:visualization/open_point_in_time", + "saved_object:visualization/close_point_in_time", + "saved_object:canvas-workpad/bulk_get", + "saved_object:canvas-workpad/get", + "saved_object:canvas-workpad/find", + "saved_object:canvas-workpad/open_point_in_time", + "saved_object:canvas-workpad/close_point_in_time", + "saved_object:event-annotation-group/bulk_get", + "saved_object:event-annotation-group/get", + "saved_object:event-annotation-group/find", + "saved_object:event-annotation-group/open_point_in_time", + "saved_object:event-annotation-group/close_point_in_time", + "saved_object:lens/bulk_get", + "saved_object:lens/get", + "saved_object:lens/find", + "saved_object:lens/open_point_in_time", + "saved_object:lens/close_point_in_time", + "saved_object:links/bulk_get", + "saved_object:links/get", + "saved_object:links/find", + "saved_object:links/open_point_in_time", + "saved_object:links/close_point_in_time", + "saved_object:map/bulk_get", + "saved_object:map/get", + "saved_object:map/find", + "saved_object:map/open_point_in_time", + "saved_object:map/close_point_in_time", + "saved_object:dashboard/bulk_get", + "saved_object:dashboard/get", + "saved_object:dashboard/find", + "saved_object:dashboard/open_point_in_time", + "saved_object:dashboard/close_point_in_time", + "ui:dashboard_v2/show", + "ui:dashboard_v2/createShortUrl", + "app:maps", + "ui:catalogue/maps", + "ui:navLinks/maps", + "ui:maps_v2/show", + "app:visualize", + "app:lens", + "ui:catalogue/visualize", + "ui:navLinks/visualize", + "ui:navLinks/lens", + "ui:visualize_v2/show", + "ui:visualize_v2/createShortUrl", + ], + "scan_operations_all": Array [ + "login:", + "api:securitySolution-writeScanOperations", + "ui:siemV5/writeScanOperations", + ], + "trusted_applications_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeTrustedApplications", + "api:securitySolution-readTrustedApplications", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/writeTrustedApplications", + "ui:siemV5/readTrustedApplications", + ], + "trusted_applications_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readTrustedApplications", + "ui:siemV5/readTrustedApplications", + ], + "trusted_devices_all": Array [ + "login:", + "api:lists-all", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-writeTrustedDevices", + "api:securitySolution-readTrustedDevices", + "saved_object:exception-list-agnostic/bulk_get", + "saved_object:exception-list-agnostic/get", + "saved_object:exception-list-agnostic/find", + "saved_object:exception-list-agnostic/open_point_in_time", + "saved_object:exception-list-agnostic/close_point_in_time", + "saved_object:exception-list-agnostic/create", + "saved_object:exception-list-agnostic/bulk_create", + "saved_object:exception-list-agnostic/update", + "saved_object:exception-list-agnostic/bulk_update", + "saved_object:exception-list-agnostic/delete", + "saved_object:exception-list-agnostic/bulk_delete", + "saved_object:exception-list-agnostic/share_to_space", + "ui:siemV5/writeTrustedDevices", + "ui:siemV5/readTrustedDevices", + ], + "trusted_devices_read": Array [ + "login:", + "api:lists-read", + "api:lists-summary", + "api:securitySolution-readTrustedDevices", + "ui:siemV5/readTrustedDevices", + ], + "workflow_insights_all": Array [ + "login:", + "api:securitySolution-writeWorkflowInsights", + "api:securitySolution-readWorkflowInsights", + "ui:siemV5/writeWorkflowInsights", + "ui:siemV5/readWorkflowInsights", + ], + "workflow_insights_read": Array [ + "login:", + "api:securitySolution-readWorkflowInsights", + "ui:siemV5/readWorkflowInsights", ], }, } diff --git a/x-pack/solutions/security/test/session_view/basic/tests/index.ts b/x-pack/solutions/security/test/session_view/basic/tests/index.ts index 7dd530442cf11..b7ced36dd0573 100644 --- a/x-pack/solutions/security/test/session_view/basic/tests/index.ts +++ b/x-pack/solutions/security/test/session_view/basic/tests/index.ts @@ -57,7 +57,8 @@ export const securitySolutionOnlyReadSpacesAll: Role = { kibana: [ { feature: { - siemV3: ['read'], + siemV5: ['read'], + securitySolutionRulesV1: ['read'], }, spaces: ['*'], }, From 4e60d9436f9ae2849e6fda940fb5414489c358da Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Fri, 17 Oct 2025 17:25:28 -0500 Subject: [PATCH 02/85] style: revert linting changes to large yaml/JSON files These changes were made automatically in an initial commit that added our new features to roles; those changes have since been reverted (320c34f485), and thus there should not currently be any behavioral changes in these files, which makes these stylistic changes even more unnecessary. Note: I also noticed that a few old references had (accidentally?) remained in `security_roles.json` after `320c34f485`; this cleans those up as well. --- config/serverless.security.search_ai_lake.yml | 72 +-- config/serverless.security.yml | 144 +++--- .../serverless_resources/security_roles.json | 450 +++++++++++++----- 3 files changed, 452 insertions(+), 214 deletions(-) diff --git a/config/serverless.security.search_ai_lake.yml b/config/serverless.security.search_ai_lake.yml index 7dd59c7f06a5f..ca7e2f40dd762 100644 --- a/config/serverless.security.search_ai_lake.yml +++ b/config/serverless.security.search_ai_lake.yml @@ -52,60 +52,60 @@ xpack.features.overrides: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV4 from maps and visualizations because these functionalities are disabled in this tier - - feature: 'discover_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] ## We need limited access to fleet (v1) in order to use integrations - - feature: 'fleet' - privileges: ['all'] + - feature: "fleet" + privileges: [ "all" ] read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'fleet' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "fleet" + privileges: [ "read" ] siemV3: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV3 from maps and visualizations because these functionalities are disabled in this tier - - feature: 'discover_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] ## We need limited access to fleet (v1) in order to use integrations - - feature: 'fleet' - privileges: ['all'] + - feature: "fleet" + privileges: [ "all" ] read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'fleet' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "fleet" + privileges: [ "read" ] siemV2: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV2 from maps and visualizations because these functionalities are disabled in this tier - - feature: 'discover_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] ## We need limited access to fleet (v1) in order to use integrations - - feature: 'fleet' - privileges: ['all'] + - feature: "fleet" + privileges: [ "all" ] read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'fleet' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "fleet" + privileges: [ "read" ] siem: privileges: all.composedOf: ## Limited values so the fields from serverless.yml or serverless.security.yml are overwritten ## We do not need to compose siemV2 from maps and visualizations because these functionalities are disabled in this tier - - feature: 'discover_v2' - privileges: ['all'] - - feature: 'savedQueryManagement' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] + - feature: "savedQueryManagement" + privileges: [ "all" ] read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'savedQueryManagement' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "savedQueryManagement" + privileges: [ "read" ] # Custom integrations/fleet settings xpack.fleet.agentless.isDefault: true @@ -121,8 +121,8 @@ xpack.actions.preconfigured: actionTypeId: .inference exposeConfig: true config: - provider: 'elastic' - taskType: 'chat_completion' - inferenceId: '.rainbow-sprinkles-elastic' + provider: "elastic" + taskType: "chat_completion" + inferenceId: ".rainbow-sprinkles-elastic" providerConfig: - model_id: 'rainbow-sprinkles' + model_id: "rainbow-sprinkles" diff --git a/config/serverless.security.yml b/config/serverless.security.yml index c857baaec04ea..afa4565511cd4 100644 --- a/config/serverless.security.yml +++ b/config/serverless.security.yml @@ -22,11 +22,11 @@ xpack.features.overrides: maps_v2.hidden: true ### agent builder feature is moved from Analytics category to the Security one the bottom agentBuilder: - category: 'security' + category: "security" order: 1101 ### Machine Learning feature is moved from Analytics category to the Security one as the last item. ml: - category: 'security' + category: "security" order: 1103 ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siemV5: @@ -59,26 +59,26 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: 'discover_v2' - privileges: ['all'] - - feature: 'dashboard_v2' - privileges: ['all'] - - feature: 'visualize_v2' - privileges: ['all'] - - feature: 'maps_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] + - feature: "dashboard_v2" + privileges: [ "all" ] + - feature: "visualize_v2" + privileges: [ "all" ] + - feature: "maps_v2" + privileges: [ "all" ] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'dashboard_v2' - privileges: ['read'] - - feature: 'visualize_v2' - privileges: ['read'] - - feature: 'maps_v2' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "dashboard_v2" + privileges: [ "read" ] + - feature: "visualize_v2" + privileges: [ "read" ] + - feature: "maps_v2" + privileges: [ "read" ] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siemV3: @@ -86,26 +86,26 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: 'discover_v2' - privileges: ['all'] - - feature: 'dashboard_v2' - privileges: ['all'] - - feature: 'visualize_v2' - privileges: ['all'] - - feature: 'maps_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] + - feature: "dashboard_v2" + privileges: [ "all" ] + - feature: "visualize_v2" + privileges: [ "all" ] + - feature: "maps_v2" + privileges: [ "all" ] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'dashboard_v2' - privileges: ['read'] - - feature: 'visualize_v2' - privileges: ['read'] - - feature: 'maps_v2' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "dashboard_v2" + privileges: [ "read" ] + - feature: "visualize_v2" + privileges: [ "read" ] + - feature: "maps_v2" + privileges: [ "read" ] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siemV2: @@ -113,26 +113,26 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: 'discover_v2' - privileges: ['all'] - - feature: 'dashboard_v2' - privileges: ['all'] - - feature: 'visualize_v2' - privileges: ['all'] - - feature: 'maps_v2' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] + - feature: "dashboard_v2" + privileges: [ "all" ] + - feature: "visualize_v2" + privileges: [ "all" ] + - feature: "maps_v2" + privileges: [ "all" ] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'dashboard_v2' - privileges: ['read'] - - feature: 'visualize_v2' - privileges: ['read'] - - feature: 'maps_v2' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "dashboard_v2" + privileges: [ "read" ] + - feature: "visualize_v2" + privileges: [ "read" ] + - feature: "maps_v2" + privileges: [ "read" ] ### Security's feature privileges are fine-tuned to grant access to Discover, Dashboard, Maps, and Visualize apps. siem: @@ -140,30 +140,30 @@ xpack.features.overrides: ### Security's `All` feature privilege should implicitly grant `All` access to Discover, Dashboard, Maps, and ### Visualize features. all.composedOf: - - feature: 'discover_v2' - privileges: ['all'] - - feature: 'dashboard_v2' - privileges: ['all'] - - feature: 'visualize_v2' - privileges: ['all'] - - feature: 'maps_v2' - privileges: ['all'] - - feature: 'savedQueryManagement' - privileges: ['all'] + - feature: "discover_v2" + privileges: [ "all" ] + - feature: "dashboard_v2" + privileges: [ "all" ] + - feature: "visualize_v2" + privileges: [ "all" ] + - feature: "maps_v2" + privileges: [ "all" ] + - feature: "savedQueryManagement" + privileges: [ "all" ] # Security's `Read` feature privilege should implicitly grant `Read` access to Discover, Dashboard, Maps, and # Visualize features. Additionally, it should implicitly grant privilege to create short URLs in Discover, ### Dashboard, and Visualize apps. read.composedOf: - - feature: 'discover_v2' - privileges: ['read'] - - feature: 'dashboard_v2' - privileges: ['read'] - - feature: 'visualize_v2' - privileges: ['read'] - - feature: 'maps_v2' - privileges: ['read'] - - feature: 'savedQueryManagement' - privileges: ['read'] + - feature: "discover_v2" + privileges: [ "read" ] + - feature: "dashboard_v2" + privileges: [ "read" ] + - feature: "visualize_v2" + privileges: [ "read" ] + - feature: "maps_v2" + privileges: [ "read" ] + - feature: "savedQueryManagement" + privileges: [ "read" ] ## Cloud settings xpack.cloud.serverless.project_type: security @@ -178,8 +178,8 @@ xpack.securitySolutionServerless.productTypes: ] xpack.securitySolution.offeringSettings: { - ILMEnabled: false, # Index Lifecycle Management (ILM) functionalities disabled, not supported by serverless Elasticsearch - } + ILMEnabled: false, # Index Lifecycle Management (ILM) functionalities disabled, not supported by serverless Elasticsearch +} newsfeed.enabled: true diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index 015a132c147f1..76a3b250530b6 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -5,8 +5,15 @@ "cluster": [], "indices": [ { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { "names": [ @@ -24,7 +31,9 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -32,17 +41,38 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV3": ["read", "read_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["read"], - "builtInAlerts": ["read"] + "ml": [ + "read" + ], + "siemV3": [ + "read", + "read_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "read" + ], + "securitySolutionTimeline": [ + "read" + ], + "securitySolutionNotes": [ + "read" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "read" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -53,8 +83,15 @@ "cluster": [], "indices": [ { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { "names": [ @@ -74,7 +111,9 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -82,17 +121,38 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV3": ["read", "read_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["read"], - "builtInAlerts": ["read"] + "ml": [ + "read" + ], + "siemV3": [ + "read", + "read_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "read" + ], + "securitySolutionTimeline": [ + "read" + ], + "securitySolutionNotes": [ + "read" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "read" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -115,15 +175,31 @@ "logstash-*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { - "names": [".lists*", ".items*"], - "privileges": ["read", "write"] + "names": [ + ".lists*", + ".items*" + ], + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -137,7 +213,9 @@ ".entities.v1.updates.security_*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -145,7 +223,9 @@ "kibana": [ { "feature": { - "ml": ["read"], + "ml": [ + "read" + ], "siemV3": [ "all", "read_alerts", @@ -161,21 +241,49 @@ "actions_log_management_all", "file_operations_all" ], - "securitySolutionCasesV2": ["all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"], - "osquery": ["all"], - "discover_v2": ["all"], - "dashboard_v2": ["all"], - "maps_v2": ["all"], - "visualize_v2": ["all"], - "savedQueryManagement": ["all"] + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ], + "osquery": [ + "all" + ], + "discover_v2": [ + "all" + ], + "dashboard_v2": [ + "all" + ], + "maps_v2": [ + "all" + ], + "visualize_v2": [ + "all" + ], + "savedQueryManagement": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -199,7 +307,10 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -210,7 +321,12 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["read", "write", "maintenance", "view_index_metadata"] + "privileges": [ + "read", + "write", + "maintenance", + "view_index_metadata" + ] }, { "names": [ @@ -219,7 +335,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -227,17 +345,39 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV3": ["all", "read_alerts", "crud_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"] + "ml": [ + "read" + ], + "siemV3": [ + "all", + "read_alerts", + "crud_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -261,7 +401,10 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -272,7 +415,11 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["read", "write", "manage"] + "privileges": [ + "read", + "write", + "manage" + ] }, { "names": [ @@ -281,7 +428,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -289,17 +438,39 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV3": ["all", "read_alerts", "crud_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["all"], - "builtInAlerts": ["all"] + "ml": [ + "read" + ], + "siemV3": [ + "all", + "read_alerts", + "crud_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "all" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -307,7 +478,9 @@ "detections_admin": { "name": "detections_admin", "elasticsearch": { - "cluster": ["manage"], + "cluster": [ + "manage" + ], "indices": [ { "names": [ @@ -329,7 +502,11 @@ "winlogbeat-*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["manage", "write", "read"] + "privileges": [ + "manage", + "write", + "read" + ] }, { "names": [ @@ -338,7 +515,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -346,19 +525,42 @@ "kibana": [ { "feature": { - "ml": ["all"], - "siemV3": ["all", "read_alerts", "crud_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "securitySolutionRulesV1": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"], - "dev_tools": ["all"] + "ml": [ + "all" + ], + "siemV3": [ + "all", + "read_alerts", + "crud_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ], + "dev_tools": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -366,11 +568,18 @@ "platform_engineer": { "name": "platform_engineer", "elasticsearch": { - "cluster": ["manage"], + "cluster": [ + "manage" + ], "indices": [ { - "names": [".lists*", ".items*"], - "privileges": ["all"] + "names": [ + ".lists*", + ".items*" + ], + "privileges": [ + "all" + ] }, { "names": [ @@ -387,7 +596,9 @@ ".fleet-actions*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["all"] + "privileges": [ + "all" + ] }, { "names": [ @@ -398,11 +609,17 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["all"] + "privileges": [ + "all" + ] }, { - "names": [".entity_analytics.monitoring*"], - "privileges": ["read"] + "names": [ + ".entity_analytics.monitoring*" + ], + "privileges": [ + "read" + ] } ], "run_as": [] @@ -410,18 +627,39 @@ "kibana": [ { "feature": { - "ml": ["all"], - "siemV3": ["all", "read_alerts", "crud_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "securitySolutionRulesV1": ["all"], - "actions": ["all"], - "builtInAlerts": ["all"] + "ml": [ + "all" + ], + "siemV3": [ + "all", + "read_alerts", + "crud_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "all" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] From 02765d819d4b1da343a7f2924301030ac02efe26 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Tue, 21 Oct 2025 14:09:54 +0200 Subject: [PATCH 03/85] update the siem migrations required permissions Instead of requiring siemVX read/all, it now requires securitySolutionRulesV1 read/all --- .../private/translations/translations/de-DE.json | 1 - .../private/translations/translations/fr-FR.json | 1 - .../private/translations/translations/ja-JP.json | 1 - .../private/translations/translations/zh-CN.json | 1 - .../common/service/capabilities.ts | 16 ++++++++-------- .../public/siem_migrations/links.ts | 5 ++--- .../lib/siem_migrations/common/api/util/authz.ts | 3 ++- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index 1f7e941bfacb9..6b34a255379b2 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -38744,7 +38744,6 @@ "xpack.securitySolution.siemMigrations.rulesService.polling.successLinkText": "Zu den übersetzten Regeln", "xpack.securitySolution.siemMigrations.rulesService.polling.successTitle": "Regelübersetzung abgeschlossen.", "xpack.securitySolution.siemMigrations.service.capabilities.connectorsRead": "Management > Aktionen und Konnektoren: Lesen", - "xpack.securitySolution.siemMigrations.service.capabilities.securityAll": "Security > Security: Alle", "xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll": "Security > SIEM-Migrationen: Alle", "xpack.securitySolution.socTrends.properties.lockDatePickerDescription": "Globale Datumsauswahl bei der SOC Trends-Datumsauswahl sperren", "xpack.securitySolution.socTrends.properties.lockDatePickerTooltip": "Synchronisierung des Datums-/Zeitbereichs zwischen der aktuell angezeigten Seite und SOC-Trends deaktivieren", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 496cdf46b988a..460f05f1ed5de 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -38999,7 +38999,6 @@ "xpack.securitySolution.siemMigrations.rulesService.polling.successLinkText": "Rendez-vous aux règles traduites", "xpack.securitySolution.siemMigrations.rulesService.polling.successTitle": "Traduction de règles terminée.", "xpack.securitySolution.siemMigrations.service.capabilities.connectorsRead": "Gestion > Actions & connecteurs : Lire", - "xpack.securitySolution.siemMigrations.service.capabilities.securityAll": "Sécurité > Sécurité : Tous", "xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll": "Sécurité > Migrations SIEM : Tous", "xpack.securitySolution.socTrends.properties.lockDatePickerDescription": "Verrouiller le sélecteur de date global sur le sélecteur de date de tendances SOC", "xpack.securitySolution.socTrends.properties.lockDatePickerTooltip": "Désactiver la synchronisation de la plage de date/heure entre la page actuellement consultée et les tendances SOC", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 8f3b38bd8f204..a7955dea98e21 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -39041,7 +39041,6 @@ "xpack.securitySolution.siemMigrations.rulesService.polling.successLinkText": "変換されたルールに移動", "xpack.securitySolution.siemMigrations.rulesService.polling.successTitle": "ルール変換が完了しました。", "xpack.securitySolution.siemMigrations.service.capabilities.connectorsRead": "管理 > アクションとコネクター:読み取り", - "xpack.securitySolution.siemMigrations.service.capabilities.securityAll": "Security > Security:すべて", "xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll": "Security > SIEM移行:すべて", "xpack.securitySolution.socTrends.properties.lockDatePickerDescription": "グローバル日付ピッカーをSOCトレンド日付ピッカーにロック", "xpack.securitySolution.socTrends.properties.lockDatePickerTooltip": "現在表示中のページとSOCトレンドの間の日付/時刻範囲の同期を無効にします", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index f8993a30dcc44..238602f1d654a 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -39028,7 +39028,6 @@ "xpack.securitySolution.siemMigrations.rulesService.polling.successLinkText": "前往已转换规则", "xpack.securitySolution.siemMigrations.rulesService.polling.successTitle": "规则转换完成。", "xpack.securitySolution.siemMigrations.service.capabilities.connectorsRead": "管理 > 操作和连接器:读取", - "xpack.securitySolution.siemMigrations.service.capabilities.securityAll": "安全 > 安全:全部", "xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll": "安全 > SIEM 迁移:全部", "xpack.securitySolution.socTrends.properties.lockDatePickerDescription": "将全局日期选取器锁定到 SOC 趋势日期选取器", "xpack.securitySolution.socTrends.properties.lockDatePickerTooltip": "禁用当前查看的页面与 SOC 趋势之间的日期/时间范围同步", diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts index 46aff57c13d59..d6e2803cba4db 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts @@ -7,9 +7,9 @@ import type { Capabilities } from '@kbn/core/public'; import { - SECURITY_UI_CRUD_PRIVILEGE, - SECURITY_UI_SHOW_PRIVILEGE, SIEM_MIGRATIONS_FEATURE_ID, + RULES_UI_READ_PRIVILEGE, + RULES_UI_EDIT_PRIVILEGE, } from '@kbn/security-solution-features/constants'; import { i18n } from '@kbn/i18n'; import { CapabilitiesChecker } from '../../../common/lib/capabilities'; @@ -21,10 +21,10 @@ export interface MissingCapability { const minimumCapabilities: MissingCapability[] = [ { - capability: SECURITY_UI_SHOW_PRIVILEGE, + capability: RULES_UI_READ_PRIVILEGE, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.securityAll', - { defaultMessage: 'Security > Security: Read' } + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', + { defaultMessage: 'Security > Rules: Read' } ), }, { @@ -38,10 +38,10 @@ const minimumCapabilities: MissingCapability[] = [ const allCapabilities: MissingCapability[] = [ { - capability: SECURITY_UI_CRUD_PRIVILEGE, + capability: RULES_UI_EDIT_PRIVILEGE, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.securityAll', - { defaultMessage: 'Security > Security: All' } + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', + { defaultMessage: 'Security > Rules: All' } ), }, { diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 8157338eb1d41..2f316b860b64a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -11,7 +11,6 @@ import { SIEM_MIGRATIONS_FEATURE_ID, } from '@kbn/security-solution-features/constants'; import { - SECURITY_FEATURE_ID, SIEM_MIGRATIONS_DASHBOARDS_PATH, SIEM_MIGRATIONS_LANDING_PATH, SIEM_MIGRATIONS_RULES_PATH, @@ -32,7 +31,7 @@ const subLinks: LinkItem[] = [ }), landingIcon: IconRules, path: SIEM_MIGRATIONS_RULES_PATH, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], skipUrlState: true, hideTimeline: true, hideWhenExperimentalKey: 'siemMigrationsDisabled', @@ -50,7 +49,7 @@ const subLinks: LinkItem[] = [ ), landingIcon: IconDashboards, path: SIEM_MIGRATIONS_DASHBOARDS_PATH, - capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], skipUrlState: true, hideTimeline: true, hideWhenExperimentalKey: 'siemMigrationsDisabled', diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts index 7131dc57f911a..8513addb5b064 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts @@ -6,7 +6,8 @@ */ import { SIEM_MIGRATIONS_API_ACTION_ALL } from '@kbn/security-solution-features/actions'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; export const authz = { - requiredPrivileges: ['securitySolution', SIEM_MIGRATIONS_API_ACTION_ALL], + requiredPrivileges: [RULES_API_READ, SIEM_MIGRATIONS_API_ACTION_ALL], }; From b35f598eeab6a52606c0ed6039d14d256ed6579b Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Tue, 21 Oct 2025 15:32:30 +0200 Subject: [PATCH 04/85] update attack discovery required permissions --- .../security_solution/public/attack_discovery/links.test.ts | 4 ++-- .../security_solution/public/attack_discovery/links.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.test.ts b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.test.ts index 5f9d06d4f9d91..fb5409d1f3e58 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.test.ts @@ -7,12 +7,12 @@ import { ATTACK_DISCOVERY_FEATURE_ID } from '../../common/constants'; import { links } from './links'; -import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { RULES_UI_READ_PRIVILEGE } from '@kbn/security-solution-features/constants'; describe('links', () => { it('for serverless, it specifies capabilities as an AND condition, via a nested array', () => { expect(links.capabilities).toEqual([ - [SECURITY_UI_SHOW_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], + [RULES_UI_READ_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], ]); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts index 02b1d8b048153..69e06e41bca36 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/attack_discovery/links.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; -import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { RULES_UI_READ_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { ATTACK_DISCOVERY } from '../app/translations'; import { ATTACK_DISCOVERY_FEATURE_ID, @@ -17,7 +17,7 @@ import { import type { LinkItem } from '../common/links/types'; export const links: LinkItem = { - capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`]], // This is an AND condition via the nested array + capabilities: [[RULES_UI_READ_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`]], // This is an AND condition via the nested array globalNavPosition: 4, globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.attackDiscovery', { From 686745e696f20ae0a14470fc5ab29a6331215f52 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Tue, 21 Oct 2025 15:40:31 +0200 Subject: [PATCH 05/85] update timeline required permissions --- .../security_solution/public/timelines/links.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts b/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts index d3537fbe584a2..f140f36413c83 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/timelines/links.ts @@ -6,7 +6,10 @@ */ import { i18n } from '@kbn/i18n'; -import { SECURITY_UI_SHOW_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { + RULES_UI_READ_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, +} from '@kbn/security-solution-features/constants'; import { SecurityPageName, TIMELINE_FEATURE_ID, TIMELINES_PATH } from '../../common/constants'; import { TIMELINES } from '../app/translations'; import type { LinkItem } from '../common/links/types'; @@ -16,8 +19,11 @@ export const links: LinkItem = { title: TIMELINES, path: TIMELINES_PATH, globalNavPosition: 9, - // It only makes sense to show this link when the user is also granted access to security solution - capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`]], + // It only makes sense to show this link when the user is also granted access to security solution or rules + capabilities: [ + [SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`], + [RULES_UI_READ_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`], + ], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.timelines', { defaultMessage: 'Timelines', @@ -31,7 +37,10 @@ export const links: LinkItem = { }), path: `${TIMELINES_PATH}/template`, sideNavDisabled: true, - capabilities: [[SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`]], + capabilities: [ + [SECURITY_UI_SHOW_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`], + [RULES_UI_READ_PRIVILEGE, `${TIMELINE_FEATURE_ID}.read`], + ], }, ], }; From 2f7cff4524c45ed5167ac6d7c249b48da27b68ed Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Fri, 24 Oct 2025 10:08:07 +0200 Subject: [PATCH 06/85] fix onboarding sections It is unclear on wether "dashboards" and "integrations" should be exclusive to `siemV5` or `securitySolutionRulesV1`. So for now we are showing it when the user has either of those. --- .../components/onboarding_body/cards/alerts/index.ts | 4 ++-- .../components/onboarding_body/cards/dashboards/index.ts | 3 ++- .../components/onboarding_body/cards/integrations/index.ts | 3 ++- .../components/onboarding_body/cards/rules/index.ts | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/index.ts index 11dcab9da2043..b365929624968 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/alerts/index.ts @@ -6,12 +6,12 @@ */ import React from 'react'; +import { RULES_UI_DETECTIONS_PRIVILEGE } from '@kbn/security-solution-features/constants'; import type { OnboardingCardConfig } from '../../../../types'; import { OnboardingCardId } from '../../../../constants'; import { ALERTS_CARD_TITLE } from './translations'; import alertsIcon from './images/alerts_icon.png'; import alertsDarkIcon from './images/alerts_icon_dark.png'; -import { SECURITY_FEATURE_ID } from '../../../../../../common/constants'; export const alertsCardConfig: OnboardingCardConfig = { id: OnboardingCardId.alerts, @@ -25,5 +25,5 @@ export const alertsCardConfig: OnboardingCardConfig = { './alerts_card' ) ), - capabilitiesRequired: [`${SECURITY_FEATURE_ID}.detections`], + capabilitiesRequired: [RULES_UI_DETECTIONS_PRIVILEGE], }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts index 561bc036b701d..e51c9bb19d3b4 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts @@ -6,6 +6,7 @@ */ import React from 'react'; +import { RULES_UI_DETECTIONS_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { IconDashboards } from '../../../../../common/icons/dashboards'; import type { OnboardingCardConfig } from '../../../../types'; import { OnboardingCardId } from '../../../../constants'; @@ -23,5 +24,5 @@ export const dashboardsCardConfig: OnboardingCardConfig = { './dashboards_card' ) ), - capabilitiesRequired: [['dashboard_v2.show', `${SECURITY_FEATURE_ID}.detections`]], + capabilitiesRequired: [['dashboard_v2.show', `${SECURITY_FEATURE_ID}.detections`], ['dashboard_v2.show', RULES_UI_DETECTIONS_PRIVILEGE]], }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts index d445564b66555..c953ee0467fa2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts @@ -7,6 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; +import { RULES_UI_DETECTIONS_PRIVILEGE } from '@kbn/security-solution-features/constants'; import { IconIntegrations } from '../../../../../common/icons/integrations'; import type { OnboardingCardConfig } from '../../../../types'; import { checkIntegrationsCardComplete } from './integrations_check_complete'; @@ -28,5 +29,5 @@ export const integrationsCardConfig: OnboardingCardConfig Date: Fri, 24 Oct 2025 12:20:26 +0000 Subject: [PATCH 07/85] [CI] Auto-commit changed files from 'node scripts/eslint_all_files --no-cache --fix' --- .../components/onboarding_body/cards/dashboards/index.ts | 5 ++++- .../components/onboarding_body/cards/integrations/index.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts index e51c9bb19d3b4..3aaeaf3708de6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/dashboards/index.ts @@ -24,5 +24,8 @@ export const dashboardsCardConfig: OnboardingCardConfig = { './dashboards_card' ) ), - capabilitiesRequired: [['dashboard_v2.show', `${SECURITY_FEATURE_ID}.detections`], ['dashboard_v2.show', RULES_UI_DETECTIONS_PRIVILEGE]], + capabilitiesRequired: [ + ['dashboard_v2.show', `${SECURITY_FEATURE_ID}.detections`], + ['dashboard_v2.show', RULES_UI_DETECTIONS_PRIVILEGE], + ], }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts index c953ee0467fa2..327594625afa5 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/components/onboarding_body/cards/integrations/index.ts @@ -29,5 +29,8 @@ export const integrationsCardConfig: OnboardingCardConfig Date: Fri, 24 Oct 2025 14:22:58 +0200 Subject: [PATCH 08/85] allow alert management operations for roles with read only access This is the current behaviour accoring do the documentation https://www.elastic.co/docs/solutions/security/detect-and-alert/detections-requirements. --- .../routes/signals/open_close_signals_route.ts | 4 ++-- .../detection_engine/routes/signals/set_alert_tags_route.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index f7399d3c46a2d..ae8ef0b68d0d2 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -15,7 +15,7 @@ import { } from '@kbn/rule-data-utils'; import type { AuthenticatedUser, ElasticsearchClient, Logger } from '@kbn/core/server'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import { ALERTS_API_ALL, ALERTS_API_READ } from '@kbn/security-solution-features/constants'; +import { ALERTS_API_READ } from '@kbn/security-solution-features/constants'; import { SetAlertsStatusRequestBody } from '../../../../../common/api/detection_engine/signals'; import { AlertStatusEnum } from '../../../../../common/api/model'; import type { SecuritySolutionPluginRouter } from '../../../../types'; @@ -42,7 +42,7 @@ export const setSignalsStatusRoute = ( access: 'public', security: { authz: { - requiredPrivileges: [ALERTS_API_ALL, ALERTS_API_READ], + requiredPrivileges: [ALERTS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts index 33632cace64e7..435f8bd1e1712 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts @@ -8,7 +8,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { uniq } from 'lodash/fp'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import { ALERTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { ALERTS_API_READ } from '@kbn/security-solution-features/constants'; import { SetAlertTagsRequestBody } from '../../../../../common/api/detection_engine/alert_tags'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { @@ -25,7 +25,7 @@ export const setAlertTagsRoute = (router: SecuritySolutionPluginRouter) => { access: 'public', security: { authz: { - requiredPrivileges: [ALERTS_API_ALL], + requiredPrivileges: [ALERTS_API_READ], }, }, }) From d70db6e8779bb58d5507c4eaf62302e5220541a3 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Fri, 24 Oct 2025 15:22:02 +0200 Subject: [PATCH 09/85] fix create shared exception list endpoint Now it requires the `securitySolutionRulesV1.all` privilege --- .../server/lib/exceptions/api/manage_exceptions/route.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/exceptions/api/manage_exceptions/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/exceptions/api/manage_exceptions/route.ts index 5b2a3a70be1a2..b447b789f05da 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/exceptions/api/manage_exceptions/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/exceptions/api/manage_exceptions/route.ts @@ -13,6 +13,7 @@ import { CreateSharedExceptionListRequestBody, CreateSharedExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import { SHARED_EXCEPTION_LIST_URL } from '../../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; @@ -25,7 +26,7 @@ export const createSharedExceptionListRoute = (router: SecuritySolutionPluginRou access: 'public', security: { authz: { - requiredPrivileges: ['securitySolution'], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) From 3cc5064fb0bdf406a0c895a734e61bff9229e8a3 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Wed, 29 Oct 2025 14:10:59 +0100 Subject: [PATCH 10/85] fix unit test --- .../common/components/user_privileges/__mocks__/index.ts | 5 +++-- .../shared/components/take_action_dropdown.test.tsx | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/__mocks__/index.ts b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/__mocks__/index.ts index a5238afacf13d..b2db7c5d3d29c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/__mocks__/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/__mocks__/index.ts @@ -9,10 +9,11 @@ import type { UserPrivilegesState } from '../user_privileges_context'; import { initialUserPrivilegesState } from '../user_privileges_context'; import { getEndpointPrivilegesInitialStateMock } from '../endpoint/mocks'; -export const getUserPrivilegesMockDefaultValue = () => { +export const getUserPrivilegesMockDefaultValue = (overrides: Partial = {}) => { const mockedPrivileges: UserPrivilegesState = { ...initialUserPrivilegesState(), - endpointPrivileges: getEndpointPrivilegesInitialStateMock(), + ...overrides, + endpointPrivileges: getEndpointPrivilegesInitialStateMock(overrides.endpointPrivileges), }; return mockedPrivileges; diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index d0881c462065a..e19cc0b76c624 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -124,7 +124,7 @@ describe('take action dropdown', () => { (useHttp as jest.Mock).mockReturnValue(mockStartServicesMock.http); }); - afterEach(() => { + beforeEach(() => { (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue()); }); @@ -381,6 +381,10 @@ describe('take action dropdown', () => { describe('"Add Endpoint exception" button', () => { const mockUseEndpointExceptionsCapability = useEndpointExceptionsCapability as jest.Mock; + beforeEach(() => { + (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue({ rulesPrivileges: { read: true, edit: true } })); + }); + test('should enable the "Add Endpoint exception" button if provided endpoint alert and has right privileges', async () => { set(defaultProps.dataAsNestedObject, 'kibana.alert.original_event.kind', ['alert']); set(defaultProps.dataAsNestedObject, 'kibana.alert.original_event.module', ['endpoint']); From 473808470101d052800eee510df46350aeb792be Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 29 Oct 2025 18:21:29 -0400 Subject: [PATCH 11/85] fixes bulk_action route to allow export on rules-read --- .../pages/rule_details/index.tsx | 2 +- .../rule_actions_overflow/index.test.tsx | 56 ++++++++++++++----- .../rule_actions_overflow/index.tsx | 25 +++++---- .../api/rules/bulk_actions/route.ts | 4 +- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 4c464aec3e484..76ada763e5e48 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -724,7 +724,7 @@ export const RuleDetailsPage = connector( Promise.resolve(null); const showManualRuleRunConfirmation = () => Promise.resolve(null); @@ -25,6 +27,7 @@ jest.mock('../../../../rule_management/logic/bulk_actions/use_bulk_export'); jest.mock( '../../../../rule_management/components/rule_details/rule_customizations_diff/rule_customizations_context' ); +jest.mock('../../../../../common/components/user_privileges'); const mockReportEvent = jest.fn(); jest.mock('../../../../../common/lib/kibana', () => { @@ -59,6 +62,10 @@ describe('RuleActionsOverflow', () => { actions: { openCustomizationsRevertFlyout: jest.fn() }, state: { doesBaseVersionExist: true }, }); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); }); describe('rules details menu panel', () => { test('menu items rendered when a rule is passed to the component', () => { @@ -67,7 +74,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -87,7 +94,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={null} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -99,13 +106,13 @@ describe('RuleActionsOverflow', () => { }); describe('rules details pop over button icon', () => { - test('it does not open the popover when rules-details-popover-button-icon is clicked when the user does not have permission', () => { + test('it does not open the popover when rules-details-popover-button-icon is clicked when the disabled flag is passed', () => { const { getByTestId } = render( Promise.resolve(true)} />, @@ -124,7 +131,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -147,7 +154,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -165,7 +172,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -177,6 +184,27 @@ describe('RuleActionsOverflow', () => { // Popover is not shown expect(getByTestId('rules-details-popover')).not.toHaveTextContent(/.+/); }); + + test('should be enabled when user only has rule read permissions', async () => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: false }, + }); + + const { getByTestId } = render( + Promise.resolve(true)} + />, + { wrapper: TestProviders } + ); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + expect(getByTestId('rules-details-export-rule')).not.toBeDisabled(); + }); }); describe('rules details delete rule', () => { @@ -186,7 +214,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -208,7 +236,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -232,7 +260,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={rule} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -255,7 +283,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -274,7 +302,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={mockRule('id')} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -305,7 +333,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={customizedMockRule} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, @@ -331,7 +359,7 @@ describe('RuleActionsOverflow', () => { showBulkDuplicateExceptionsConfirmation={showBulkDuplicateExceptionsConfirmation} showManualRuleRunConfirmation={showManualRuleRunConfirmation} rule={customizedMockRule} - userHasPermissions + isDisabled={false} canDuplicateRuleWithActions={true} confirmDeletion={() => Promise.resolve(true)} />, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx index 863a5dcf88821..89d717f0380c3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx @@ -14,6 +14,7 @@ import { } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; import { useRuleCustomizationsContext } from '../../../../rule_management/components/rule_details/rule_customizations_diff/rule_customizations_context'; import { isCustomizedPrebuiltRule } from '../../../../../../common/api/detection_engine'; import { useScheduleRuleRun } from '../../../../rule_gaps/logic/use_schedule_rule_run'; @@ -52,7 +53,7 @@ const MyEuiButtonIcon = styled(EuiButtonIcon)` interface RuleActionsOverflowComponentProps { rule: Rule | null; - userHasPermissions: boolean; + isDisabled: boolean; canDuplicateRuleWithActions: boolean; showBulkDuplicateExceptionsConfirmation: () => Promise; showManualRuleRunConfirmation: () => Promise; @@ -64,7 +65,7 @@ interface RuleActionsOverflowComponentProps { */ const RuleActionsOverflowComponent = ({ rule, - userHasPermissions, + isDisabled, canDuplicateRuleWithActions, showBulkDuplicateExceptionsConfirmation, showManualRuleRunConfirmation, @@ -80,6 +81,7 @@ const RuleActionsOverflowComponent = ({ const { bulkExport } = useBulkExport(); const downloadExportedRules = useDownloadExportedRules(); const { scheduleRuleRun } = useScheduleRuleRun(); + const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges; const onRuleDeletedCallback = useCallback(() => { navigateToApp(APP_UI_ID, { @@ -100,7 +102,7 @@ const RuleActionsOverflowComponent = ({ { startTransaction({ name: SINGLE_RULE_ACTIONS.DUPLICATE }); @@ -145,7 +147,7 @@ const RuleActionsOverflowComponent = ({ { startTransaction({ name: SINGLE_RULE_ACTIONS.EXPORT }); @@ -161,9 +163,9 @@ const RuleActionsOverflowComponent = ({ { @@ -198,7 +200,7 @@ const RuleActionsOverflowComponent = ({ 'data-test-subj': 'rules-details-revert-rule-tooltip', }} icon="timeRefresh" - disabled={!userHasPermissions || !doesBaseVersionExist} + disabled={!canEditRules || !doesBaseVersionExist} data-test-subj="rules-details-revert-rule" onClick={() => { closePopover(); @@ -212,7 +214,7 @@ const RuleActionsOverflowComponent = ({ { closePopover(); @@ -238,7 +240,8 @@ const RuleActionsOverflowComponent = ({ [ rule, canDuplicateRuleWithActions, - userHasPermissions, + canEditRules, + canReadRules, doesBaseVersionExist, startTransaction, closePopover, @@ -262,13 +265,13 @@ const RuleActionsOverflowComponent = ({ ), - [togglePopover, userHasPermissions] + [togglePopover, isDisabled] ); return ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts index 08cda67183005..b29766cf3df38 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts @@ -10,7 +10,7 @@ import { AbortError } from '@kbn/kibana-utils-plugin/common'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import type { BulkActionSkipResult } from '@kbn/alerting-plugin/common'; -import { RULES_API_ALL } from '@kbn/security-solution-features/constants'; +import { RULES_API_ALL, RULES_API_READ } from '@kbn/security-solution-features/constants'; import type { PerformRulesBulkActionResponse } from '../../../../../../../common/api/detection_engine/rule_management'; import { BulkActionTypeEnum, @@ -109,7 +109,7 @@ export const performBulkActionRoute = ( path: DETECTION_ENGINE_RULES_BULK_ACTION, security: { authz: { - requiredPrivileges: [RULES_API_ALL], + requiredPrivileges: [{ anyRequired: [RULES_API_READ, RULES_API_ALL] }], }, }, options: { From 191d62c5798dc07e27ab6c8277688b59901eca62 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Oct 2025 00:00:54 +0000 Subject: [PATCH 12/85] Changes from node scripts/eslint_all_files --no-cache --fix --- .../shared/components/take_action_dropdown.test.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index e19cc0b76c624..d6e5099ab7374 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -382,7 +382,9 @@ describe('take action dropdown', () => { const mockUseEndpointExceptionsCapability = useEndpointExceptionsCapability as jest.Mock; beforeEach(() => { - (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue({ rulesPrivileges: { read: true, edit: true } })); + (useUserPrivileges as jest.Mock).mockReturnValue( + getUserPrivilegesMockDefaultValue({ rulesPrivileges: { read: true, edit: true } }) + ); }); test('should enable the "Add Endpoint exception" button if provided endpoint alert and has right privileges', async () => { From 5ed674ebe6aab53c96838712d19667515b95024e Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Thu, 30 Oct 2025 11:23:29 +0100 Subject: [PATCH 13/85] fix cypress test: endpoint_role_rbac_with_space_awareness.cy.ts No security subfeature is required in all spaces anymore. The test was failing because the `siemV5` feature file never got updated and it was still referencing a feature flag that has been enabled and removed in `main`. The feature flag in question is `endpointManagementSpaceAwarenessEnabled` which was being used to override the subfeature configuration by setting `requireAllSpaces=false` and `privilegesTooltip=undefined`. Now that the feature flag doesn't exist, it makes sense to remove these properties directly in the subfeature configuration instead of overriding them outside of it. --- .../translations/translations/de-DE.json | 14 ---- .../translations/translations/fr-FR.json | 14 ---- .../translations/translations/ja-JP.json | 14 ---- .../translations/translations/zh-CN.json | 14 ---- .../src/security/kibana_sub_features.ts | 79 ------------------- .../v1_features/kibana_sub_features.ts | 3 - .../v2_features/kibana_sub_features.ts | 3 - .../v3_features/kibana_sub_features.ts | 3 - .../v4_features/kibana_sub_features.ts | 3 - .../v5_features/kibana_sub_features.ts | 13 +-- 10 files changed, 1 insertion(+), 159 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index 6b34a255379b2..e9de2af9b00b1 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -7195,49 +7195,35 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.assistant.description": "Ändern Sie die Standard-Felder, die vom KI-Assistenten und der Angriffserkennung verwendet werden dürfen. Anonymisieren Sie jeglichen Inhalt für die ausgewählten Felder.", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList": "Blockliste", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.description": "Erweitern Sie den Schutz von Elastic Defend gegen bösartige Prozesse und schützen Sie vor potenziell schädlichen Anwendungen.", - "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.privilegesTooltip": "Für den Zugriff auf die Blocklist ist 'Alle Spaces' erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions": "Endpoint-Ausnahmen", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.description": "Verwenden Sie Endpoint-Ausnahmen (dies ist eine Test-Unterfunktion).", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.privilegesTooltip": "Für den Zugriff auf Endpoint-Ausnahmen ist „Alle Bereiche“ erforderlich.A", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList": "Endpoint-Liste", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.description": "Zeigt alle Hosts an, auf denen Elastic Defend läuft, sowie deren relevante Integrationsdetails.", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.privilegesTooltip": "Für den Zugriff auf die Endpoint-Liste ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters": "Ereignisfilter", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.description": "Filtern Sie Endpoint-Ereignisse heraus, die Sie nicht in Elasticsearch speichern müssen oder möchten.", - "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.privilegesTooltip": "Für den Zugriff auf Ereignisfilter ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations": "Operationen ausführen", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.description": "Führen Sie Reaktionsmaßnahmen auf Skriptausführungen in der Antwortkonsole aus.", - "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.privilegesTooltip": "Für den Zugriff auf „Operationen ausführen“ ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations": "Dateioperationen", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.description": "Führen Sie dateibezogene Reaktionsmaßnahmen in der Antwortkonsole aus.", - "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.privilegesTooltip": "Für den Zugriff auf Dateivorgänge sind alle Spaces erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement": "Globale Artefaktverwaltung", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement.description": "Verwalten Sie die globale Zuweisung von Endpoint-Artefakten (z. B. Trusted Applications, Ereignisfilter) über alle Richtlinien hinweg. Diese Berechtigung steuert nur die globalen Zuweisungsrechte; für die vollständige Verwaltung der Artefakte sind Berechtigungen für jeden Artefakttyp erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation": "Host-Isolierung", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.description": "Führen Sie die Reaktionsmaßnahmen „Isolieren“ und „Freigeben“ durch.", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.privilegesTooltip": "Für den Zugriff auf die Host-Isolierung sind alle Spaces erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions": "Ausnahmen für die Host-Isolation", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.description": "Fügen Sie spezifische IP-Adressen hinzu, mit denen isolierte Hosts weiterhin kommunizieren dürfen, selbst wenn sie vom Rest des Netzwerks isoliert sind.", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip": "Für den Zugriff auf Ausnahmen für die Host-Isolation ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement": "Elastic Defend-Richtlinienverwaltung", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.description": "Greifen Sie auf die Elastic Defend-Integrationsrichtlinie zu, um Schutzmaßnahmen, Ereigniserfassung und erweiterte Elastic Features zu konfigurieren.", - "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.privilegesTooltip": "Für den Zugriff auf die Richtlinienverwaltung ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations": "Prozessabläufe", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.description": "Führen Sie prozessbezogene Reaktionsmaßnahmen in der Reaktionkonsole durch.", - "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.privilegesTooltip": "Für den Zugriff auf Prozessvorgänge sind alle Bereiche erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName": "Lesen", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory": "Verlauf der Reaktionsmaßnahmen", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.description": "Greifen Sie auf den Verlauf der Reaktionsmaßnahmen zu, die auf Endpoints durchgeführt wurden.", - "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.privilegesTooltip": "Alle Spaces sind für den Zugriff auf den Verlauf der Reaktionsaktionen erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations": "Scanvorgänge", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.description": "Führen Sie Bekämpfungsmaßnahmen für Ordnerscans in der Antwortkonsole aus.", - "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.privilegesTooltip": "Für den Zugriff auf Scan-Vorgänge ist „Alle Spaces“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "Vertrauenswürdige Anwendungen", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "Hilft, Konflikte mit anderer Software zu mildern, normalerweise mit anderen Antiviren- oder Endpoint-Sicherheitsanwendungen.", - "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "Für den Zugriff auf vertrauenswürdige Anwendungen ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights": "Automatische Problembehebung", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.description": "Zugriff auf die automatische Problembehebung.", - "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.privilegesTooltip": "Für den Zugriff auf die automatische Fehlerbehebung ist „Alle Bereiche“ erforderlich.", "securitySolutionPackages.markdown.insight.upsell": "Führen Sie ein Upgrade auf {requiredLicense} durch, um Einblicke in Untersuchungsleitfäden zu erhalten", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "Aktualisieren Sie auf {requiredLicense}, um die Interaktionen des Untersuchungsleitfadens nutzen zu können.", "securitySolutionPackages.navigation.landingLinks": "Security-Ansichten", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 460f05f1ed5de..cdf02a32c4d2a 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -7345,49 +7345,35 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.assistant.description": "Modifiez les champs par défaut autorisés à être utilisés par l'assistant IA et Attack discovery. Anonymisez n'importe quel contenu pour les champs sélectionnés.", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList": "Liste noire", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.description": "Étendez la protection d'Elastic Defend contre les processus malveillants et protégez-vous des applications potentiellement nuisibles.", - "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à la liste noire.", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions": "Exceptions de point de terminaison", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.description": "Utiliser les exceptions de point de terminaison (il s'agit d'une sous-fonctionnalité test).", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux exceptions de points de terminaison.", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList": "Liste de points de terminaison", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.description": "Affiche tous les hôtes exécutant Elastic Defend et leurs détails d'intégration associés.", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à la liste de points de terminaison.", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters": "Filtres d'événements", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.description": "Excluez les événements de point de terminaison dont vous n'avez pas besoin ou que vous ne souhaitez pas stocker dans Elasticsearch.", - "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux filtres d'événements.", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations": "Exécuter les opérations", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.description": "Effectuez les actions de réponse d'exécution de script dans la console de réponse.", - "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux opérations d'exécution.", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations": "Opérations de fichier", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.description": "Effectuez les actions de réponse liées aux fichiers dans la console de réponse.", - "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux opérations de fichier.", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement": "Gestion globale des artefacts", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement.description": "Gérez l'affectation globale des artefacts des points de terminaison (par exemple, les applications de confiance, les filtres d'événements) dans l'ensemble des politiques. Ce privilège gère uniquement les droits d'affectation globale ; il est nécessaire d'avoir des privilèges pour chaque type d'artefact pour assurer une gestion complète des artefacts.", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation": "Isolation de l'hôte", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.description": "Effectuez les actions de réponse \"isoler\" et \"libérer\".", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à l'isolation de l'hôte.", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions": "Exceptions d'isolation de l'hôte", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.description": "Ajoutez des adresses IP spécifiques avec lesquelles les hôtes isolés sont toujours autorisés à communiquer, même lorsqu'ils sont isolés du reste du réseau.", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux exceptions d'isolation de l'hôte.", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement": "Gestion des politiques Elastic Defend", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.description": "Accédez à la politique d'intégration Elastic Defend pour configurer les protections, la collecte des événements et les fonctionnalités de politique avancées.", - "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à la gestion des politiques.", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations": "Opérations de traitement", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.description": "Effectuez les actions de réponse liées aux processus dans la console de réponse.", - "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux opérations de traitement.", "securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName": "Lire", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory": "Historique des actions de réponse", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.description": "Accédez à l'historique des actions de réponse effectuées sur les points de terminaison.", - "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à l'historique des actions de réponse.", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations": "Opérations d’analyse", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.description": "Effectuez les actions de réponse liées aux analyses de dossiers dans la console de réponse.", - "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.privilegesTooltip": "Tous les espaces est requis pour l'accès aux opérations d’analyse.", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "Applications de confiance", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "Aide à atténuer les conflits avec d'autres logiciels, généralement d'autres applications d'antivirus ou de sécurité des points de terminaison.", - "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux applications de confiance.", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights": "Résolution des problèmes automatisée", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.description": "Accès à la résolution des problèmes automatisée.", - "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès à la résolution des problèmes automatisée.", "securitySolutionPackages.markdown.insight.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les informations des guides d'investigation", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les interactions des guides d'investigation", "securitySolutionPackages.navigation.landingLinks": "Vues de sécurité", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index a7955dea98e21..f500b21991289 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -7353,49 +7353,35 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.assistant.description": "AI AssistantおよびAttack Discoveryで使用できるデフォルトフィールドを変更します。選択したフィールドのすべてのコンテンツを匿名化します。", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList": "ブロックリスト", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.description": "Elastic Defendの悪意のあるプロセスに対する保護機能を拡張し、潜在的に有害なアプリケーションから保護します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.privilegesTooltip": "ブロックリストのアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions": "エンドポイント例外", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.description": "エンドポイント例外を使用します(これはテストサブ機能です)。", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.privilegesTooltip": "エンドポイント例外のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList": "エンドポイントリスト", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.description": "Elastic Defendを実行しているすべてのホストと、関連する統合の詳細が表示されます。", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.privilegesTooltip": "エンドポイントリストのアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters": "イベントフィルター", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.description": "Elasticsearchに保存する必要のない、あるいは保存しないエンドポイントイベントをフィルターします。", - "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.privilegesTooltip": "イベントフィルターのアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations": "実行操作", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.description": "応答コンソールでスクリプト実行応答アクションを実行します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.privilegesTooltip": "実行操作のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations": "ファイル操作", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.description": "対応コンソールでファイル関連の対応アクションを実行します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.privilegesTooltip": "ファイル操作のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement": "グローバルアーティファクト管理", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement.description": "すべてのポリシーでエンドポイントアーティファクト(例:信頼できるアプリケーション、イベントフィルター)のグローバル割り当てを管理します。この権限はグローバル割り当て権限のみを制御します。完全なアーティファクト管理には、各アーティファクトタイプの権限が必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation": "ホスト分離", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.description": "「isolate」および「release」応答アクションを実行します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.privilegesTooltip": "ホスト分離のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions": "ホスト分離例外", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.description": "ネットワークの他の部分から分離された場合でも、分離されたホストが通信することを許可する特定のIPアドレスを追加します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip": "ホスト分離例外のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement": "Elastic Defendポリシー管理", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.description": "Elastic Defendの統合ポリシーにアクセスし、プロテクション、イベント収集、および高度なポリシー機能を設定することができます。", - "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.privilegesTooltip": "ポリシー管理のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations": "プロセス操作", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.description": "対応コンソールでプロセス関連の対応アクションを実行します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.privilegesTooltip": "プロセス操作のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName": "読み取り", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory": "対応アクション履歴", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.description": "エンドポイントで実行された対応アクションの履歴を表示します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.privilegesTooltip": "対応アクション履歴アクセスにはすべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations": "スキャン操作", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.description": "対応コンソールでフォルダースキャン対応アクションを実行します。", - "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.privilegesTooltip": "スキャン操作のアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "信頼できるアプリケーション", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "他のソフトウェア(通常は他のウイルス対策またはエンドポイントセキュリティアプリケーション)との競合を軽減することができます。", - "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "信頼できるアプリケーションのアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights": "自動トラブルシューティング", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.description": "自動トラブルシューティングへのアクセス。", - "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.privilegesTooltip": "自動トラブルシューティングへのアクセスには、すべてのスペースが必要です。", "securitySolutionPackages.markdown.insight.upsell": "{requiredLicense}にアップグレードして、調査ガイドのインサイトを利用", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "{requiredLicense}にアップグレードして、調査ガイドのインタラクションを利用", "securitySolutionPackages.navigation.landingLinks": "セキュリティビュー", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 238602f1d654a..8967e8bdcb2d8 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -7344,49 +7344,35 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.assistant.description": "更改 AI 助手和 Attack Discovery 功能可使用的默认字段。匿名处理选定字段的任何内容。", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList": "阻止列表", "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.description": "针对恶意进程扩大 Elastic Defend 防护,并防范具有潜在危害的应用程序。", - "securitySolutionPackages.features.featureRegistry.subFeatures.blockList.privilegesTooltip": "访问阻止列表需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions": "终端例外", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.description": "使用终端例外(这是一项测试子功能)。", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.privilegesTooltip": "访问终端例外需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList": "终端列表", "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.description": "显示运行 Elastic Defend 的所有主机及其相关集成详情。", - "securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.privilegesTooltip": "访问终端列表需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters": "事件筛选", "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.description": "筛除您不需要或希望存储在 Elasticsearch 中的终端事件。", - "securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.privilegesTooltip": "访问事件筛选需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations": "执行操作", "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.description": "在响应控制台中执行脚本执行响应操作。", - "securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.privilegesTooltip": "访问执行操作需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations": "文件操作", "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.description": "在响应控制台中执行文件相关响应操作。", - "securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.privilegesTooltip": "访问文件操作需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement": "全局项目管理", "securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement.description": "跨所有策略管理终端项目(如受信任的应用程序、事件筛选)的全局分配。此权限仅控制全局分配权限;进行全面项目管理需要每种项目类型的权限。", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation": "主机隔离", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.description": "执行“隔离”和“释放”响应操作。", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.privilegesTooltip": "访问主机隔离需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions": "主机隔离例外", "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.description": "添加仍允许已隔离(即使与剩余网络隔离)主机与其通信的特定 IP 地址。", - "securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip": "访问主机隔离例外需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement": "Elastic Defend 策略管理", "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.description": "访问 Elastic Defend 集成策略以配置防护、事件收集和高级策略功能。", - "securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.privilegesTooltip": "访问策略管理需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations": "进程操作", "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.description": "在响应控制台中执行进程相关响应操作。", - "securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.privilegesTooltip": "访问进程操作需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName": "读取", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory": "响应操作历史记录", "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.description": "访问在终端上执行的响应操作的历史记录。", - "securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.privilegesTooltip": "访问响应操作历史记录需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations": "扫描操作", "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.description": "在响应控制台中执行文件夹扫描响应操作。", - "securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.privilegesTooltip": "访问扫描操作需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "受信任的应用程序", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "帮助减少与其他软件(通常指其他防病毒或终端安全应用程序)的冲突。", - "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "访问受信任的应用程序需要所有工作区。", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights": "自动故障排除", "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.description": "访问自动故障排除。", - "securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.privilegesTooltip": "需要所有工作区的访问权限才能使用自动故障排除功能。", "securitySolutionPackages.markdown.insight.upsell": "升级到{requiredLicense}以利用调查指南中的洞见", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "升级到 {requiredLicense} 以利用调查指南交互", "securitySolutionPackages.navigation.landingLinks": "安全视图", diff --git a/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts index f99aaa60cff8e..41006fdff126d 100644 --- a/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts @@ -24,11 +24,6 @@ const TRANSLATIONS = Object.freeze({ }); export const endpointListSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.endpointList.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Endpoint List access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.endpointList', { defaultMessage: 'Endpoint List' } @@ -72,11 +67,6 @@ export const endpointListSubFeature = (): SubFeatureConfig => ({ }); export const trustedApplicationsSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Trusted Applications access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications', { defaultMessage: 'Trusted Applications' } @@ -126,13 +116,6 @@ export const trustedApplicationsSubFeature = (): SubFeatureConfig => ({ }); export const trustedDevicesSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.trustedDevices.privilegesTooltip', - { - defaultMessage: 'All Spaces is required for Trusted Devices access.', - } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.trustedDevices', { @@ -183,11 +166,6 @@ export const trustedDevicesSubFeature = (): SubFeatureConfig => ({ }); export const hostIsolationExceptionsBasicSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Host Isolation Exceptions access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolationExceptions', { defaultMessage: 'Host Isolation Exceptions' } @@ -236,11 +214,6 @@ export const hostIsolationExceptionsBasicSubFeature = (): SubFeatureConfig => ({ ], }); export const blocklistSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.blockList.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Blocklist access.' } - ), name: i18n.translate('securitySolutionPackages.features.featureRegistry.subFeatures.blockList', { defaultMessage: 'Blocklist', }), @@ -288,11 +261,6 @@ export const blocklistSubFeature = (): SubFeatureConfig => ({ ], }); export const eventFiltersSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Event Filters access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.eventFilters', { defaultMessage: 'Event Filters' } @@ -341,11 +309,6 @@ export const eventFiltersSubFeature = (): SubFeatureConfig => ({ ], }); export const policyManagementSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Policy Management access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.policyManagement', { defaultMessage: 'Elastic Defend Policy Management' } @@ -389,11 +352,6 @@ export const policyManagementSubFeature = (): SubFeatureConfig => ({ }); export const responseActionsHistorySubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Response Actions History access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.responseActionsHistory', { defaultMessage: 'Response Actions History' } @@ -433,11 +391,6 @@ export const responseActionsHistorySubFeature = (): SubFeatureConfig => ({ ], }); export const hostIsolationSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Host Isolation access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.hostIsolation', { defaultMessage: 'Host Isolation' } @@ -467,11 +420,6 @@ export const hostIsolationSubFeature = (): SubFeatureConfig => ({ }); export const processOperationsSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.processOperations.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Process Operations access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.processOperations', { defaultMessage: 'Process Operations' } @@ -500,11 +448,6 @@ export const processOperationsSubFeature = (): SubFeatureConfig => ({ ], }); export const fileOperationsSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations.privilegesTooltip', - { defaultMessage: 'All Spaces is required for File Operations access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.fileOperations', { defaultMessage: 'File Operations' } @@ -536,11 +479,6 @@ export const fileOperationsSubFeature = (): SubFeatureConfig => ({ // execute operations are not available in 8.7, // but will be available in 8.8 export const executeActionSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Execute Operations access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.executeOperations', { defaultMessage: 'Execute Operations' } @@ -571,11 +509,6 @@ export const executeActionSubFeature = (): SubFeatureConfig => ({ // 8.15 feature export const scanActionSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Scan Operations access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.scanOperations', { defaultMessage: 'Scan Operations' } @@ -605,11 +538,6 @@ export const scanActionSubFeature = (): SubFeatureConfig => ({ }); export const workflowInsightsSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Automatic Troubleshooting access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.workflowInsights', { defaultMessage: 'Automatic Troubleshooting' } @@ -651,11 +579,6 @@ export const workflowInsightsSubFeature = (): SubFeatureConfig => ({ }); export const endpointExceptionsSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: true, - privilegesTooltip: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions.privilegesTooltip', - { defaultMessage: 'All Spaces is required for Endpoint Exceptions access.' } - ), name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.endpointExceptions', { defaultMessage: 'Endpoint Exceptions' } @@ -725,8 +648,6 @@ export const globalArtifactManagementSubFeature = ( ); return { - requireAllSpaces: false, - privilegesTooltip: undefined, name: GLOBAL_ARTIFACT_MANAGEMENT, description: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.globalArtifactManagement.description', diff --git a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts index 94ea900639a1f..8a678ab0e61e2 100644 --- a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_sub_features.ts @@ -108,9 +108,6 @@ export const getSecuritySubFeaturesMap = ({ subFeature = addSubFeatureReplacements(subFeature, featureReplacements); } - // Space awareness is now always enabled - set requireAllSpaces to false and remove privilegesTooltip - subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; - return [id, subFeature]; }) ); diff --git a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts index 83c17704b8cfb..1540ab318f4d4 100644 --- a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_sub_features.ts @@ -118,9 +118,6 @@ export const getSecurityV2SubFeaturesMap = ({ subFeature = addSubFeatureReplacements(subFeature, featureReplacements); } - // Space awareness is now always enabled - set requireAllSpaces to false and remove privilegesTooltip - subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; - return [id, subFeature]; }) ); diff --git a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts index 5063ec9fdb9f0..0a06d273f8d00 100644 --- a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_sub_features.ts @@ -95,9 +95,6 @@ export const getSecurityV3SubFeaturesMap = ({ subFeature = addSubFeatureReplacements(subFeature, featureReplacements); } - // Space awareness is now always enabled - set requireAllSpaces to false and remove privilegesTooltip - subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; - return [id, subFeature]; }) ); diff --git a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts index 4877ef932f367..59879ba52195d 100644 --- a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts @@ -95,9 +95,6 @@ export const getSecurityV4SubFeaturesMap = ({ subFeature = addSubFeatureReplacements(subFeature, featureReplacements); } - // Space awareness is now always enabled - set requireAllSpaces to false and remove privilegesTooltip - subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; - return [id, subFeature]; }) ); diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts index 6bf4461430984..cfcd1585d56e2 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts @@ -64,18 +64,7 @@ export const getSecurityV5SubFeaturesMap = ({ [SecuritySubFeatureId.scanAction, scanActionSubFeature()], ]; - const securitySubFeaturesMap = new Map( - securitySubFeaturesList.map(([id, originalSubFeature]) => { - let subFeature = originalSubFeature; - - // If the feature is space-aware, we need to set false to the requireAllSpaces flag and remove the privilegesTooltip - if (experimentalFeatures.endpointManagementSpaceAwarenessEnabled) { - subFeature = { ...subFeature, requireAllSpaces: false, privilegesTooltip: undefined }; - } - - return [id, subFeature]; - }) - ); + const securitySubFeaturesMap = new Map(securitySubFeaturesList); // Remove disabled experimental features if (!experimentalFeatures.defendInsightsPolicyResponseFailure) { From f2b15eef597fc764b5bb92b7810bfc359b17ff05 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 30 Oct 2025 12:01:10 +0000 Subject: [PATCH 14/85] Changes from node scripts/eslint_all_files --no-cache --fix --- .../features/src/security/v5_features/kibana_sub_features.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts index cfcd1585d56e2..83e5bb9c051dc 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts @@ -64,7 +64,9 @@ export const getSecurityV5SubFeaturesMap = ({ [SecuritySubFeatureId.scanAction, scanActionSubFeature()], ]; - const securitySubFeaturesMap = new Map(securitySubFeaturesList); + const securitySubFeaturesMap = new Map( + securitySubFeaturesList + ); // Remove disabled experimental features if (!experimentalFeatures.defendInsightsPolicyResponseFailure) { From f47b16ed5958e4c218336228962765115bd4526c Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Thu, 30 Oct 2025 15:35:35 +0100 Subject: [PATCH 15/85] fix manage value lists button disabled for rules-all The logic to show it was relying on the old siemPrivileges, however value lists is now under rules. --- .../detection_engine/lists/use_lists_privileges.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx index d95974439ac2a..3b88e5b50ad51 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx @@ -57,7 +57,7 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { canWriteIndex: null, }); - const { listPrivileges, siemPrivileges } = useUserPrivileges(); + const { listPrivileges, rulesPrivileges } = useUserPrivileges(); // handleReadResult useEffect(() => { @@ -72,16 +72,16 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { isAuthenticated, canReadIndex: canReadIndex(listsPrivileges) && canReadIndex(listItemsPrivileges), canManageIndex: - siemPrivileges.crud && + rulesPrivileges.edit && canManageIndex(listsPrivileges) && canManageIndex(listItemsPrivileges), canWriteIndex: - siemPrivileges.crud && + rulesPrivileges.edit && canWriteIndex(listsPrivileges) && canWriteIndex(listItemsPrivileges), }); } - }, [listPrivileges.result, siemPrivileges.crud]); + }, [listPrivileges.result, rulesPrivileges.edit]); // handleReadError useEffect(() => { From 51c9819588ecd3c040582ec65aeb9b301badaa36 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Thu, 30 Oct 2025 12:58:41 -0400 Subject: [PATCH 16/85] fix showing rule update callouts when users don't have rules-all --- .../rule_management/hooks/use_rule_update_callout.tsx | 7 +++++-- .../rule_management_ui/pages/rule_management/index.tsx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx index a4bff69d4fb99..7cdece866adf6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import type { RuleResponse } from '../../../../common/api/detection_engine'; import { RuleUpdateCallout } from '../components/rule_details/rule_update_callout'; @@ -21,8 +22,9 @@ export const useRuleUpdateCallout = ({ message, actionButton, onUpgrade, -}: UseRuleUpdateCalloutProps): JSX.Element | null => - !rule || rule.rule_source.type !== 'external' ? null : ( +}: UseRuleUpdateCalloutProps): JSX.Element | null => { + const canEditRules = useUserPrivileges().rulesPrivileges.edit; + return !rule || rule.rule_source.type !== 'external' || !canEditRules ? null : ( ); +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index 355e2643a4aa7..6a1803e3e0e6b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -145,7 +145,7 @@ const RulesPageComponent: React.FC = () => { {isDoesNotMatchForIndicatorMatchRuleEnabled && } - + Date: Fri, 31 Oct 2025 15:47:33 +0100 Subject: [PATCH 17/85] fix authorization tests Reshuffling privileges and removal of alerting privileges from siemV5. These alerting privileges exist exclusively in securitySolutionRulesV1 --- .../platform_security/authorization.ts | 423 ++---------------- 1 file changed, 45 insertions(+), 378 deletions(-) diff --git a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts index a4fb526e76409..86524d40823fe 100644 --- a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts +++ b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts @@ -9795,8 +9795,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.notifications/siem/rule/delete", "alerting:siem.notifications/siem/rule/update", "alerting:siem.notifications/siem/rule/updateApiKey", - "alerting:siem.notifications/siem/rule/enable", - "alerting:siem.notifications/siem/rule/disable", "alerting:siem.notifications/siem/rule/muteAll", "alerting:siem.notifications/siem/rule/unmuteAll", "alerting:siem.notifications/siem/rule/muteAlert", @@ -9804,13 +9802,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.notifications/siem/rule/snooze", "alerting:siem.notifications/siem/rule/bulkEdit", "alerting:siem.notifications/siem/rule/bulkDelete", - "alerting:siem.notifications/siem/rule/bulkEnable", - "alerting:siem.notifications/siem/rule/bulkDisable", "alerting:siem.notifications/siem/rule/unsnooze", "alerting:siem.notifications/siem/rule/runSoon", - "alerting:siem.notifications/siem/rule/scheduleBackfill", + "alerting:siem.notifications/siem/rule/enable", + "alerting:siem.notifications/siem/rule/disable", + "alerting:siem.notifications/siem/rule/bulkEnable", + "alerting:siem.notifications/siem/rule/bulkDisable", "alerting:siem.notifications/siem/rule/deleteBackfill", "alerting:siem.notifications/siem/rule/fillGaps", + "alerting:siem.notifications/siem/rule/scheduleBackfill", "alerting:siem.esqlRule/siem/rule/get", "alerting:siem.esqlRule/siem/rule/bulkGet", "alerting:siem.esqlRule/siem/rule/getRuleState", @@ -9827,8 +9827,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.esqlRule/siem/rule/delete", "alerting:siem.esqlRule/siem/rule/update", "alerting:siem.esqlRule/siem/rule/updateApiKey", - "alerting:siem.esqlRule/siem/rule/enable", - "alerting:siem.esqlRule/siem/rule/disable", "alerting:siem.esqlRule/siem/rule/muteAll", "alerting:siem.esqlRule/siem/rule/unmuteAll", "alerting:siem.esqlRule/siem/rule/muteAlert", @@ -9836,13 +9834,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.esqlRule/siem/rule/snooze", "alerting:siem.esqlRule/siem/rule/bulkEdit", "alerting:siem.esqlRule/siem/rule/bulkDelete", - "alerting:siem.esqlRule/siem/rule/bulkEnable", - "alerting:siem.esqlRule/siem/rule/bulkDisable", "alerting:siem.esqlRule/siem/rule/unsnooze", "alerting:siem.esqlRule/siem/rule/runSoon", - "alerting:siem.esqlRule/siem/rule/scheduleBackfill", + "alerting:siem.esqlRule/siem/rule/enable", + "alerting:siem.esqlRule/siem/rule/disable", + "alerting:siem.esqlRule/siem/rule/bulkEnable", + "alerting:siem.esqlRule/siem/rule/bulkDisable", "alerting:siem.esqlRule/siem/rule/deleteBackfill", "alerting:siem.esqlRule/siem/rule/fillGaps", + "alerting:siem.esqlRule/siem/rule/scheduleBackfill", "alerting:siem.eqlRule/siem/rule/get", "alerting:siem.eqlRule/siem/rule/bulkGet", "alerting:siem.eqlRule/siem/rule/getRuleState", @@ -9859,8 +9859,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.eqlRule/siem/rule/delete", "alerting:siem.eqlRule/siem/rule/update", "alerting:siem.eqlRule/siem/rule/updateApiKey", - "alerting:siem.eqlRule/siem/rule/enable", - "alerting:siem.eqlRule/siem/rule/disable", "alerting:siem.eqlRule/siem/rule/muteAll", "alerting:siem.eqlRule/siem/rule/unmuteAll", "alerting:siem.eqlRule/siem/rule/muteAlert", @@ -9868,13 +9866,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.eqlRule/siem/rule/snooze", "alerting:siem.eqlRule/siem/rule/bulkEdit", "alerting:siem.eqlRule/siem/rule/bulkDelete", - "alerting:siem.eqlRule/siem/rule/bulkEnable", - "alerting:siem.eqlRule/siem/rule/bulkDisable", "alerting:siem.eqlRule/siem/rule/unsnooze", "alerting:siem.eqlRule/siem/rule/runSoon", - "alerting:siem.eqlRule/siem/rule/scheduleBackfill", + "alerting:siem.eqlRule/siem/rule/enable", + "alerting:siem.eqlRule/siem/rule/disable", + "alerting:siem.eqlRule/siem/rule/bulkEnable", + "alerting:siem.eqlRule/siem/rule/bulkDisable", "alerting:siem.eqlRule/siem/rule/deleteBackfill", "alerting:siem.eqlRule/siem/rule/fillGaps", + "alerting:siem.eqlRule/siem/rule/scheduleBackfill", "alerting:siem.indicatorRule/siem/rule/get", "alerting:siem.indicatorRule/siem/rule/bulkGet", "alerting:siem.indicatorRule/siem/rule/getRuleState", @@ -9891,8 +9891,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.indicatorRule/siem/rule/delete", "alerting:siem.indicatorRule/siem/rule/update", "alerting:siem.indicatorRule/siem/rule/updateApiKey", - "alerting:siem.indicatorRule/siem/rule/enable", - "alerting:siem.indicatorRule/siem/rule/disable", "alerting:siem.indicatorRule/siem/rule/muteAll", "alerting:siem.indicatorRule/siem/rule/unmuteAll", "alerting:siem.indicatorRule/siem/rule/muteAlert", @@ -9900,13 +9898,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.indicatorRule/siem/rule/snooze", "alerting:siem.indicatorRule/siem/rule/bulkEdit", "alerting:siem.indicatorRule/siem/rule/bulkDelete", - "alerting:siem.indicatorRule/siem/rule/bulkEnable", - "alerting:siem.indicatorRule/siem/rule/bulkDisable", "alerting:siem.indicatorRule/siem/rule/unsnooze", "alerting:siem.indicatorRule/siem/rule/runSoon", - "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", + "alerting:siem.indicatorRule/siem/rule/enable", + "alerting:siem.indicatorRule/siem/rule/disable", + "alerting:siem.indicatorRule/siem/rule/bulkEnable", + "alerting:siem.indicatorRule/siem/rule/bulkDisable", "alerting:siem.indicatorRule/siem/rule/deleteBackfill", "alerting:siem.indicatorRule/siem/rule/fillGaps", + "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", "alerting:siem.mlRule/siem/rule/get", "alerting:siem.mlRule/siem/rule/bulkGet", "alerting:siem.mlRule/siem/rule/getRuleState", @@ -9923,8 +9923,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.mlRule/siem/rule/delete", "alerting:siem.mlRule/siem/rule/update", "alerting:siem.mlRule/siem/rule/updateApiKey", - "alerting:siem.mlRule/siem/rule/enable", - "alerting:siem.mlRule/siem/rule/disable", "alerting:siem.mlRule/siem/rule/muteAll", "alerting:siem.mlRule/siem/rule/unmuteAll", "alerting:siem.mlRule/siem/rule/muteAlert", @@ -9932,13 +9930,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.mlRule/siem/rule/snooze", "alerting:siem.mlRule/siem/rule/bulkEdit", "alerting:siem.mlRule/siem/rule/bulkDelete", - "alerting:siem.mlRule/siem/rule/bulkEnable", - "alerting:siem.mlRule/siem/rule/bulkDisable", "alerting:siem.mlRule/siem/rule/unsnooze", "alerting:siem.mlRule/siem/rule/runSoon", - "alerting:siem.mlRule/siem/rule/scheduleBackfill", + "alerting:siem.mlRule/siem/rule/enable", + "alerting:siem.mlRule/siem/rule/disable", + "alerting:siem.mlRule/siem/rule/bulkEnable", + "alerting:siem.mlRule/siem/rule/bulkDisable", "alerting:siem.mlRule/siem/rule/deleteBackfill", "alerting:siem.mlRule/siem/rule/fillGaps", + "alerting:siem.mlRule/siem/rule/scheduleBackfill", "alerting:siem.queryRule/siem/rule/get", "alerting:siem.queryRule/siem/rule/bulkGet", "alerting:siem.queryRule/siem/rule/getRuleState", @@ -9955,8 +9955,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.queryRule/siem/rule/delete", "alerting:siem.queryRule/siem/rule/update", "alerting:siem.queryRule/siem/rule/updateApiKey", - "alerting:siem.queryRule/siem/rule/enable", - "alerting:siem.queryRule/siem/rule/disable", "alerting:siem.queryRule/siem/rule/muteAll", "alerting:siem.queryRule/siem/rule/unmuteAll", "alerting:siem.queryRule/siem/rule/muteAlert", @@ -9964,13 +9962,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.queryRule/siem/rule/snooze", "alerting:siem.queryRule/siem/rule/bulkEdit", "alerting:siem.queryRule/siem/rule/bulkDelete", - "alerting:siem.queryRule/siem/rule/bulkEnable", - "alerting:siem.queryRule/siem/rule/bulkDisable", "alerting:siem.queryRule/siem/rule/unsnooze", "alerting:siem.queryRule/siem/rule/runSoon", - "alerting:siem.queryRule/siem/rule/scheduleBackfill", + "alerting:siem.queryRule/siem/rule/enable", + "alerting:siem.queryRule/siem/rule/disable", + "alerting:siem.queryRule/siem/rule/bulkEnable", + "alerting:siem.queryRule/siem/rule/bulkDisable", "alerting:siem.queryRule/siem/rule/deleteBackfill", "alerting:siem.queryRule/siem/rule/fillGaps", + "alerting:siem.queryRule/siem/rule/scheduleBackfill", "alerting:siem.savedQueryRule/siem/rule/get", "alerting:siem.savedQueryRule/siem/rule/bulkGet", "alerting:siem.savedQueryRule/siem/rule/getRuleState", @@ -9987,8 +9987,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.savedQueryRule/siem/rule/delete", "alerting:siem.savedQueryRule/siem/rule/update", "alerting:siem.savedQueryRule/siem/rule/updateApiKey", - "alerting:siem.savedQueryRule/siem/rule/enable", - "alerting:siem.savedQueryRule/siem/rule/disable", "alerting:siem.savedQueryRule/siem/rule/muteAll", "alerting:siem.savedQueryRule/siem/rule/unmuteAll", "alerting:siem.savedQueryRule/siem/rule/muteAlert", @@ -9996,13 +9994,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.savedQueryRule/siem/rule/snooze", "alerting:siem.savedQueryRule/siem/rule/bulkEdit", "alerting:siem.savedQueryRule/siem/rule/bulkDelete", - "alerting:siem.savedQueryRule/siem/rule/bulkEnable", - "alerting:siem.savedQueryRule/siem/rule/bulkDisable", "alerting:siem.savedQueryRule/siem/rule/unsnooze", "alerting:siem.savedQueryRule/siem/rule/runSoon", - "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", + "alerting:siem.savedQueryRule/siem/rule/enable", + "alerting:siem.savedQueryRule/siem/rule/disable", + "alerting:siem.savedQueryRule/siem/rule/bulkEnable", + "alerting:siem.savedQueryRule/siem/rule/bulkDisable", "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", "alerting:siem.savedQueryRule/siem/rule/fillGaps", + "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", "alerting:siem.thresholdRule/siem/rule/get", "alerting:siem.thresholdRule/siem/rule/bulkGet", "alerting:siem.thresholdRule/siem/rule/getRuleState", @@ -10019,8 +10019,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.thresholdRule/siem/rule/delete", "alerting:siem.thresholdRule/siem/rule/update", "alerting:siem.thresholdRule/siem/rule/updateApiKey", - "alerting:siem.thresholdRule/siem/rule/enable", - "alerting:siem.thresholdRule/siem/rule/disable", "alerting:siem.thresholdRule/siem/rule/muteAll", "alerting:siem.thresholdRule/siem/rule/unmuteAll", "alerting:siem.thresholdRule/siem/rule/muteAlert", @@ -10028,13 +10026,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.thresholdRule/siem/rule/snooze", "alerting:siem.thresholdRule/siem/rule/bulkEdit", "alerting:siem.thresholdRule/siem/rule/bulkDelete", - "alerting:siem.thresholdRule/siem/rule/bulkEnable", - "alerting:siem.thresholdRule/siem/rule/bulkDisable", "alerting:siem.thresholdRule/siem/rule/unsnooze", "alerting:siem.thresholdRule/siem/rule/runSoon", - "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", + "alerting:siem.thresholdRule/siem/rule/enable", + "alerting:siem.thresholdRule/siem/rule/disable", + "alerting:siem.thresholdRule/siem/rule/bulkEnable", + "alerting:siem.thresholdRule/siem/rule/bulkDisable", "alerting:siem.thresholdRule/siem/rule/deleteBackfill", "alerting:siem.thresholdRule/siem/rule/fillGaps", + "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", "alerting:siem.newTermsRule/siem/rule/get", "alerting:siem.newTermsRule/siem/rule/bulkGet", "alerting:siem.newTermsRule/siem/rule/getRuleState", @@ -10051,8 +10051,6 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.newTermsRule/siem/rule/delete", "alerting:siem.newTermsRule/siem/rule/update", "alerting:siem.newTermsRule/siem/rule/updateApiKey", - "alerting:siem.newTermsRule/siem/rule/enable", - "alerting:siem.newTermsRule/siem/rule/disable", "alerting:siem.newTermsRule/siem/rule/muteAll", "alerting:siem.newTermsRule/siem/rule/unmuteAll", "alerting:siem.newTermsRule/siem/rule/muteAlert", @@ -10060,13 +10058,15 @@ export default function ({ getService }: FtrProviderContext) { "alerting:siem.newTermsRule/siem/rule/snooze", "alerting:siem.newTermsRule/siem/rule/bulkEdit", "alerting:siem.newTermsRule/siem/rule/bulkDelete", - "alerting:siem.newTermsRule/siem/rule/bulkEnable", - "alerting:siem.newTermsRule/siem/rule/bulkDisable", "alerting:siem.newTermsRule/siem/rule/unsnooze", "alerting:siem.newTermsRule/siem/rule/runSoon", - "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", + "alerting:siem.newTermsRule/siem/rule/enable", + "alerting:siem.newTermsRule/siem/rule/disable", + "alerting:siem.newTermsRule/siem/rule/bulkEnable", + "alerting:siem.newTermsRule/siem/rule/bulkDisable", "alerting:siem.newTermsRule/siem/rule/deleteBackfill", "alerting:siem.newTermsRule/siem/rule/fillGaps", + "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", "alerting:siem.notifications/siem/alert/get", "alerting:siem.notifications/siem/alert/find", "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", @@ -12042,339 +12042,6 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "alerting:siem.notifications/siem/rule/get", - "alerting:siem.notifications/siem/rule/bulkGet", - "alerting:siem.notifications/siem/rule/getRuleState", - "alerting:siem.notifications/siem/rule/getAlertSummary", - "alerting:siem.notifications/siem/rule/getExecutionLog", - "alerting:siem.notifications/siem/rule/getActionErrorLog", - "alerting:siem.notifications/siem/rule/find", - "alerting:siem.notifications/siem/rule/getRuleExecutionKPI", - "alerting:siem.notifications/siem/rule/getBackfill", - "alerting:siem.notifications/siem/rule/findBackfill", - "alerting:siem.notifications/siem/rule/findGaps", - "alerting:siem.notifications/siem/rule/bulkEditParams", - "alerting:siem.notifications/siem/rule/create", - "alerting:siem.notifications/siem/rule/delete", - "alerting:siem.notifications/siem/rule/update", - "alerting:siem.notifications/siem/rule/updateApiKey", - "alerting:siem.notifications/siem/rule/muteAll", - "alerting:siem.notifications/siem/rule/unmuteAll", - "alerting:siem.notifications/siem/rule/muteAlert", - "alerting:siem.notifications/siem/rule/unmuteAlert", - "alerting:siem.notifications/siem/rule/snooze", - "alerting:siem.notifications/siem/rule/bulkEdit", - "alerting:siem.notifications/siem/rule/bulkDelete", - "alerting:siem.notifications/siem/rule/unsnooze", - "alerting:siem.notifications/siem/rule/runSoon", - "alerting:siem.notifications/siem/rule/enable", - "alerting:siem.notifications/siem/rule/disable", - "alerting:siem.notifications/siem/rule/bulkEnable", - "alerting:siem.notifications/siem/rule/bulkDisable", - "alerting:siem.notifications/siem/rule/deleteBackfill", - "alerting:siem.notifications/siem/rule/fillGaps", - "alerting:siem.notifications/siem/rule/scheduleBackfill", - "alerting:siem.esqlRule/siem/rule/get", - "alerting:siem.esqlRule/siem/rule/bulkGet", - "alerting:siem.esqlRule/siem/rule/getRuleState", - "alerting:siem.esqlRule/siem/rule/getAlertSummary", - "alerting:siem.esqlRule/siem/rule/getExecutionLog", - "alerting:siem.esqlRule/siem/rule/getActionErrorLog", - "alerting:siem.esqlRule/siem/rule/find", - "alerting:siem.esqlRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.esqlRule/siem/rule/getBackfill", - "alerting:siem.esqlRule/siem/rule/findBackfill", - "alerting:siem.esqlRule/siem/rule/findGaps", - "alerting:siem.esqlRule/siem/rule/bulkEditParams", - "alerting:siem.esqlRule/siem/rule/create", - "alerting:siem.esqlRule/siem/rule/delete", - "alerting:siem.esqlRule/siem/rule/update", - "alerting:siem.esqlRule/siem/rule/updateApiKey", - "alerting:siem.esqlRule/siem/rule/muteAll", - "alerting:siem.esqlRule/siem/rule/unmuteAll", - "alerting:siem.esqlRule/siem/rule/muteAlert", - "alerting:siem.esqlRule/siem/rule/unmuteAlert", - "alerting:siem.esqlRule/siem/rule/snooze", - "alerting:siem.esqlRule/siem/rule/bulkEdit", - "alerting:siem.esqlRule/siem/rule/bulkDelete", - "alerting:siem.esqlRule/siem/rule/unsnooze", - "alerting:siem.esqlRule/siem/rule/runSoon", - "alerting:siem.esqlRule/siem/rule/enable", - "alerting:siem.esqlRule/siem/rule/disable", - "alerting:siem.esqlRule/siem/rule/bulkEnable", - "alerting:siem.esqlRule/siem/rule/bulkDisable", - "alerting:siem.esqlRule/siem/rule/deleteBackfill", - "alerting:siem.esqlRule/siem/rule/fillGaps", - "alerting:siem.esqlRule/siem/rule/scheduleBackfill", - "alerting:siem.eqlRule/siem/rule/get", - "alerting:siem.eqlRule/siem/rule/bulkGet", - "alerting:siem.eqlRule/siem/rule/getRuleState", - "alerting:siem.eqlRule/siem/rule/getAlertSummary", - "alerting:siem.eqlRule/siem/rule/getExecutionLog", - "alerting:siem.eqlRule/siem/rule/getActionErrorLog", - "alerting:siem.eqlRule/siem/rule/find", - "alerting:siem.eqlRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.eqlRule/siem/rule/getBackfill", - "alerting:siem.eqlRule/siem/rule/findBackfill", - "alerting:siem.eqlRule/siem/rule/findGaps", - "alerting:siem.eqlRule/siem/rule/bulkEditParams", - "alerting:siem.eqlRule/siem/rule/create", - "alerting:siem.eqlRule/siem/rule/delete", - "alerting:siem.eqlRule/siem/rule/update", - "alerting:siem.eqlRule/siem/rule/updateApiKey", - "alerting:siem.eqlRule/siem/rule/muteAll", - "alerting:siem.eqlRule/siem/rule/unmuteAll", - "alerting:siem.eqlRule/siem/rule/muteAlert", - "alerting:siem.eqlRule/siem/rule/unmuteAlert", - "alerting:siem.eqlRule/siem/rule/snooze", - "alerting:siem.eqlRule/siem/rule/bulkEdit", - "alerting:siem.eqlRule/siem/rule/bulkDelete", - "alerting:siem.eqlRule/siem/rule/unsnooze", - "alerting:siem.eqlRule/siem/rule/runSoon", - "alerting:siem.eqlRule/siem/rule/enable", - "alerting:siem.eqlRule/siem/rule/disable", - "alerting:siem.eqlRule/siem/rule/bulkEnable", - "alerting:siem.eqlRule/siem/rule/bulkDisable", - "alerting:siem.eqlRule/siem/rule/deleteBackfill", - "alerting:siem.eqlRule/siem/rule/fillGaps", - "alerting:siem.eqlRule/siem/rule/scheduleBackfill", - "alerting:siem.indicatorRule/siem/rule/get", - "alerting:siem.indicatorRule/siem/rule/bulkGet", - "alerting:siem.indicatorRule/siem/rule/getRuleState", - "alerting:siem.indicatorRule/siem/rule/getAlertSummary", - "alerting:siem.indicatorRule/siem/rule/getExecutionLog", - "alerting:siem.indicatorRule/siem/rule/getActionErrorLog", - "alerting:siem.indicatorRule/siem/rule/find", - "alerting:siem.indicatorRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.indicatorRule/siem/rule/getBackfill", - "alerting:siem.indicatorRule/siem/rule/findBackfill", - "alerting:siem.indicatorRule/siem/rule/findGaps", - "alerting:siem.indicatorRule/siem/rule/bulkEditParams", - "alerting:siem.indicatorRule/siem/rule/create", - "alerting:siem.indicatorRule/siem/rule/delete", - "alerting:siem.indicatorRule/siem/rule/update", - "alerting:siem.indicatorRule/siem/rule/updateApiKey", - "alerting:siem.indicatorRule/siem/rule/muteAll", - "alerting:siem.indicatorRule/siem/rule/unmuteAll", - "alerting:siem.indicatorRule/siem/rule/muteAlert", - "alerting:siem.indicatorRule/siem/rule/unmuteAlert", - "alerting:siem.indicatorRule/siem/rule/snooze", - "alerting:siem.indicatorRule/siem/rule/bulkEdit", - "alerting:siem.indicatorRule/siem/rule/bulkDelete", - "alerting:siem.indicatorRule/siem/rule/unsnooze", - "alerting:siem.indicatorRule/siem/rule/runSoon", - "alerting:siem.indicatorRule/siem/rule/enable", - "alerting:siem.indicatorRule/siem/rule/disable", - "alerting:siem.indicatorRule/siem/rule/bulkEnable", - "alerting:siem.indicatorRule/siem/rule/bulkDisable", - "alerting:siem.indicatorRule/siem/rule/deleteBackfill", - "alerting:siem.indicatorRule/siem/rule/fillGaps", - "alerting:siem.indicatorRule/siem/rule/scheduleBackfill", - "alerting:siem.mlRule/siem/rule/get", - "alerting:siem.mlRule/siem/rule/bulkGet", - "alerting:siem.mlRule/siem/rule/getRuleState", - "alerting:siem.mlRule/siem/rule/getAlertSummary", - "alerting:siem.mlRule/siem/rule/getExecutionLog", - "alerting:siem.mlRule/siem/rule/getActionErrorLog", - "alerting:siem.mlRule/siem/rule/find", - "alerting:siem.mlRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.mlRule/siem/rule/getBackfill", - "alerting:siem.mlRule/siem/rule/findBackfill", - "alerting:siem.mlRule/siem/rule/findGaps", - "alerting:siem.mlRule/siem/rule/bulkEditParams", - "alerting:siem.mlRule/siem/rule/create", - "alerting:siem.mlRule/siem/rule/delete", - "alerting:siem.mlRule/siem/rule/update", - "alerting:siem.mlRule/siem/rule/updateApiKey", - "alerting:siem.mlRule/siem/rule/muteAll", - "alerting:siem.mlRule/siem/rule/unmuteAll", - "alerting:siem.mlRule/siem/rule/muteAlert", - "alerting:siem.mlRule/siem/rule/unmuteAlert", - "alerting:siem.mlRule/siem/rule/snooze", - "alerting:siem.mlRule/siem/rule/bulkEdit", - "alerting:siem.mlRule/siem/rule/bulkDelete", - "alerting:siem.mlRule/siem/rule/unsnooze", - "alerting:siem.mlRule/siem/rule/runSoon", - "alerting:siem.mlRule/siem/rule/enable", - "alerting:siem.mlRule/siem/rule/disable", - "alerting:siem.mlRule/siem/rule/bulkEnable", - "alerting:siem.mlRule/siem/rule/bulkDisable", - "alerting:siem.mlRule/siem/rule/deleteBackfill", - "alerting:siem.mlRule/siem/rule/fillGaps", - "alerting:siem.mlRule/siem/rule/scheduleBackfill", - "alerting:siem.queryRule/siem/rule/get", - "alerting:siem.queryRule/siem/rule/bulkGet", - "alerting:siem.queryRule/siem/rule/getRuleState", - "alerting:siem.queryRule/siem/rule/getAlertSummary", - "alerting:siem.queryRule/siem/rule/getExecutionLog", - "alerting:siem.queryRule/siem/rule/getActionErrorLog", - "alerting:siem.queryRule/siem/rule/find", - "alerting:siem.queryRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.queryRule/siem/rule/getBackfill", - "alerting:siem.queryRule/siem/rule/findBackfill", - "alerting:siem.queryRule/siem/rule/findGaps", - "alerting:siem.queryRule/siem/rule/bulkEditParams", - "alerting:siem.queryRule/siem/rule/create", - "alerting:siem.queryRule/siem/rule/delete", - "alerting:siem.queryRule/siem/rule/update", - "alerting:siem.queryRule/siem/rule/updateApiKey", - "alerting:siem.queryRule/siem/rule/muteAll", - "alerting:siem.queryRule/siem/rule/unmuteAll", - "alerting:siem.queryRule/siem/rule/muteAlert", - "alerting:siem.queryRule/siem/rule/unmuteAlert", - "alerting:siem.queryRule/siem/rule/snooze", - "alerting:siem.queryRule/siem/rule/bulkEdit", - "alerting:siem.queryRule/siem/rule/bulkDelete", - "alerting:siem.queryRule/siem/rule/unsnooze", - "alerting:siem.queryRule/siem/rule/runSoon", - "alerting:siem.queryRule/siem/rule/enable", - "alerting:siem.queryRule/siem/rule/disable", - "alerting:siem.queryRule/siem/rule/bulkEnable", - "alerting:siem.queryRule/siem/rule/bulkDisable", - "alerting:siem.queryRule/siem/rule/deleteBackfill", - "alerting:siem.queryRule/siem/rule/fillGaps", - "alerting:siem.queryRule/siem/rule/scheduleBackfill", - "alerting:siem.savedQueryRule/siem/rule/get", - "alerting:siem.savedQueryRule/siem/rule/bulkGet", - "alerting:siem.savedQueryRule/siem/rule/getRuleState", - "alerting:siem.savedQueryRule/siem/rule/getAlertSummary", - "alerting:siem.savedQueryRule/siem/rule/getExecutionLog", - "alerting:siem.savedQueryRule/siem/rule/getActionErrorLog", - "alerting:siem.savedQueryRule/siem/rule/find", - "alerting:siem.savedQueryRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.savedQueryRule/siem/rule/getBackfill", - "alerting:siem.savedQueryRule/siem/rule/findBackfill", - "alerting:siem.savedQueryRule/siem/rule/findGaps", - "alerting:siem.savedQueryRule/siem/rule/bulkEditParams", - "alerting:siem.savedQueryRule/siem/rule/create", - "alerting:siem.savedQueryRule/siem/rule/delete", - "alerting:siem.savedQueryRule/siem/rule/update", - "alerting:siem.savedQueryRule/siem/rule/updateApiKey", - "alerting:siem.savedQueryRule/siem/rule/muteAll", - "alerting:siem.savedQueryRule/siem/rule/unmuteAll", - "alerting:siem.savedQueryRule/siem/rule/muteAlert", - "alerting:siem.savedQueryRule/siem/rule/unmuteAlert", - "alerting:siem.savedQueryRule/siem/rule/snooze", - "alerting:siem.savedQueryRule/siem/rule/bulkEdit", - "alerting:siem.savedQueryRule/siem/rule/bulkDelete", - "alerting:siem.savedQueryRule/siem/rule/unsnooze", - "alerting:siem.savedQueryRule/siem/rule/runSoon", - "alerting:siem.savedQueryRule/siem/rule/enable", - "alerting:siem.savedQueryRule/siem/rule/disable", - "alerting:siem.savedQueryRule/siem/rule/bulkEnable", - "alerting:siem.savedQueryRule/siem/rule/bulkDisable", - "alerting:siem.savedQueryRule/siem/rule/deleteBackfill", - "alerting:siem.savedQueryRule/siem/rule/fillGaps", - "alerting:siem.savedQueryRule/siem/rule/scheduleBackfill", - "alerting:siem.thresholdRule/siem/rule/get", - "alerting:siem.thresholdRule/siem/rule/bulkGet", - "alerting:siem.thresholdRule/siem/rule/getRuleState", - "alerting:siem.thresholdRule/siem/rule/getAlertSummary", - "alerting:siem.thresholdRule/siem/rule/getExecutionLog", - "alerting:siem.thresholdRule/siem/rule/getActionErrorLog", - "alerting:siem.thresholdRule/siem/rule/find", - "alerting:siem.thresholdRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.thresholdRule/siem/rule/getBackfill", - "alerting:siem.thresholdRule/siem/rule/findBackfill", - "alerting:siem.thresholdRule/siem/rule/findGaps", - "alerting:siem.thresholdRule/siem/rule/bulkEditParams", - "alerting:siem.thresholdRule/siem/rule/create", - "alerting:siem.thresholdRule/siem/rule/delete", - "alerting:siem.thresholdRule/siem/rule/update", - "alerting:siem.thresholdRule/siem/rule/updateApiKey", - "alerting:siem.thresholdRule/siem/rule/muteAll", - "alerting:siem.thresholdRule/siem/rule/unmuteAll", - "alerting:siem.thresholdRule/siem/rule/muteAlert", - "alerting:siem.thresholdRule/siem/rule/unmuteAlert", - "alerting:siem.thresholdRule/siem/rule/snooze", - "alerting:siem.thresholdRule/siem/rule/bulkEdit", - "alerting:siem.thresholdRule/siem/rule/bulkDelete", - "alerting:siem.thresholdRule/siem/rule/unsnooze", - "alerting:siem.thresholdRule/siem/rule/runSoon", - "alerting:siem.thresholdRule/siem/rule/enable", - "alerting:siem.thresholdRule/siem/rule/disable", - "alerting:siem.thresholdRule/siem/rule/bulkEnable", - "alerting:siem.thresholdRule/siem/rule/bulkDisable", - "alerting:siem.thresholdRule/siem/rule/deleteBackfill", - "alerting:siem.thresholdRule/siem/rule/fillGaps", - "alerting:siem.thresholdRule/siem/rule/scheduleBackfill", - "alerting:siem.newTermsRule/siem/rule/get", - "alerting:siem.newTermsRule/siem/rule/bulkGet", - "alerting:siem.newTermsRule/siem/rule/getRuleState", - "alerting:siem.newTermsRule/siem/rule/getAlertSummary", - "alerting:siem.newTermsRule/siem/rule/getExecutionLog", - "alerting:siem.newTermsRule/siem/rule/getActionErrorLog", - "alerting:siem.newTermsRule/siem/rule/find", - "alerting:siem.newTermsRule/siem/rule/getRuleExecutionKPI", - "alerting:siem.newTermsRule/siem/rule/getBackfill", - "alerting:siem.newTermsRule/siem/rule/findBackfill", - "alerting:siem.newTermsRule/siem/rule/findGaps", - "alerting:siem.newTermsRule/siem/rule/bulkEditParams", - "alerting:siem.newTermsRule/siem/rule/create", - "alerting:siem.newTermsRule/siem/rule/delete", - "alerting:siem.newTermsRule/siem/rule/update", - "alerting:siem.newTermsRule/siem/rule/updateApiKey", - "alerting:siem.newTermsRule/siem/rule/muteAll", - "alerting:siem.newTermsRule/siem/rule/unmuteAll", - "alerting:siem.newTermsRule/siem/rule/muteAlert", - "alerting:siem.newTermsRule/siem/rule/unmuteAlert", - "alerting:siem.newTermsRule/siem/rule/snooze", - "alerting:siem.newTermsRule/siem/rule/bulkEdit", - "alerting:siem.newTermsRule/siem/rule/bulkDelete", - "alerting:siem.newTermsRule/siem/rule/unsnooze", - "alerting:siem.newTermsRule/siem/rule/runSoon", - "alerting:siem.newTermsRule/siem/rule/enable", - "alerting:siem.newTermsRule/siem/rule/disable", - "alerting:siem.newTermsRule/siem/rule/bulkEnable", - "alerting:siem.newTermsRule/siem/rule/bulkDisable", - "alerting:siem.newTermsRule/siem/rule/deleteBackfill", - "alerting:siem.newTermsRule/siem/rule/fillGaps", - "alerting:siem.newTermsRule/siem/rule/scheduleBackfill", - "alerting:siem.notifications/siem/alert/get", - "alerting:siem.notifications/siem/alert/find", - "alerting:siem.notifications/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.notifications/siem/alert/getAlertSummary", - "alerting:siem.notifications/siem/alert/update", - "alerting:siem.esqlRule/siem/alert/get", - "alerting:siem.esqlRule/siem/alert/find", - "alerting:siem.esqlRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.esqlRule/siem/alert/getAlertSummary", - "alerting:siem.esqlRule/siem/alert/update", - "alerting:siem.eqlRule/siem/alert/get", - "alerting:siem.eqlRule/siem/alert/find", - "alerting:siem.eqlRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.eqlRule/siem/alert/getAlertSummary", - "alerting:siem.eqlRule/siem/alert/update", - "alerting:siem.indicatorRule/siem/alert/get", - "alerting:siem.indicatorRule/siem/alert/find", - "alerting:siem.indicatorRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.indicatorRule/siem/alert/getAlertSummary", - "alerting:siem.indicatorRule/siem/alert/update", - "alerting:siem.mlRule/siem/alert/get", - "alerting:siem.mlRule/siem/alert/find", - "alerting:siem.mlRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.mlRule/siem/alert/getAlertSummary", - "alerting:siem.mlRule/siem/alert/update", - "alerting:siem.queryRule/siem/alert/get", - "alerting:siem.queryRule/siem/alert/find", - "alerting:siem.queryRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.queryRule/siem/alert/getAlertSummary", - "alerting:siem.queryRule/siem/alert/update", - "alerting:siem.savedQueryRule/siem/alert/get", - "alerting:siem.savedQueryRule/siem/alert/find", - "alerting:siem.savedQueryRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.savedQueryRule/siem/alert/getAlertSummary", - "alerting:siem.savedQueryRule/siem/alert/update", - "alerting:siem.thresholdRule/siem/alert/get", - "alerting:siem.thresholdRule/siem/alert/find", - "alerting:siem.thresholdRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.thresholdRule/siem/alert/getAlertSummary", - "alerting:siem.thresholdRule/siem/alert/update", - "alerting:siem.newTermsRule/siem/alert/get", - "alerting:siem.newTermsRule/siem/alert/find", - "alerting:siem.newTermsRule/siem/alert/getAuthorizedAlertsIndices", - "alerting:siem.newTermsRule/siem/alert/getAlertSummary", - "alerting:siem.newTermsRule/siem/alert/update", "api:fileUpload:analyzeFile", "api:store_search_session", "api:generateReport", From 80ce6a540e29339f6b51a9366129b2232b9d5266 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Mon, 3 Nov 2025 13:01:01 +0100 Subject: [PATCH 18/85] add missing socManagement sub feature config to siemV4 and siemV5 --- .../features/src/security/v4_features/kibana_sub_features.ts | 1 + .../features/src/security/v5_features/kibana_sub_features.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts index d5f99f905e6c2..d463b81ab6205 100644 --- a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_sub_features.ts @@ -48,6 +48,7 @@ const replacements: Partial [SecuritySubFeatureId.fileOperations]: [{ feature: SECURITY_FEATURE_ID_V5 }], [SecuritySubFeatureId.executeAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], [SecuritySubFeatureId.scanAction]: [{ feature: SECURITY_FEATURE_ID_V5 }], + [SecuritySubFeatureId.socManagement]: [{ feature: SECURITY_FEATURE_ID_V5 }], }; /** diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts index 83e5bb9c051dc..f58f7c1f0d3b4 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts @@ -25,6 +25,7 @@ import { scanActionSubFeature, workflowInsightsSubFeature, trustedDevicesSubFeature, + socManagementSubFeature, } from '../kibana_sub_features'; /** @@ -45,6 +46,7 @@ export const getSecurityV5SubFeaturesMap = ({ const securitySubFeaturesList: Array<[SecuritySubFeatureId, SubFeatureConfig]> = [ [SecuritySubFeatureId.endpointList, endpointListSubFeature()], [SecuritySubFeatureId.workflowInsights, workflowInsightsSubFeature()], + [SecuritySubFeatureId.socManagement, socManagementSubFeature()], [ SecuritySubFeatureId.globalArtifactManagement, globalArtifactManagementSubFeature(experimentalFeatures), From 17018e6bcea557ba16073d65dccc409c91688082 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Mon, 3 Nov 2025 15:01:03 +0100 Subject: [PATCH 19/85] fix ai4soc cypress test The test broke after merging main into the branch --- .../cypress/screens/custom_roles/assign_to_space_flyout.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/custom_roles/assign_to_space_flyout.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/custom_roles/assign_to_space_flyout.ts index 2a1255c4429c3..f2581ce220703 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/custom_roles/assign_to_space_flyout.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/custom_roles/assign_to_space_flyout.ts @@ -16,10 +16,10 @@ export const SECURITY_CATEGORY = '[data-test-subj="featureCategory_securitySolut export const SECURITY_FEATURE = `[data-test-subj="featureCategory_securitySolution_${SECURITY_FEATURE_ID}"]`; export const SECURITY_FEATURE_DESCRIPTION = '[data-test-subj="featurePrivilegeDescriptionText"]'; export const SECURITY_SUB_FEATURE_TABLE = - '[data-test-subj="securitySolution_siemV4_subFeaturesTable"]'; + '[data-test-subj="securitySolution_siemV5_subFeaturesTable"]'; export const SOC_MANAGEMENT_SUB_FEATURE = - '[data-test-subj="securitySolution_siemV4_soc_management"]'; + '[data-test-subj="securitySolution_siemV5_soc_management"]'; export const CASES_FEATURE = '[data-test-subj="featureCategory_securitySolution_securitySolutionCasesV3"]'; From 11b9349150abc714877f26b69c6fcc6ddc7a4ed9 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Mon, 3 Nov 2025 15:10:52 +0100 Subject: [PATCH 20/85] add missing siemV5 case to trusted devices rbac cypress test --- .../management/cypress/e2e/artifacts/trusted_devices_rbac.cy.ts | 1 + .../public/management/cypress/e2e/rbac/navigation.cy.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/trusted_devices_rbac.cy.ts b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/trusted_devices_rbac.cy.ts index 067471ec23919..dbdcf1f64b8dc 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/trusted_devices_rbac.cy.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/trusted_devices_rbac.cy.ts @@ -17,5 +17,6 @@ describe( getArtifactMockedDataTests(getArtifactsListTestDataForArtifact('trustedDevices'), [ 'siemV3', 'siemV4', + 'siemV5', ]) ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/rbac/navigation.cy.ts b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/rbac/navigation.cy.ts index b65256e9afee7..91cd69de9d6d4 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/rbac/navigation.cy.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/rbac/navigation.cy.ts @@ -40,7 +40,7 @@ describe('Navigation RBAC', () => { name: 'Trusted devices', privilegePrefix: 'trusted_devices_', selector: Selectors.TRUSTED_DEVICES, - siemVersions: ['siemV3', 'siemV4'], // Only available starting siemV3 + siemVersions: ['siemV3', 'siemV4', 'siemV5'], // Only available starting siemV3 }, { name: 'Event filters', From 63635af42f5cab8e8f7623a85320889c4472afca Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Mon, 3 Nov 2025 15:11:19 +0100 Subject: [PATCH 21/85] fix authorization tests after new ai4soc changes --- .../test_suites/platform_security/authorization.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts index 66bd8f131e5af..3992128dc8b41 100644 --- a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts +++ b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts @@ -3047,7 +3047,7 @@ export default function ({ getService }: FtrProviderContext) { "login:", "api:securitySolution-socManagement", "ui:siem/socManagement", - "ui:siemV4/socManagement", + "ui:siemV5/socManagement", ], "trusted_applications_all": Array [ "login:", @@ -5724,7 +5724,7 @@ export default function ({ getService }: FtrProviderContext) { "login:", "api:securitySolution-socManagement", "ui:siemV2/socManagement", - "ui:siemV4/socManagement", + "ui:siemV5/socManagement", ], "trusted_applications_all": Array [ "login:", @@ -8405,7 +8405,7 @@ export default function ({ getService }: FtrProviderContext) { "login:", "api:securitySolution-socManagement", "ui:siemV3/socManagement", - "ui:siemV4/socManagement", + "ui:siemV5/socManagement", ], "trusted_applications_all": Array [ "login:", @@ -11102,6 +11102,12 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV4/writeScanOperations", "ui:siemV5/writeScanOperations", ], + "soc_management_all": Array [ + "login:", + "api:securitySolution-socManagement", + "ui:siemV4/socManagement", + "ui:siemV5/socManagement", + ], "trusted_applications_all": Array [ "login:", "api:lists-all", @@ -12667,7 +12673,7 @@ export default function ({ getService }: FtrProviderContext) { "soc_management_all": Array [ "login:", "api:securitySolution-socManagement", - "ui:siemV4/socManagement", + "ui:siemV5/socManagement", ], "trusted_applications_all": Array [ "login:", From daa85798eb60501b1f1794607105c27fac80cb40 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Mon, 3 Nov 2025 15:56:01 +0100 Subject: [PATCH 22/85] fix api privileges tests after ai4soc changes --- x-pack/platform/test/api_integration/apis/security/privileges.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/platform/test/api_integration/apis/security/privileges.ts b/x-pack/platform/test/api_integration/apis/security/privileges.ts index 7a83ad1acca59..82736f8e0d427 100644 --- a/x-pack/platform/test/api_integration/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration/apis/security/privileges.ts @@ -252,6 +252,7 @@ export default function ({ getService }: FtrProviderContext) { 'endpoint_list_read', 'workflow_insights_all', 'workflow_insights_read', + 'soc_management_all', 'global_artifact_management_all', 'trusted_applications_all', 'trusted_applications_read', From dd43f8bfe57c864c71811dbb2a1de050f6f5a7e9 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 3 Nov 2025 17:12:37 -0500 Subject: [PATCH 23/85] fixes respectLicenseLevel test that broke merging upstream --- .../test/api_integration_basic/apis/security/privileges.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts index 5dd971dd6469e..ff23fc048a0b3 100644 --- a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts @@ -383,6 +383,7 @@ export default function ({ getService }: FtrProviderContext) { 'file_operations_all', 'execute_operations_all', 'scan_operations_all', + 'soc_management_all', 'trusted_devices_all', 'trusted_devices_read', 'workflow_insights_all', From 5b544bc8ad40d1289ebf6dd05e62e3226fa8eee1 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Tue, 4 Nov 2025 16:01:43 +0100 Subject: [PATCH 24/85] add cypress tests for the rules management page --- .../asset_inventory_page.cy.ts | 2 +- .../rules_table/privileges.cy.ts | 161 ++++++++++++++++++ .../cypress/screens/alerts_detection_rules.ts | 4 + .../asset_inventory/asset_inventory_page.ts | 1 - .../cypress/screens/common/page.ts | 4 + .../cypress/tasks/privileges.ts | 61 ++++++- 6 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/asset_inventory/asset_inventory_page.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/asset_inventory/asset_inventory_page.cy.ts index 56e1304ba97b8..aa3cb4ac8e264 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/asset_inventory/asset_inventory_page.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/asset_inventory/asset_inventory_page.cy.ts @@ -16,7 +16,6 @@ import { ID_FILTER_BOX, INVESTIGATE_IN_TIMELINE_BUTTON, NAME_FILTER_BOX, - NO_PRIVILEGES_BOX, TAKE_ACTION_BUTTON, TIMELINE_BODY, TYPE_FILTER_BOX, @@ -34,6 +33,7 @@ import { login } from '../../tasks/login'; import { visit } from '../../tasks/navigation'; import { ASSET_INVENTORY_URL } from '../../urls/navigation'; import { postDataView } from '../../tasks/api_calls/common'; +import { NO_PRIVILEGES_BOX } from '../../screens/common/page'; describe('Asset Inventory page - uiSetting disabled', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts new file mode 100644 index 0000000000000..ff928d67c07ed --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + CREATE_NEW_RULE_BTN, + ENABLE_RULE_TOGGLE, + SUCCESS_TOASTER_HEADER, + TOASTER_BODY, +} from '../../../../screens/alerts_detection_rules'; +import { loginWithUser } from '../../../../tasks/login'; +import { visit } from '../../../../tasks/navigation'; +import { + createUsersAndRoles, + deleteUsersAndRoles, + rulesAll, + rulesAllUser, + rulesRead, + rulesReadUser, + secAll as rulesNone, + secAllUser as rulesNoneUser, +} from '../../../../tasks/privileges'; + +import { RULES_URL } from '../../../../urls/navigation'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; +import { getCustomQueryRuleParams } from '../../../../objects/rule'; +import { + createAndEnableRule, + fillAboutRuleMinimumAndContinue, + fillDefineCustomRuleAndContinue, + fillScheduleRuleAndContinue, +} from '../../../../tasks/create_new_rule'; +import { enableRule, selectRulesByName } from '../../../../tasks/alerts_detection_rules'; +import { + BULK_ACTIONS_BTN, + BULK_EXPORT_ACTION_BTN, + BULK_MANUAL_RULE_RUN_BTN, + DELETE_RULE_BULK_BTN, + DISABLE_RULE_BULK_BTN, + DUPLICATE_RULE_BULK_BTN, + ENABLE_RULE_BULK_BTN, +} from '../../../../screens/rules_bulk_actions'; +const usersToCreate = [rulesAllUser, rulesReadUser, rulesNoneUser]; +const rolesToCreate = [rulesAll, rulesRead, rulesNone]; + +// As part of the rules RBAC effort, we have created these tests with roles that only have the new rules feature 'securitySolutionVX' enabled in order to test +// the features that said roles should have access to. Notice that the roles created are very minimal and only contain the new rules feature. + +describe('Rules table - privileges', { tags: ['@ess'] }, () => { + const ruleName = 'My rule'; + const createRule = () => { + const rule = getCustomQueryRuleParams({ name: ruleName }); + loginWithUser(rulesAllUser); + visit(RULES_URL); + cy.get(CREATE_NEW_RULE_BTN).click(); + + fillDefineCustomRuleAndContinue(rule); + fillAboutRuleMinimumAndContinue(rule); + fillScheduleRuleAndContinue(rule); + createAndEnableRule(); + }; + + const assertSuccessToaster = (heading: string, msg: string) => { + cy.get(SUCCESS_TOASTER_HEADER).should('be.visible').should('have.text', heading); + cy.get(TOASTER_BODY).should('be.visible').should('have.text', msg); + }; + + before(() => { + deleteAlertsAndRules(); + deleteUsersAndRoles(usersToCreate, rolesToCreate); + createUsersAndRoles(usersToCreate, rolesToCreate); + createRule(); + }); + + describe('securitySolutionRulesV1.all', () => { + beforeEach(() => { + loginWithUser(rulesAllUser); + visit(RULES_URL); + }); + + it(`User with role ${rulesAllUser.roles.join()} should be able to "Enable/Disable" a rule`, () => { + // Click the rule enable toggle for the only rule we have. The rule is enabled when created so we click to disable + enableRule(0); + assertSuccessToaster('Rules disabled', 'Successfully disabled 1 rule'); + + // Click again to enable + enableRule(0); + assertSuccessToaster('Rules enabled', 'Successfully enabled 1 rule'); + }); + + it(`User with role ${rulesAllUser.roles.join()} should see enabled bulk actions from context menu`, () => { + selectRulesByName([ruleName]); + cy.get(BULK_ACTIONS_BTN).click(); + + type ActionsButtonEnableArray = [string, 'enabled' | 'disabled'][]; + const bulkActionButtonsWhenEnabled: ActionsButtonEnableArray = [ + [BULK_MANUAL_RULE_RUN_BTN, 'enabled'], + [DISABLE_RULE_BULK_BTN, 'enabled'], + [ENABLE_RULE_BULK_BTN, 'disabled'], + [DELETE_RULE_BULK_BTN, 'enabled'], + [DUPLICATE_RULE_BULK_BTN, 'enabled'], + [BULK_EXPORT_ACTION_BTN, 'enabled'], + ]; + + for (const [actionButton, enableState] of bulkActionButtonsWhenEnabled) { + cy.get(actionButton).should(`be.${enableState}`); + } + + // Click to disable the rule + enableRule(0); + assertSuccessToaster('Rules disabled', 'Successfully disabled 1 rule'); + + cy.get(BULK_ACTIONS_BTN).click(); + + const bulkActionsWhenDisabled: ActionsButtonEnableArray = [ + [BULK_MANUAL_RULE_RUN_BTN, 'disabled'], + [DISABLE_RULE_BULK_BTN, 'disabled'], + [ENABLE_RULE_BULK_BTN, 'enabled'], + [DELETE_RULE_BULK_BTN, 'enabled'], + [DUPLICATE_RULE_BULK_BTN, 'enabled'], + [BULK_EXPORT_ACTION_BTN, 'enabled'], + ]; + + for (const [actionButton, disabledState] of bulkActionsWhenDisabled) { + cy.get(actionButton).should(`be.${disabledState}`); + } + }); + }); + + describe('securitySolutionRulesV1.read', () => { + beforeEach(() => { + loginWithUser(rulesReadUser); + visit(RULES_URL); + }); + + it(`User with role ${rulesReadUser.roles.join()} should not be able to trigger "Create rule" process`, () => { + cy.get(CREATE_NEW_RULE_BTN).should('not.be.enabled'); + }); + + it(`User with role ${rulesReadUser.roles.join()} should not be able to "Enable/Disable" a rule`, () => { + cy.get(ENABLE_RULE_TOGGLE).should('not.be.enabled'); + }); + }); + + describe('securitySolutionRulesV1 none', () => { + beforeEach(() => { + loginWithUser(rulesNoneUser); + visit(RULES_URL); + }); + it(`User ${ + rulesNoneUser.username + } with role(s) ${rulesNoneUser.roles.join()} should not be able to see the rules management page`, () => { + loginWithUser(rulesNoneUser); + visit(RULES_URL); + cy.get(CREATE_NEW_RULE_BTN).should('not.be.enabled'); + }); + }); +}); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts index 4eef3a0f85067..b694d52183bea 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts @@ -113,6 +113,10 @@ export const RULES_ROW = '.euiTableRow'; export const SEVERITY = '[data-test-subj="severity"]'; +export const CREATE_NEW_RULE_BTN = '[data-test-subj="create-new-rule"]'; + +export const ENABLE_RULE_TOGGLE = '[data-test-subj="ruleSwitch"]'; + export const SELECT_ALL_RULES_BTN = '[data-test-subj="selectAllRules"]'; export const RULES_EMPTY_PROMPT = '[data-test-subj="rulesEmptyPrompt"]'; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/asset_inventory/asset_inventory_page.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/asset_inventory/asset_inventory_page.ts index f6c541300aaa2..b825f2561cea1 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/asset_inventory/asset_inventory_page.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/asset_inventory/asset_inventory_page.ts @@ -7,7 +7,6 @@ import { getDataTestSubjectSelector } from '../../helpers/common'; -export const NO_PRIVILEGES_BOX = getDataTestSubjectSelector('noPrivilegesPage'); export const ALL_ASSETS_TITLE = getDataTestSubjectSelector('asset-inventory-test-subj-page-title'); export const FLYOUT_RIGHT_PANEL = getDataTestSubjectSelector('rightSection'); export const FLYOUT_CARDS = getDataTestSubjectSelector('responsive-data-card'); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/page.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/page.ts index 7cd4eb2afac91..f36bb302ba93c 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/page.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/page.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { getDataTestSubjectSelector } from '../../helpers/common'; + export const PAGE_TITLE = '[data-test-subj="header-page-title"]'; export const NOT_FOUND = '[data-test-subj="notFoundPage"]'; @@ -14,3 +16,5 @@ export const LOADING_SPINNER = '.euiLoadingSpinner'; export const PAGE_CONTENT = '[data-test-subj="pageContainer"]'; export const PAGE_CONTENT_SPINNER = `${PAGE_CONTENT} ${LOADING_SPINNER}`; + +export const NO_PRIVILEGES_BOX = getDataTestSubjectSelector('noPrivilegesPage'); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts index b0caea059577c..a307716fb6045 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts @@ -63,7 +63,6 @@ export const secAll: Role = { { feature: { siemV5: ['all'], - rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -102,7 +101,6 @@ export const secReadCasesAll: Role = { { feature: { siemV5: ['read'], - rules: ['read'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -140,7 +138,6 @@ export const secAllCasesOnlyReadDelete: Role = { { feature: { siemV5: ['all'], - rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -178,7 +175,6 @@ export const secAllCasesNoDelete: Role = { { feature: { siemV5: ['all'], - rules: ['all'], securitySolutionTimeline: ['all'], securitySolutionNotes: ['all'], securitySolutionAssistant: ['all'], @@ -201,6 +197,63 @@ export const secAllCasesNoDeleteUser: User = { roles: [secAllCasesNoDelete.name], }; +export const rulesAll: Role = { + name: 'rules_all_role', + privileges: { + elasticsearch: { + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + securitySolutionRulesV1: ['all'], + actions: ['all'], + }, + spaces: ['*'], + }, + ], + }, +}; + +export const rulesRead: Role = { + name: 'rules_read_role', + privileges: { + elasticsearch: { + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + securitySolutionRulesV1: ['read'], + }, + spaces: ['*'], + }, + ], + }, +}; + +export const rulesAllUser: User = { + username: 'rules_all_user', + password: 'password', + roles: [rulesAll.name], +}; + +export const rulesReadUser: User = { + username: 'rules_read_user', + password: 'password', + roles: [rulesRead.name], +}; + const getUserInfo = (user: User): UserInfo => ({ username: user.username, full_name: user.username.replace('_', ' '), From 698722a6fd064e3689fd3bf34476ee2c4504393e Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 4 Nov 2025 21:55:19 -0500 Subject: [PATCH 25/85] removes unused code and resolves PR TODOs --- .../packages/data-table/components/data_table/index.tsx | 4 ++-- .../security/packages/data-table/store/data_table/model.ts | 2 +- .../packages/features/src/security/kibana_sub_features.ts | 2 -- .../features/src/security/v5_features/kibana_features.ts | 1 - .../features/src/security/v5_features/kibana_sub_features.ts | 3 --- .../public/common/components/events_viewer/index.tsx | 2 +- 6 files changed, 4 insertions(+), 10 deletions(-) diff --git a/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx b/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx index 2f106d01fcb19..9c3836d64b8de 100644 --- a/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx +++ b/x-pack/solutions/security/packages/data-table/components/data_table/index.tsx @@ -271,10 +271,10 @@ export const DataTableComponent = React.memo( direction: 'asc' | 'desc'; }> = useMemo( () => - sort?.map((x) => ({ + sort.map((x) => ({ id: x.columnId, direction: mapSortDirectionToDirection(x.sortDirection), - })) ?? [], + })), [sort] ); diff --git a/x-pack/solutions/security/packages/data-table/store/data_table/model.ts b/x-pack/solutions/security/packages/data-table/store/data_table/model.ts index c70cf88d7448e..bcddfe864d4f1 100644 --- a/x-pack/solutions/security/packages/data-table/store/data_table/model.ts +++ b/x-pack/solutions/security/packages/data-table/store/data_table/model.ts @@ -21,7 +21,7 @@ export interface DataTableModelSettings { /** When true, shows checkboxes enabling selection. Selected events store in selectedEventIds **/ showCheckboxes: boolean; /** Specifies which column the data table is sorted on, and the direction (ascending / descending) */ - sort: SortColumnTable[]; // TODO this was made optional in the initial commit; why? + sort: SortColumnTable[]; title: string; unit?: (n: number) => string | React.ReactNode; } diff --git a/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts index 3a3d77fd29095..c4475d4800d69 100644 --- a/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/kibana_sub_features.ts @@ -680,8 +680,6 @@ export const globalArtifactManagementSubFeature = ( }; export const socManagementSubFeature = (): SubFeatureConfig => ({ - requireAllSpaces: false, - privilegesTooltip: undefined, name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.subFeatures.socManagement', { defaultMessage: 'SOC Management' } diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts index 090e3a1c7ed5a..2c0e3577839d9 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts @@ -35,7 +35,6 @@ export const getSecurityV5BaseKibanaFeature = ({ ), order: 1100, category: DEFAULT_APP_CATEGORIES.security, - // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], catalogue: [APP_ID], description: i18n.translate( diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts index f58f7c1f0d3b4..1117b4db745e7 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_sub_features.ts @@ -71,9 +71,6 @@ export const getSecurityV5SubFeaturesMap = ({ ); // Remove disabled experimental features - if (!experimentalFeatures.defendInsightsPolicyResponseFailure) { - securitySubFeaturesMap.delete(SecuritySubFeatureId.workflowInsights); - } if (!experimentalFeatures.trustedDevices) { securitySubFeaturesMap.delete(SecuritySubFeatureId.trustedDevices); } diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx index 416ecd502580b..f1d819bdc1df7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -128,7 +128,7 @@ const StatefulEventsViewerComponent: React.FC Date: Wed, 5 Nov 2025 11:15:25 +0100 Subject: [PATCH 26/85] update SECURITY_FEATURE_ID constant to siemV5 --- .../plugins/cloud_security_posture/public/test/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/cloud_security_posture/public/test/constants.ts b/x-pack/solutions/security/plugins/cloud_security_posture/public/test/constants.ts index 9178df8e5b867..3ec601ce0b177 100644 --- a/x-pack/solutions/security/plugins/cloud_security_posture/public/test/constants.ts +++ b/x-pack/solutions/security/plugins/cloud_security_posture/public/test/constants.ts @@ -5,4 +5,4 @@ * 2.0. */ -export const SECURITY_FEATURE_ID = 'siemV4'; +export const SECURITY_FEATURE_ID = 'siemV5'; From b6b35b7e536db0e7a22cfee6a37631ba2b8fb933 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Wed, 5 Nov 2025 13:19:43 +0100 Subject: [PATCH 27/85] fix rules management page privileges cypress test failure --- .../rule_management/rules_table/privileges.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts index ff928d67c07ed..329d88fa8b961 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts @@ -43,6 +43,7 @@ import { DUPLICATE_RULE_BULK_BTN, ENABLE_RULE_BULK_BTN, } from '../../../../screens/rules_bulk_actions'; +import { NO_PRIVILEGES_BOX } from '../../../../screens/common/page'; const usersToCreate = [rulesAllUser, rulesReadUser, rulesNoneUser]; const rolesToCreate = [rulesAll, rulesRead, rulesNone]; @@ -155,7 +156,7 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { } with role(s) ${rulesNoneUser.roles.join()} should not be able to see the rules management page`, () => { loginWithUser(rulesNoneUser); visit(RULES_URL); - cy.get(CREATE_NEW_RULE_BTN).should('not.be.enabled'); + cy.get(NO_PRIVILEGES_BOX).should('exist'); }); }); }); From 150472a7809697f2354fecaf672e09767401b263 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 5 Nov 2025 20:21:17 -0500 Subject: [PATCH 28/85] removes remaining TODOs and unskips tests --- .../public/common/hooks/use_missing_privileges.test.tsx | 5 ++--- .../public/common/hooks/use_missing_privileges.ts | 7 +++---- .../timeline_actions/use_add_bulk_to_timeline.tsx | 2 +- .../public/exceptions/hooks/use_list_detail_view/index.ts | 4 +--- .../lib/product_features_service/security_saved_objects.ts | 4 ++-- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx index 3c1e91fbda9eb..789564eea1646 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx @@ -143,12 +143,11 @@ describe('useMissingPrivileges', () => { }); }); - // TODO this behavior now seems inadequate. What should be reported if user does not have rules:read? Do we ever report `siemv5` feature as missing? - it.skip('reports missing "all" privilege for security if user does not have CRUD', () => { + it('reports missing "all" privilege for security if user does not have CRUD', () => { const hookResult = renderHook(() => useMissingPrivileges()); expect(hookResult.result.current.featurePrivileges).toEqual( - expect.arrayContaining([RULES_FEATURE_ID, ['all']]) + expect.arrayContaining([[RULES_FEATURE_ID, ['all']]]) ); }); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts index 5b2f9f6617996..1e94846a1e557 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts @@ -48,8 +48,7 @@ export interface MissingPrivileges { * Hook that returns index and feature privileges that are missing for the user. */ export const useMissingPrivileges = (): MissingPrivileges => { - const { detectionEnginePrivileges, listPrivileges } = useUserPrivileges(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const { detectionEnginePrivileges, listPrivileges, rulesPrivileges } = useUserPrivileges(); return useMemo(() => { const featurePrivileges: MissingFeaturePrivileges[] = []; @@ -66,7 +65,7 @@ export const useMissingPrivileges = (): MissingPrivileges => { }; } - if (canEditRules === false) { + if (rulesPrivileges.edit === false) { featurePrivileges.push([RULES_FEATURE_ID, ['all']]); } @@ -91,5 +90,5 @@ export const useMissingPrivileges = (): MissingPrivileges => { featurePrivileges, indexPrivileges, }; - }, [listPrivileges.result, detectionEnginePrivileges.result, canEditRules]); + }, [listPrivileges.result, detectionEnginePrivileges.result, rulesPrivileges.edit]); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx index ddbcdc71826b7..187e53bb7e1b2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_bulk_to_timeline.tsx @@ -119,7 +119,7 @@ export const useAddBulkToTimelineAction = ({ const esQueryConfig = useMemo(() => getEsQueryConfig(uiSettings), [uiSettings]); const timelineQuerySortField = useMemo(() => { - return sort?.map(({ columnId, columnType, esTypes, sortDirection }) => ({ + return sort.map(({ columnId, columnType, esTypes, sortDirection }) => ({ field: columnId, direction: sortDirection as Direction, esTypes: esTypes ?? [], diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts index 0641e85c5ce0e..adca7eeb4f237 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts @@ -16,7 +16,6 @@ import { useApi } from '@kbn/securitysolution-list-hooks'; import { isEqual } from 'lodash'; import { ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../../../common/endpoint/service/artifacts/constants'; -import { useUserData } from '../../../detections/components/user_info'; import { APP_UI_ID, SecurityPageName } from '../../../../common/constants'; import { useKibana, useToasts } from '../../../common/lib/kibana'; import { @@ -57,7 +56,6 @@ export const useListDetailsView = (exceptionListId: string) => { const { exportExceptionList, deleteExceptionList, duplicateExceptionList } = useApi(http); const { read: canReadRules, edit: canEditRules } = useUserPrivileges().rulesPrivileges; - const [{ loading: userInfoLoading }] = useUserData(); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); const canUserWriteCurrentList = exceptionListId === ENDPOINT_ARTIFACT_LISTS.endpointExceptions.id @@ -411,7 +409,7 @@ export const useListDetailsView = (exceptionListId: string) => { // #endregion return { - isLoading: isLoading || userInfoLoading, + isLoading, invalidListId, isReadOnly: !!(!canUserWriteCurrentList && canReadRules), list, diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts index c4adb4181d41b..6eb35aa12df52 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts @@ -45,10 +45,10 @@ export const securityV2SavedObjects = [ export const securityV3SavedObjects = [...securityV2SavedObjects]; -export const securityV4SavedObjects = [...securityV3SavedObjects]; // TODO: is this right? +export const securityV4SavedObjects = [...securityV3SavedObjects]; export const securityV5SavedObjects = [ - // The difference between v4 and v5 is that v4 removes the exceptions list SO + // The difference between v4 and v5 is that v5 removes the exceptions list SO // type and prebuilt rules which are now managed by the rules product feature DATA_VIEW_SAVED_OBJECT_TYPE, CLOUD_POSTURE_SAVED_OBJECT_RULE_TYPE, From 29f215aa2bfc7a317b958757bf2ed138cd40fd2c Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Thu, 6 Nov 2025 16:04:13 +0100 Subject: [PATCH 29/85] add cypress tests for the alerts page --- .../detection_alerts/privileges.cy.ts | 145 ++++++++++++++++++ .../rules_table/privileges.cy.ts | 28 ++-- .../cypress/screens/common/data_grid.ts | 3 + .../cypress/screens/common/toast.ts | 9 ++ .../cypress/tasks/alerts.ts | 13 ++ .../cypress/tasks/privileges.ts | 36 +++++ .../cypress/tasks/table_pagination.ts | 13 ++ 7 files changed, 228 insertions(+), 19 deletions(-) create mode 100644 x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/privileges.cy.ts diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/privileges.cy.ts new file mode 100644 index 0000000000000..050bbec19d2b2 --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/detection_alerts/privileges.cy.ts @@ -0,0 +1,145 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getCustomQueryRuleParams } from '../../../../objects/rule'; +import { ADD_EXCEPTION_BTN, ATTACH_TO_NEW_CASE_BUTTON } from '../../../../screens/alerts'; +import { + addAlertTagToNAlerts, + closeAlerts, + expandFirstAlertActions, + selectNumberOfAlerts, +} from '../../../../tasks/alerts'; +import { createRule } from '../../../../tasks/api_calls/rules'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; +import { loginWithUser } from '../../../../tasks/login'; +import { visit } from '../../../../tasks/navigation'; +import { ALERTS_URL } from '../../../../urls/navigation'; +import { + createUsersAndRoles, + deleteUsersAndRoles, + rulesAllUser, + rulesAllWithCasesUser, + rulesReadUser, + secAll as rulesNone, + secAllUser as rulesNoneUser, + rulesAll, + rulesRead, + rulesAllWithCases, +} from '../../../../tasks/privileges'; +import { assertSuccessToast } from '../../../../screens/common/toast'; +import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule'; +import { + removeAllAssigneesForFirstAlert, + updateAssigneesForFirstAlert, +} from '../../../../tasks/alert_assignments'; +import { sortUsingDataGridBtn } from '../../../../tasks/table_pagination'; +import { NO_PRIVILEGES_BOX } from '../../../../screens/common/page'; +import { openKibanaNavigation } from '../../../../tasks/kibana_navigation'; +import { ALERTS_PAGE } from '../../../../screens/kibana_navigation'; + +const usersToCreate = [rulesAllUser, rulesAllWithCasesUser, rulesReadUser, rulesNoneUser]; +const rolesToCreate = [rulesAll, rulesAllWithCases, rulesRead, rulesNone]; + +describe('Alerts page - privileges', { tags: ['@ess'] }, () => { + before(() => { + cy.task('esArchiverLoad', { archiveName: 'auditbeat_multiple' }); + deleteAlertsAndRules(); + deleteUsersAndRoles(usersToCreate, rolesToCreate); + createUsersAndRoles(usersToCreate, rolesToCreate); + // This triggers the creation of list indexes which is necessary to visualize the alerts page + loginWithUser(rulesAllUser); + visit(ALERTS_URL); + }); + + after(() => { + cy.task('esArchiverUnload', { archiveName: 'auditbeat_multiple' }); + }); + + beforeEach(() => { + loginWithUser(rulesAllUser); + deleteAlertsAndRules(); + createRule(getCustomQueryRuleParams()); + }); + + describe('securitySolutionRulesV1.all', () => { + beforeEach(() => { + loginWithUser(rulesAllUser); + visit(ALERTS_URL); + waitForAlertsToPopulate(); + }); + + it(`should be able close alerts`, () => { + selectNumberOfAlerts(3); + + closeAlerts(); + assertSuccessToast('Successfully closed 3 alerts.', ''); + }); + + it(`should be able to add an exception`, () => { + expandFirstAlertActions(); + + cy.get(ADD_EXCEPTION_BTN).click(); + cy.get('[data-test-subj="exceptionFlyoutTitle"]').should('be.visible'); + }); + }); + + describe('securitySolutionRulesV1.all with cases', () => { + beforeEach(() => { + loginWithUser(rulesAllWithCasesUser); + visit(ALERTS_URL); + waitForAlertsToPopulate(); + }); + + it(`should be able to add to case`, () => { + expandFirstAlertActions(); + + cy.get(ATTACH_TO_NEW_CASE_BUTTON).click(); + + cy.get('[data-test-subj="create-case-submit"]').should('be.enabled'); + }); + }); + + describe('securitySolutionRulesV1.read', () => { + beforeEach(() => { + loginWithUser(rulesReadUser); + visit(ALERTS_URL); + waitForAlertsToPopulate(); + sortUsingDataGridBtn('Assignees'); + }); + + it('should be able to assign/unassign alerts', () => { + const assignees = [rulesReadUser.username]; + updateAssigneesForFirstAlert(assignees); + removeAllAssigneesForFirstAlert(); + }); + + it('should be able to apply alert tags', () => { + addAlertTagToNAlerts(5); + }); + + it(`should not be able to add an exception`, () => { + expandFirstAlertActions(); + cy.get(ADD_EXCEPTION_BTN).should('not.exist'); + }); + }); + + describe('securitySolutionRulesV1 none', () => { + beforeEach(() => { + loginWithUser(rulesNoneUser); + visit(ALERTS_URL); + }); + + it('should not be able to see the alerts page', () => { + cy.get(NO_PRIVILEGES_BOX).should('exist'); + }); + + it('should not see the "alerts" link in the sidebar', () => { + openKibanaNavigation(); + cy.get(ALERTS_PAGE).should('not.exist'); + }); + }); +}); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts index 329d88fa8b961..ba1ef9ace803f 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts @@ -8,8 +8,6 @@ import { CREATE_NEW_RULE_BTN, ENABLE_RULE_TOGGLE, - SUCCESS_TOASTER_HEADER, - TOASTER_BODY, } from '../../../../screens/alerts_detection_rules'; import { loginWithUser } from '../../../../tasks/login'; import { visit } from '../../../../tasks/navigation'; @@ -44,6 +42,7 @@ import { ENABLE_RULE_BULK_BTN, } from '../../../../screens/rules_bulk_actions'; import { NO_PRIVILEGES_BOX } from '../../../../screens/common/page'; +import { assertSuccessToast } from '../../../../screens/common/toast'; const usersToCreate = [rulesAllUser, rulesReadUser, rulesNoneUser]; const rolesToCreate = [rulesAll, rulesRead, rulesNone]; @@ -64,11 +63,6 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { createAndEnableRule(); }; - const assertSuccessToaster = (heading: string, msg: string) => { - cy.get(SUCCESS_TOASTER_HEADER).should('be.visible').should('have.text', heading); - cy.get(TOASTER_BODY).should('be.visible').should('have.text', msg); - }; - before(() => { deleteAlertsAndRules(); deleteUsersAndRoles(usersToCreate, rolesToCreate); @@ -82,17 +76,17 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { visit(RULES_URL); }); - it(`User with role ${rulesAllUser.roles.join()} should be able to "Enable/Disable" a rule`, () => { + it(`should be able to "Enable/Disable" a rule`, () => { // Click the rule enable toggle for the only rule we have. The rule is enabled when created so we click to disable enableRule(0); - assertSuccessToaster('Rules disabled', 'Successfully disabled 1 rule'); + assertSuccessToast('Rules disabled', 'Successfully disabled 1 rule'); // Click again to enable enableRule(0); - assertSuccessToaster('Rules enabled', 'Successfully enabled 1 rule'); + assertSuccessToast('Rules enabled', 'Successfully enabled 1 rule'); }); - it(`User with role ${rulesAllUser.roles.join()} should see enabled bulk actions from context menu`, () => { + it(`should see enabled bulk actions from context menu`, () => { selectRulesByName([ruleName]); cy.get(BULK_ACTIONS_BTN).click(); @@ -112,7 +106,7 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { // Click to disable the rule enableRule(0); - assertSuccessToaster('Rules disabled', 'Successfully disabled 1 rule'); + assertSuccessToast('Rules disabled', 'Successfully disabled 1 rule'); cy.get(BULK_ACTIONS_BTN).click(); @@ -137,11 +131,11 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { visit(RULES_URL); }); - it(`User with role ${rulesReadUser.roles.join()} should not be able to trigger "Create rule" process`, () => { + it(`should not be able to trigger "Create rule" process`, () => { cy.get(CREATE_NEW_RULE_BTN).should('not.be.enabled'); }); - it(`User with role ${rulesReadUser.roles.join()} should not be able to "Enable/Disable" a rule`, () => { + it(`should not be able to "Enable/Disable" a rule`, () => { cy.get(ENABLE_RULE_TOGGLE).should('not.be.enabled'); }); }); @@ -151,11 +145,7 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { loginWithUser(rulesNoneUser); visit(RULES_URL); }); - it(`User ${ - rulesNoneUser.username - } with role(s) ${rulesNoneUser.roles.join()} should not be able to see the rules management page`, () => { - loginWithUser(rulesNoneUser); - visit(RULES_URL); + it('should not be able to see the rules management page', () => { cy.get(NO_PRIVILEGES_BOX).should('exist'); }); }); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/data_grid.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/data_grid.ts index 6861fdf24fdf3..94b1da13d5145 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/data_grid.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/data_grid.ts @@ -43,3 +43,6 @@ export const DATA_GRID_FULL_SCREEN = export const DATA_GRID_FIELD_SORT_BTN = '[data-test-subj="dataGridColumnSortingButton"]'; export const DATA_GRID_COLUMN_ORDER_BTN = '[data-test-subj="dataGridColumnSelectorButton"]'; + +export const DATA_GRID_COLUMN_SORTER_SELECTION_BTN = + '[data-test-subj="dataGridColumnSortingSelectionButton"]'; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/toast.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/toast.ts index 3f52d30a05a1a..dfed6a5bb90fa 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/toast.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/screens/common/toast.ts @@ -5,4 +5,13 @@ * 2.0. */ +import { SUCCESS_TOASTER_HEADER, TOASTER_BODY } from '../alerts_detection_rules'; + export const TOAST_CLOSE_BUTTON = '[data-test-subj="toastCloseButton"]'; + +export const assertSuccessToast = (heading: string, msg?: string) => { + cy.get(SUCCESS_TOASTER_HEADER).should('be.visible').should('have.text', heading); + if (msg) { + cy.get(TOASTER_BODY).should('be.visible').should('have.text', msg); + } +}; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts index c7c14bbe61f62..8424807636ac3 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts @@ -26,6 +26,7 @@ import { ALERT_TAGGING_CONTEXT_MENU_ITEM, ALERT_TAGGING_UPDATE_BUTTON, ALERTS_HISTOGRAM_LEGEND, + ALERTS_TABLE_ROW_LOADER, CELL_ADD_TO_TIMELINE_BUTTON, CELL_FILTER_IN_BUTTON, CELL_FILTER_OUT_BUTTON, @@ -49,6 +50,7 @@ import { SELECT_COUNTS_TABLE, SELECT_HISTOGRAM, SELECT_TREEMAP, + SELECTED_ALERT_TAG, SELECTED_ALERTS, SEND_ALERT_TO_TIMELINE_BTN, SESSION_VIEWER_BUTTON, @@ -560,6 +562,17 @@ export const updateAlertTags = () => { cy.get(ALERT_TAGGING_UPDATE_BUTTON).click(); }; +export const addAlertTagToNAlerts = (alertCount: number, tag = 'Duplicate') => { + selectNumberOfAlerts(alertCount); + openAlertTaggingBulkActionMenu(); + clickAlertTag(tag); + updateAlertTags(); + cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); + selectNumberOfAlerts(alertCount); + openAlertTaggingBulkActionMenu(); + cy.get(SELECTED_ALERT_TAG).contains(tag); +} + export const showHoverActionsEventRenderedView = (fieldSelector: string) => { cy.get(fieldSelector).first().realHover(); cy.get(HOVER_ACTIONS_CONTAINER).should('be.visible'); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts index a307716fb6045..e12a49eab2f03 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts @@ -213,6 +213,34 @@ export const rulesAll: Role = { feature: { securitySolutionRulesV1: ['all'], actions: ['all'], + indexPatterns: ['all'], + savedObjectManagement: ['all'], + }, + spaces: ['*'], + }, + ], + }, +}; + +export const rulesAllWithCases: Role = { + name: 'rules_all_role', + privileges: { + elasticsearch: { + indices: [ + { + names: ['*'], + privileges: ['all'], + }, + ], + }, + kibana: [ + { + feature: { + securitySolutionRulesV1: ['all'], + actions: ['all'], + indexPatterns: ['all'], + savedObjectManagement: ['all'], + securitySolutionCasesV3: ['all'], }, spaces: ['*'], }, @@ -235,6 +263,8 @@ export const rulesRead: Role = { { feature: { securitySolutionRulesV1: ['read'], + savedObjectManagement: ['all'], + indexPatterns: ['all'], }, spaces: ['*'], }, @@ -248,6 +278,12 @@ export const rulesAllUser: User = { roles: [rulesAll.name], }; +export const rulesAllWithCasesUser: User = { + username: 'rules_all_with_cases_user', + password: 'password', + roles: [rulesAllWithCases.name], +}; + export const rulesReadUser: User = { username: 'rules_read_user', password: 'password', diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/table_pagination.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/table_pagination.ts index 1318a5258684e..70b4bf3fb3522 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/table_pagination.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/table_pagination.ts @@ -5,6 +5,10 @@ * 2.0. */ +import { + DATA_GRID_COLUMN_SORTER_SELECTION_BTN, + DATA_GRID_FIELD_SORT_BTN, +} from '../screens/common/data_grid'; import { LOADING_SPINNER } from '../screens/loading'; import { rowsPerPageSelector, @@ -60,3 +64,12 @@ export const expectTableSorting = (columnName: string, direction: 'asc' | 'desc' .parents('.euiTableHeaderCell') .should('have.attr', 'aria-sort', direction === 'asc' ? 'ascending' : 'descending'); }; + +export const sortUsingDataGridBtn = (columnName: string) => { + cy.get(DATA_GRID_FIELD_SORT_BTN).click(); + cy.get(DATA_GRID_COLUMN_SORTER_SELECTION_BTN).click(); + cy.get('[data-test-subj^="dataGridColumnSortingPopoverColumnSelection"]') + .contains(columnName) + .first() + .click(); +}; From 632bbc0e8c2597ae9f676123d6ecd09b644bbf73 Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Fri, 7 Nov 2025 15:39:38 +0100 Subject: [PATCH 30/85] add cypress tests for the rule details page --- .../rule_details/execution_log.cy.ts | 24 +-- .../rule_details/privileges.cy.ts | 179 ++++++++++++++++++ .../cypress/tasks/alerts.ts | 18 +- .../cypress/tasks/rule_details.ts | 13 ++ 4 files changed, 204 insertions(+), 30 deletions(-) create mode 100644 x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/privileges.cy.ts diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/execution_log.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/execution_log.cy.ts index 572237426a75b..7a6113ec5e42c 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/execution_log.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/execution_log.cy.ts @@ -15,8 +15,8 @@ import { createRule } from '../../../../tasks/api_calls/rules'; import { goToExecutionLogTab, getExecutionLogTableRow, - refreshRuleExecutionTable, filterByRunType, + waitForExecutionLogTabToBePopulated, } from '../../../../tasks/rule_details'; import { getCustomQueryRuleParams } from '../../../../objects/rule'; import { EXECUTION_SHOWING } from '../../../../screens/rule_details'; @@ -48,16 +48,7 @@ describe( visit(ruleDetailsUrl(this.ruleId)); goToExecutionLogTab(); - cy.waitUntil( - () => { - cy.log('Waiting for execution logs to appear in execution log table'); - refreshRuleExecutionTable(); - return getExecutionLogTableRow().then((rows) => { - return rows.length > 0; - }); - }, - { interval: 5000, timeout: 20000 } - ); + waitForExecutionLogTabToBePopulated(1); cy.get(EXECUTION_SHOWING).contains('Showing 1 rule execution'); getExecutionLogTableRow().should('have.length', 1); @@ -69,16 +60,7 @@ describe( end: moment().toISOString(), }); - cy.waitUntil( - () => { - cy.log('Waiting for execution logs to appear in execution log table'); - refreshRuleExecutionTable(); - return getExecutionLogTableRow().then((rows) => { - return rows.length > 1; - }); - }, - { interval: 5000, timeout: 20000 } - ); + waitForExecutionLogTabToBePopulated(2); cy.get(EXECUTION_SHOWING).contains('Showing 2 rule executions'); getExecutionLogTableRow().should('have.length', 2); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/privileges.cy.ts new file mode 100644 index 0000000000000..3b2bd47dbdaca --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_details/privileges.cy.ts @@ -0,0 +1,179 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ADD_EXCEPTIONS_BTN_FROM_EMPTY_PROMPT_BTN } from '../../../../screens/exceptions'; +import { + CREATE_NEW_RULE_BTN, + MODAL_CONFIRMATION_BTN, + RULE_DETAILS_MANUAL_RULE_RUN_BTN, +} from '../../../../screens/alerts_detection_rules'; +import { loginWithUser } from '../../../../tasks/login'; +import { visit } from '../../../../tasks/navigation'; +import { + createUsersAndRoles, + deleteUsersAndRoles, + rulesAll, + rulesAllUser, + rulesRead, + rulesReadUser, + secAll as rulesNone, + secAllUser as rulesNoneUser, +} from '../../../../tasks/privileges'; + +import { RULES_URL } from '../../../../urls/navigation'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; +import { getCustomQueryRuleParams } from '../../../../objects/rule'; +import { + createAndEnableRule, + fillAboutRuleMinimumAndContinue, + fillDefineCustomRuleAndContinue, + fillScheduleRuleAndContinue, +} from '../../../../tasks/create_new_rule'; +import { + goToRuleDetailsOf, + manualRuleRunFromDetailsPage, +} from '../../../../tasks/alerts_detection_rules'; +import { + addFirstExceptionFromRuleDetails, + goToExceptionsTab, + goToExecutionLogTab, + goToRuleEditSettings, + waitForExecutionLogTabToBePopulated, +} from '../../../../tasks/rule_details'; +import { EDIT_SUBMIT_BUTTON } from '../../../../screens/edit_rule'; +import { + EDIT_RULE_SETTINGS_LINK, + POPOVER_ACTIONS_TRIGGER_BUTTON, + RULE_FILL_ALL_GAPS_BUTTON, +} from '../../../../screens/rule_details'; +import { + expectRuleSnoozed, + expectUnsnoozeSuccessToast, + snoozeRule, + unsnoozeRule, +} from '../../../../tasks/rule_snoozing'; +import { UNSNOOZED_BADGE } from '../../../../screens/rule_snoozing'; +const usersToCreate = [rulesAllUser, rulesReadUser, rulesNoneUser]; +const rolesToCreate = [rulesAll, rulesRead, rulesNone]; + +// As part of the rules RBAC effort, we have created these tests with roles that only have the new rules feature 'securitySolutionVX' enabled in order to test +// the features that said roles should have access to. Notice that the roles created are very minimal and only contain the new rules feature. + +describe('Rules table - privileges', { tags: ['@ess'] }, () => { + const ruleName = 'My rule'; + const createRule = () => { + const rule = getCustomQueryRuleParams({ name: ruleName }); + loginWithUser(rulesAllUser); + visit(RULES_URL); + cy.get(CREATE_NEW_RULE_BTN).click(); + + fillDefineCustomRuleAndContinue(rule); + fillAboutRuleMinimumAndContinue(rule); + fillScheduleRuleAndContinue(rule); + createAndEnableRule(); + }; + + before(() => { + deleteAlertsAndRules(); + deleteUsersAndRoles(usersToCreate, rolesToCreate); + createUsersAndRoles(usersToCreate, rolesToCreate); + createRule(); + }); + + describe('securitySolutionRulesV1.all', () => { + beforeEach(() => { + loginWithUser(rulesAllUser); + visit(RULES_URL); + goToRuleDetailsOf(ruleName); + }); + + it(`should be able to edit rules`, () => { + goToRuleEditSettings(); + cy.get(EDIT_SUBMIT_BUTTON).should('be.enabled'); + }); + + describe('execution log tab', () => { + beforeEach(() => { + goToExecutionLogTab(); + }); + + it(`should be able to see the execution history`, () => { + waitForExecutionLogTabToBePopulated(1); + }); + + it('should be able to trigger gap fills', () => { + cy.get(RULE_FILL_ALL_GAPS_BUTTON).click(); + cy.get(MODAL_CONFIRMATION_BTN).should('be.enabled'); + }); + }); + + it('should be able to trigger manual runs', () => { + manualRuleRunFromDetailsPage(); + }); + + it('should be able to trigger adding exceptions', () => { + goToExceptionsTab(); + + addFirstExceptionFromRuleDetails( + { + field: 'host.name', + operator: 'is one of', + values: ['foo', 'FOO', 'bar'], + }, + 'Some exception name' + ); + }); + + it('should be able to adjust snooze settings', () => { + snoozeRule('3 days'); + expectRuleSnoozed('3 days'); + unsnoozeRule(); + expectUnsnoozeSuccessToast(); + }); + }); + + describe('securitySolutionRulesV1.read', () => { + beforeEach(() => { + loginWithUser(rulesReadUser); + visit(RULES_URL); + goToRuleDetailsOf(ruleName); + }); + + it(`should not be able to edit rules`, () => { + cy.get(EDIT_RULE_SETTINGS_LINK).should('be.disabled'); + }); + + describe('execution log tab', () => { + beforeEach(() => { + goToExecutionLogTab(); + }); + + it(`should be able to see the execution history`, () => { + waitForExecutionLogTabToBePopulated(1); + }); + + it('should not be able to trigger gap fills', () => { + cy.get(RULE_FILL_ALL_GAPS_BUTTON).should('not.exist'); + }); + }); + + it('should not be able to trigger manual runs', () => { + cy.get(POPOVER_ACTIONS_TRIGGER_BUTTON).click(); + cy.get(RULE_DETAILS_MANUAL_RULE_RUN_BTN).should('be.disabled'); + }); + + it('should not be able to trigger adding exceptions', () => { + goToExceptionsTab(); + + cy.get(ADD_EXCEPTIONS_BTN_FROM_EMPTY_PROMPT_BTN).should('not.exist'); + }); + + it('should not be able to adjust snooze settings', () => { + cy.get(UNSNOOZED_BADGE).should('be.disabled'); + }); + }); +}); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts index 8424807636ac3..1aa0d363d4c21 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/alerts.ts @@ -563,15 +563,15 @@ export const updateAlertTags = () => { }; export const addAlertTagToNAlerts = (alertCount: number, tag = 'Duplicate') => { - selectNumberOfAlerts(alertCount); - openAlertTaggingBulkActionMenu(); - clickAlertTag(tag); - updateAlertTags(); - cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - selectNumberOfAlerts(alertCount); - openAlertTaggingBulkActionMenu(); - cy.get(SELECTED_ALERT_TAG).contains(tag); -} + selectNumberOfAlerts(alertCount); + openAlertTaggingBulkActionMenu(); + clickAlertTag(tag); + updateAlertTags(); + cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); + selectNumberOfAlerts(alertCount); + openAlertTaggingBulkActionMenu(); + cy.get(SELECTED_ALERT_TAG).contains(tag); +}; export const showHoverActionsEventRenderedView = (fieldSelector: string) => { cy.get(fieldSelector).first().realHover(); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/rule_details.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/rule_details.ts index a79d248670fc4..a9e2befe71c46 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/rule_details.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/rule_details.ts @@ -135,6 +135,19 @@ export const goToExecutionLogTab = () => { cy.get(EXECUTIONS_TAB).click(); }; +export const waitForExecutionLogTabToBePopulated = (minRowCount = 1) => { + cy.waitUntil( + () => { + cy.log('Waiting for execution logs to appear in execution log table'); + refreshRuleExecutionTable(); + return getExecutionLogTableRow().then((rows) => { + return rows.length > minRowCount - 1; + }); + }, + { interval: 5000, timeout: 20000 } + ); +}; + export const viewExpiredExceptionItems = () => { cy.get(EXCEPTIONS_TAB_EXPIRED_FILTER).click(); cy.get(EXCEPTIONS_TAB_ACTIVE_FILTER).click(); From ebd653e82e70f497907200825161589512527049 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 12 Nov 2025 15:30:42 -0500 Subject: [PATCH 31/85] switches detection engine health setup endpiont to have initalize-sec-sol permission --- .../api/detection_engine_health/setup/setup_health_route.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts index 6e9febcf0659c..764a85b3d4803 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_monitoring/api/detection_engine_health/setup/setup_health_route.ts @@ -7,7 +7,7 @@ import type { IKibanaResponse } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; -import { RULES_API_READ } from '@kbn/security-solution-features/constants'; +import { INITIALIZE_SECURITY_SOLUTION } from '@kbn/security-solution-features/constants'; import { SETUP_HEALTH_URL } from '../../../../../../../common/api/detection_engine/rule_monitoring'; import type { SetupHealthResponse } from '../../../../../../../common/api/detection_engine'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; @@ -25,7 +25,7 @@ export const setupHealthRoute = (router: SecuritySolutionPluginRouter) => { path: SETUP_HEALTH_URL, security: { authz: { - requiredPrivileges: [RULES_API_READ], + requiredPrivileges: [INITIALIZE_SECURITY_SOLUTION], }, }, }) From 0500901fc6c2af9bee3c6f9a1bf61a238b68f4c0 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Fri, 14 Nov 2025 16:37:14 -0500 Subject: [PATCH 32/85] removes commented out code --- .../security/packages/features/src/rules/kibana_features.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts index a39684fab801c..04f3f35553316 100644 --- a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts @@ -69,7 +69,6 @@ export const getRulesBaseKibanaFeature = ( ), order: 1100, category: DEFAULT_APP_CATEGORIES.security, - // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], app: [RULES_FEATURE_ID, 'kibana'], catalogue: [APP_ID], alerting: alertingFeatures, From 052687fb61aeea1dcf574a890cfc8f7c131f5492 Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Fri, 14 Nov 2025 16:37:43 -0500 Subject: [PATCH 33/85] adds deprecation / migration from rulev1 to rulev2 and init exceptions subfeature --- .../packages/features/product_features.ts | 3 +- .../packages/features/src/constants.ts | 13 +- .../packages/features/src/exceptions/index.ts | 17 +++ .../src/exceptions/kibana_features.ts | 51 +++++++ .../src/exceptions/product_feature_config.ts | 37 +++++ .../features/src/product_features_keys.ts | 16 ++- .../features/src/rules/kibana_features.ts | 33 +++++ .../security/v1_features/kibana_features.ts | 10 +- .../security/v2_features/kibana_features.ts | 10 +- .../security/v3_features/kibana_features.ts | 10 +- .../security/v4_features/kibana_features.ts | 10 +- .../packages/features/src/v2_rules/index.ts | 20 +++ .../features/src/v2_rules/kibana_features.ts | 136 ++++++++++++++++++ .../src/v2_rules/kibana_subfeatures.ts | 86 +++++++++++ .../src/v2_rules/product_feature_config.ts | 36 +++++ .../packages/features/src/v2_rules/types.ts | 11 ++ .../security_solution/common/constants.ts | 2 +- .../common/hooks/use_missing_privileges.ts | 4 +- .../product_features_service.ts | 4 +- .../security_saved_objects.ts | 3 + .../security_solution/server/saved_objects.ts | 2 + 21 files changed, 483 insertions(+), 31 deletions(-) create mode 100644 x-pack/solutions/security/packages/features/src/exceptions/index.ts create mode 100644 x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts create mode 100644 x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts create mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/index.ts create mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts create mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts create mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts create mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/types.ts diff --git a/x-pack/solutions/security/packages/features/product_features.ts b/x-pack/solutions/security/packages/features/product_features.ts index 93aaa24bda52e..7591cc2249a0a 100644 --- a/x-pack/solutions/security/packages/features/product_features.ts +++ b/x-pack/solutions/security/packages/features/product_features.ts @@ -18,4 +18,5 @@ export { getAttackDiscoveryFeature } from './src/attack_discovery'; export { getTimelineFeature } from './src/timeline'; export { getNotesFeature } from './src/notes'; export { getSiemMigrationsFeature } from './src/siem_migrations'; -export { getRulesFeature } from './src/rules'; +// export { getRulesFeature } from './src/rules'; +export { getRulesV2Feature } from './src/v2_rules'; diff --git a/x-pack/solutions/security/packages/features/src/constants.ts b/x-pack/solutions/security/packages/features/src/constants.ts index e5ea639b2dcef..df86c3359a4be 100644 --- a/x-pack/solutions/security/packages/features/src/constants.ts +++ b/x-pack/solutions/security/packages/features/src/constants.ts @@ -36,6 +36,9 @@ export const CASES_FEATURE_ID_V2 = 'securitySolutionCasesV2' as const; export const CASES_FEATURE_ID_V3 = 'securitySolutionCasesV3' as const; export const SECURITY_SOLUTION_CASES_APP_ID = 'securitySolutionCases' as const; +export const EXCEPTIONS_SUBFEATURE_ID = 'securitySolutionExceptions' as const; +export const EXCEPTIONS_SUBFEATURE_ID_ALL = 'securitySolutionExceptionsAll' as const; +export const EXCEPTIONS_SUBFEATURE_ID_READ = 'securitySolutionExceptionsRead' as const; export const ASSISTANT_FEATURE_ID = 'securitySolutionAssistant' as const; export const ATTACK_DISCOVERY_FEATURE_ID = 'securitySolutionAttackDiscovery' as const; @@ -44,6 +47,7 @@ export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SIEM_MIGRATIONS_FEATURE_ID = 'securitySolutionSiemMigrations' as const; export const RULES_FEATURE_ID = 'securitySolutionRulesV1' as const; +export const RULES_FEATURE_ID_V2 = 'securitySolutionRulesV2' as const; // Rules API privileges export const RULES_API_READ = 'rules-read' as const; @@ -62,12 +66,13 @@ export const USERS_API_READ = 'users-read' as const; export const RULES_UI_READ = 'read_rules' as const; export const RULES_UI_DETECTIONS = 'detections' as const; export const RULES_UI_EXTERNAL_DETECTIONS = 'external_detections' as const; -export const RULES_UI_READ_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_READ}` as const; +export const RULES_UI_READ_PRIVILEGE = `${RULES_FEATURE_ID_V2}.${RULES_UI_READ}` as const; export const RULES_UI_EDIT = 'edit_rules' as const; -export const RULES_UI_EDIT_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_EDIT}` as const; -export const RULES_UI_DETECTIONS_PRIVILEGE = `${RULES_FEATURE_ID}.${RULES_UI_DETECTIONS}` as const; +export const RULES_UI_EDIT_PRIVILEGE = `${RULES_FEATURE_ID_V2}.${RULES_UI_EDIT}` as const; +export const RULES_UI_DETECTIONS_PRIVILEGE = + `${RULES_FEATURE_ID_V2}.${RULES_UI_DETECTIONS}` as const; export const RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE = - `${RULES_FEATURE_ID}.${RULES_UI_EXTERNAL_DETECTIONS}` as const; + `${RULES_FEATURE_ID_V2}.${RULES_UI_EXTERNAL_DETECTIONS}` as const; // Same as the plugin id defined by Cloud Security Posture export const CLOUD_POSTURE_APP_ID = 'csp' as const; diff --git a/x-pack/solutions/security/packages/features/src/exceptions/index.ts b/x-pack/solutions/security/packages/features/src/exceptions/index.ts new file mode 100644 index 0000000000000..c1e8e551d2bf3 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/exceptions/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// import { getExceptionsBaseKibanaFeature } from './kibana_features'; +// import type { ProductFeatureParams } from '../types'; +// import type { SecurityFeatureParams } from '../security/types'; +// import { EXCEPTIONS_SUBFEATURE_ID } from '../../constants'; + +// export const getExceptionsFeature = (params: SecurityFeatureParams): ProductFeatureParams => ({ +// baseKibanaFeature: getExceptionsBaseKibanaFeature(params), +// baseKibanaSubFeatureIds: [EXCEPTIONS_SUBFEATURE_ID], +// subFeaturesMap: new Map(), +// }); diff --git a/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts b/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts new file mode 100644 index 0000000000000..4ee74fd1d4b2a --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +// import { i18n } from '@kbn/i18n'; + +// import { APP_ID, EXCEPTIONS_FEATURE_ID } from '../constants'; +// import { type BaseKibanaFeatureConfig } from '../types'; +// import type { SecurityFeatureParams } from '../security/types'; + +// export const getExceptionsBaseKibanaFeature = ( +// params: SecurityFeatureParams +// ): BaseKibanaFeatureConfig => ({ +// id: EXCEPTIONS_FEATURE_ID, +// name: i18n.translate( +// 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionExceptionsTitle', +// { +// defaultMessage: 'Exceptions', +// } +// ), +// order: 1100, +// category: DEFAULT_APP_CATEGORIES.security, +// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], +// catalogue: [APP_ID], +// privileges: { +// all: { +// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], +// catalogue: [APP_ID], +// savedObject: { +// all: params.savedObjects, +// read: params.savedObjects, +// }, +// ui: ['read', 'crud'], +// api: ['exceptions_read', 'exceptions_write'], +// }, +// read: { +// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], +// catalogue: [APP_ID], +// savedObject: { +// all: [], +// read: params.savedObjects, +// }, +// ui: ['read'], +// api: ['exceptions_read'], +// }, +// }, +// }); diff --git a/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts new file mode 100644 index 0000000000000..3824e266502da --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// import { ProductFeatureRulesKey } from '../product_features_keys'; +// import type { ProductFeatureKibanaConfig } from '../types'; + +// /** +// * App features privileges configuration for the Rules feature. +// * These are the configs that are shared between both offering types (ess and serverless). +// * They can be extended on each offering plugin to register privileges using different way on each offering type. +// * +// * Privileges can be added in different ways: +// * - `privileges`: the privileges that will be added directly into the main Security feature. +// * - `subFeatureIds`: the ids of the sub-features that will be added into the Security subFeatures entry. +// * - `subFeaturesPrivileges`: the privileges that will be added into the existing Security subFeature with the privilege `id` specified. +// */ +// export const rulesDefaultProductFeaturesConfig: Record< +// ProductFeatureRulesKey, +// ProductFeatureKibanaConfig +// > = { +// [ProductFeatureRulesKey.rules]: { +// privileges: { +// all: { +// api: ['exceptions_read', 'exceptions_write'], +// ui: ['read', 'crud'], +// }, +// read: { +// api: ['exceptions_read'], +// ui: ['read'], +// }, +// }, +// }, +// }; diff --git a/x-pack/solutions/security/packages/features/src/product_features_keys.ts b/x-pack/solutions/security/packages/features/src/product_features_keys.ts index 8338f394a9551..83d473c8b228c 100644 --- a/x-pack/solutions/security/packages/features/src/product_features_keys.ts +++ b/x-pack/solutions/security/packages/features/src/product_features_keys.ts @@ -163,6 +163,18 @@ export enum ProductFeatureRulesKey { * Enables customization of prebuilt Elastic rules */ prebuiltRuleCustomization = 'prebuilt_rule_customization', + + /** + * Enables Exceptions + */ + exceptions = 'exceptions', +} + +export enum ProductFeatureExceptionsFeatureKey { + /** + * Enables Exceptions + */ + exceptions = 'exceptions', } // Merges the two enums. @@ -175,6 +187,7 @@ export const ProductFeatureKey = { ...ProductFeatureTimelineKey, ...ProductFeatureNotesKey, ...ProductFeatureRulesKey, + ...ProductFeatureExceptionsFeatureKey, }; // We need to merge the value and the type and export both to replicate how enum works. export type ProductFeatureKeyType = @@ -185,7 +198,8 @@ export type ProductFeatureKeyType = | ProductFeatureSiemMigrationsKey | ProductFeatureTimelineKey | ProductFeatureNotesKey - | ProductFeatureRulesKey; + | ProductFeatureRulesKey + | ProductFeatureExceptionsFeatureKey; export const ALL_PRODUCT_FEATURE_KEYS = Object.freeze(Object.values(ProductFeatureKey)); diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts index a39684fab801c..a6bb40ad109fd 100644 --- a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts @@ -32,10 +32,13 @@ import { RULES_API_ALL, RULES_API_READ, RULES_FEATURE_ID, + RULES_FEATURE_ID_V2, RULES_UI_EDIT, RULES_UI_READ, SERVER_APP_ID, USERS_API_READ, + EXCEPTIONS_SUBFEATURE_ID_ALL, + EXCEPTIONS_SUBFEATURE_ID_READ, } from '../constants'; import { type BaseKibanaFeatureConfig } from '../types'; import type { SecurityFeatureParams } from '../security/types'; @@ -60,6 +63,18 @@ const alertingFeatures = SECURITY_RULE_TYPES.map((ruleTypeId) => ({ export const getRulesBaseKibanaFeature = ( params: SecurityFeatureParams ): BaseKibanaFeatureConfig => ({ + deprecated: { + notice: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionSecurity.deprecationMessage', + { + defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', + values: { + currentId: RULES_FEATURE_ID, + latestId: RULES_FEATURE_ID_V2, + }, + } + ), + }, id: RULES_FEATURE_ID, name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionRolesTitle', @@ -78,6 +93,15 @@ export const getRulesBaseKibanaFeature = ( }, privileges: { all: { + replacedBy: { + default: [{ feature: RULES_FEATURE_ID_V2, privileges: ['all'] }], + minimal: [ + { + feature: RULES_FEATURE_ID_V2, + privileges: ['minimal_all', EXCEPTIONS_SUBFEATURE_ID_ALL], + }, + ], + }, app: [RULES_FEATURE_ID, 'kibana'], catalogue: [APP_ID], savedObject: { @@ -108,6 +132,15 @@ export const getRulesBaseKibanaFeature = ( ], }, read: { + replacedBy: { + default: [{ feature: RULES_FEATURE_ID_V2, privileges: ['read'] }], + minimal: [ + { + feature: RULES_FEATURE_ID_V2, + privileges: ['minimal_read', EXCEPTIONS_SUBFEATURE_ID_READ], + }, + ], + }, app: [RULES_FEATURE_ID, 'kibana'], catalogue: [APP_ID], savedObject: { diff --git a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts index 23e9c5e7e8a3d..dc319e5ec71da 100644 --- a/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v1_features/kibana_features.ts @@ -29,7 +29,7 @@ import { LISTS_API_SUMMARY, LISTS_API_READ, LISTS_API_ALL, - RULES_FEATURE_ID, + RULES_FEATURE_ID_V2, SECURITY_UI_SHOW, SECURITY_UI_CRUD, INITIALIZE_SECURITY_SOLUTION, @@ -107,14 +107,14 @@ export const getSecurityBaseKibanaFeature = ({ { feature: NOTES_FEATURE_ID, privileges: ['all'] }, // note: overriden by product feature endpointArtifactManagement when enabled { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, - { feature: RULES_FEATURE_ID, privileges: ['all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['all'] }, ], minimal: [ { feature: TIMELINE_FEATURE_ID, privileges: ['all'] }, { feature: NOTES_FEATURE_ID, privileges: ['all'] }, // note: overriden by product feature endpointArtifactManagement when enabled { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_all'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], @@ -163,13 +163,13 @@ export const getSecurityBaseKibanaFeature = ({ { feature: TIMELINE_FEATURE_ID, privileges: ['read'] }, { feature: NOTES_FEATURE_ID, privileges: ['read'] }, { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, - { feature: RULES_FEATURE_ID, privileges: ['read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['read'] }, ], minimal: [ { feature: TIMELINE_FEATURE_ID, privileges: ['read'] }, { feature: NOTES_FEATURE_ID, privileges: ['read'] }, { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_read'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], diff --git a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts index 788f29ef7bd4c..ac2a09bfafd94 100644 --- a/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v2_features/kibana_features.ts @@ -28,7 +28,7 @@ import { LISTS_API_ALL, LISTS_API_READ, LISTS_API_SUMMARY, - RULES_FEATURE_ID, + RULES_FEATURE_ID_V2, SECURITY_UI_SHOW, SECURITY_UI_CRUD, INITIALIZE_SECURITY_SOLUTION, @@ -104,12 +104,12 @@ export const getSecurityV2BaseKibanaFeature = ({ default: [ // note: overriden by product feature endpointArtifactManagement when enabled { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, - { feature: RULES_FEATURE_ID, privileges: ['all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['all'] }, ], minimal: [ // note: overriden by product feature endpointArtifactManagement when enabled { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_all'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], @@ -146,11 +146,11 @@ export const getSecurityV2BaseKibanaFeature = ({ replacedBy: { default: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, - { feature: RULES_FEATURE_ID, privileges: ['read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['read'] }, ], minimal: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_read'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], diff --git a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts index c00578819438d..5237f2016ba7f 100644 --- a/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v3_features/kibana_features.ts @@ -25,7 +25,7 @@ import { CLOUD_POSTURE_APP_ID, SERVER_APP_ID, SECURITY_FEATURE_ID_V5, - RULES_FEATURE_ID, + RULES_FEATURE_ID_V2, LISTS_API_SUMMARY, LISTS_API_READ, LISTS_API_ALL, @@ -102,11 +102,11 @@ export const getSecurityV3BaseKibanaFeature = ({ replacedBy: { default: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, - { feature: RULES_FEATURE_ID, privileges: ['all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['all'] }, ], minimal: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_all'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], @@ -143,11 +143,11 @@ export const getSecurityV3BaseKibanaFeature = ({ replacedBy: { default: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, - { feature: RULES_FEATURE_ID, privileges: ['read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['read'] }, ], minimal: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_read'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], diff --git a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts index 2d1c676ccab5d..2c91d7992d78b 100644 --- a/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v4_features/kibana_features.ts @@ -25,7 +25,7 @@ import { CLOUD_POSTURE_APP_ID, SERVER_APP_ID, SECURITY_FEATURE_ID_V5, - RULES_FEATURE_ID, + RULES_FEATURE_ID_V2, LISTS_API_READ, RULES_API_READ, ALERTS_API_READ, @@ -102,11 +102,11 @@ export const getSecurityV4BaseKibanaFeature = ({ replacedBy: { default: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['all'] }, - { feature: RULES_FEATURE_ID, privileges: ['all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['all'] }, ], minimal: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_all'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_all'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_all'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], @@ -143,11 +143,11 @@ export const getSecurityV4BaseKibanaFeature = ({ replacedBy: { default: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['read'] }, - { feature: RULES_FEATURE_ID, privileges: ['read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['read'] }, ], minimal: [ { feature: SECURITY_FEATURE_ID_V5, privileges: ['minimal_read'] }, - { feature: RULES_FEATURE_ID, privileges: ['minimal_read'] }, + { feature: RULES_FEATURE_ID_V2, privileges: ['minimal_read'] }, ], }, app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/index.ts b/x-pack/solutions/security/packages/features/src/v2_rules/index.ts new file mode 100644 index 0000000000000..80d41396b691b --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/v2_rules/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getRulesV2BaseKibanaFeature } from './kibana_features'; +import type { ProductFeatureParams } from '../types'; +import type { SecurityFeatureParams } from '../security/types'; +import { rulesDefaultProductFeaturesConfig } from './product_feature_config'; +import { getExceptionsSubFeaturesMap } from './kibana_subfeatures'; +import { EXCEPTIONS_SUBFEATURE_ID } from '../constants'; + +export const getRulesV2Feature = (params: SecurityFeatureParams): ProductFeatureParams => ({ + baseKibanaFeature: getRulesV2BaseKibanaFeature(params), + baseKibanaSubFeatureIds: [EXCEPTIONS_SUBFEATURE_ID], + subFeaturesMap: getExceptionsSubFeaturesMap(params.savedObjects), + productFeatureConfig: rulesDefaultProductFeaturesConfig, +}); diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts new file mode 100644 index 0000000000000..71360860a4f6e --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; +import { i18n } from '@kbn/i18n'; + +import { + ESQL_RULE_TYPE_ID, + EQL_RULE_TYPE_ID, + INDICATOR_RULE_TYPE_ID, + ML_RULE_TYPE_ID, + QUERY_RULE_TYPE_ID, + SAVED_QUERY_RULE_TYPE_ID, + THRESHOLD_RULE_TYPE_ID, + NEW_TERMS_RULE_TYPE_ID, +} from '@kbn/securitysolution-rules'; +import { + ALERTS_API_ALL, + ALERTS_API_READ, + APP_ID, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + LEGACY_NOTIFICATIONS_ID, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + RULES_API_ALL, + RULES_API_READ, + RULES_FEATURE_ID_V2, + RULES_UI_EDIT, + RULES_UI_READ, + SERVER_APP_ID, + USERS_API_READ, +} from '../constants'; +import { type BaseKibanaFeatureConfig } from '../types'; +import type { SecurityFeatureParams } from '../security/types'; + +const SECURITY_RULE_TYPES = [ + LEGACY_NOTIFICATIONS_ID, + ESQL_RULE_TYPE_ID, + EQL_RULE_TYPE_ID, + INDICATOR_RULE_TYPE_ID, + ML_RULE_TYPE_ID, + QUERY_RULE_TYPE_ID, + SAVED_QUERY_RULE_TYPE_ID, + THRESHOLD_RULE_TYPE_ID, + NEW_TERMS_RULE_TYPE_ID, +]; + +const alertingFeatures = SECURITY_RULE_TYPES.map((ruleTypeId) => ({ + ruleTypeId, + consumers: [SERVER_APP_ID], +})); + +export const getRulesV2BaseKibanaFeature = ( + params: SecurityFeatureParams +): BaseKibanaFeatureConfig => ({ + id: RULES_FEATURE_ID_V2, + name: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionRolesTitle', + { + defaultMessage: 'Rules', + } + ), + order: 1100, + category: DEFAULT_APP_CATEGORIES.security, + // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], + app: [RULES_FEATURE_ID_V2, 'kibana'], + catalogue: [APP_ID], + alerting: alertingFeatures, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + privileges: { + all: { + app: [RULES_FEATURE_ID_V2, 'kibana'], + catalogue: [APP_ID], + savedObject: { + all: params.savedObjects, + read: params.savedObjects, + }, + alerting: { + rule: { all: alertingFeatures }, + alert: { all: alertingFeatures }, + }, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + ui: [RULES_UI_READ, RULES_UI_EDIT], + api: [ + RULES_API_ALL, + RULES_API_READ, + ALERTS_API_ALL, + ALERTS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + LISTS_API_ALL, + LISTS_API_READ, + LISTS_API_SUMMARY, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + 'rac', + ], + }, + read: { + app: [RULES_FEATURE_ID_V2, 'kibana'], + catalogue: [APP_ID], + savedObject: { + all: [], + read: params.savedObjects, + }, + alerting: { + rule: { read: alertingFeatures }, + alert: { read: alertingFeatures }, + }, + management: { + insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI + }, + ui: [RULES_UI_READ], + api: [ + RULES_API_READ, + ALERTS_API_READ, + EXCEPTIONS_API_READ, + LISTS_API_READ, + USERS_API_READ, + INITIALIZE_SECURITY_SOLUTION, + 'rac', + ], + }, + }, +}); diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts new file mode 100644 index 0000000000000..d029d9f163a65 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import { + APP_ID, + EXCEPTIONS_API_READ, + EXCEPTIONS_API_ALL, + EXCEPTIONS_SUBFEATURE_ID, + EXCEPTIONS_SUBFEATURE_ID_ALL, + EXCEPTIONS_SUBFEATURE_ID_READ, + LISTS_API_ALL, + LISTS_API_READ, +} from '../../constants'; +import type { SecurityFeatureParams } from '../security/types'; + +const TRANSLATIONS = Object.freeze({ + all: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.subFeatures.allPrivilegeName', + { + defaultMessage: 'All', + } + ), + read: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName', + { + defaultMessage: 'Read', + } + ), +}); + +/** + * Defines all the Security Solution Cases subFeatures available. + * The order of the subFeatures is the order they will be displayed + */ +export const getExceptionsSubFeaturesMap = ( + savedObjects: SecurityFeatureParams['savedObjects'] +) => { + const exceptionsSubFeature: SubFeatureConfig = { + name: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.exceptionsSubFeatureName', + { + defaultMessage: 'Exceptions', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + id: EXCEPTIONS_SUBFEATURE_ID_ALL, + includeIn: 'all', + name: TRANSLATIONS.all, + savedObject: { + all: savedObjects, + read: savedObjects, + }, + ui: ['readExceptions', 'crudExceptions'], + api: [EXCEPTIONS_API_READ, EXCEPTIONS_API_ALL, LISTS_API_ALL, LISTS_API_READ], + }, + { + id: EXCEPTIONS_SUBFEATURE_ID_READ, + includeIn: 'read', + name: TRANSLATIONS.read, + catalogue: [APP_ID], + savedObject: { + all: [], + read: savedObjects, + }, + ui: ['readExceptions'], + api: [EXCEPTIONS_API_READ, LISTS_API_READ], + }, + ], + }, + ], + }; + + return new Map([ + [EXCEPTIONS_SUBFEATURE_ID, exceptionsSubFeature], + ]); +}; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts new file mode 100644 index 0000000000000..b78ae93bfe48e --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ProductFeatureRulesKey } from '../product_features_keys'; +import type { RulesProductFeaturesConfig } from './types'; + +export const rulesDefaultProductFeaturesConfig: RulesProductFeaturesConfig = { + [ProductFeatureRulesKey.externalDetections]: { + privileges: { + all: { + ui: ['external_detections'], + api: [], + }, + read: { + ui: ['external_detections'], + api: [], + }, + }, + }, + [ProductFeatureRulesKey.detections]: { + privileges: { + all: { + ui: ['detections'], + api: ['cloud-security-posture-all', 'cloud-security-posture-read', 'bulkGetUserProfiles'], + }, + read: { + ui: ['detections'], + api: ['cloud-security-posture-read', 'bulkGetUserProfiles'], + }, + }, + }, +}; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/types.ts b/x-pack/solutions/security/packages/features/src/v2_rules/types.ts new file mode 100644 index 0000000000000..af9bf035239c9 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/v2_rules/types.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ProductFeatureRulesKey } from '../product_features_keys'; +import type { ProductFeaturesConfig } from '../types'; + +export type RulesProductFeaturesConfig = ProductFeaturesConfig; diff --git a/x-pack/solutions/security/plugins/security_solution/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/constants.ts index d15e54378193d..70a9f59b49907 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/constants.ts @@ -30,7 +30,7 @@ export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SERVER_APP_ID = 'siem' as const; export const SECURITY_FEATURE_ID = SECURITY_FEATURE_ID_V5; -export { RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; +export { RULES_FEATURE_ID_V2 as RULES_FEAUTRE_ID } from '@kbn/security-solution-features/constants'; export const APP_NAME = 'Security' as const; export const APP_ICON_SOLUTION = 'logoSecurity' as const; export const APP_PATH = `/app/security` as const; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts index 1e94846a1e557..829c3ea293bca 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; +import { RULES_FEATURE_ID_V2 } from '@kbn/security-solution-features/constants'; import { useMemo } from 'react'; import type { Privilege } from '../../detections/containers/detection_engine/alerts/types'; import { useUserPrivileges } from '../components/user_privileges'; @@ -66,7 +66,7 @@ export const useMissingPrivileges = (): MissingPrivileges => { } if (rulesPrivileges.edit === false) { - featurePrivileges.push([RULES_FEATURE_ID, ['all']]); + featurePrivileges.push([RULES_FEATURE_ID_V2, ['all']]); } const missingItemsPrivileges = getMissingIndexPrivileges(listPrivileges.result.listItems.index); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts index ee1ac46fb6c45..6edb9d1606a5c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts @@ -24,7 +24,7 @@ import { getTimelineFeature, getNotesFeature, getSiemMigrationsFeature, - getRulesFeature, + getRulesV2Feature, } from '@kbn/security-solution-features/product_features'; import { API_ACTION_PREFIX } from '@kbn/security-solution-features/actions'; import type { ExperimentalFeatures } from '../../../common'; @@ -81,7 +81,7 @@ export class ProductFeaturesService { getNotesFeature({ ...securityFeatureParams, savedObjects: securityNotesSavedObjects }), ]); this.productFeaturesRegistry.create('rules', [ - getRulesFeature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), + getRulesV2Feature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), ]); if (!experimentalFeatures.siemMigrationsDisabled) { this.productFeaturesRegistry.create('siemMigrations', [getSiemMigrationsFeature()]); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts index 6eb35aa12df52..56379d5648861 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts @@ -11,6 +11,7 @@ import { timelineSavedObjectTypes, notesSavedObjectTypes, savedObjectTypes, + exceptionsSavedObjectTypes, } from '../../saved_objects'; import { noteType, pinnedEventType, timelineType } from '../timeline/saved_object_mappings'; import { prebuiltRuleAssetType } from '../detection_engine/prebuilt_rules'; @@ -75,3 +76,5 @@ export const rulesSavedObjects = [ EXCEPTION_LIST_NAMESPACE_AGNOSTIC, prebuiltRuleAssetType.name, ]; + +export const securityExceptionsSavedObjects = exceptionsSavedObjectTypes; diff --git a/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts index c860be2cbbbb9..1c3be30bdad04 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/saved_objects.ts @@ -9,6 +9,7 @@ import type { CoreSetup, Logger } from '@kbn/core/server'; import { promptType } from '@kbn/security-ai-prompts'; import type { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; +import { exceptionListType } from '@kbn/lists-plugin/server/saved_objects'; import { referenceDataSavedObjectType } from './endpoint/lib/reference_data'; import { protectionUpdatesNoteType } from './endpoint/lib/protection_updates_note/saved_object_mappings'; import { noteType, pinnedEventType, timelineType } from './lib/timeline/saved_object_mappings'; @@ -52,6 +53,7 @@ export const savedObjectTypes = types.map((type) => type.name); export const timelineSavedObjectTypes = [timelineType.name, pinnedEventType.name]; export const notesSavedObjectTypes = [noteType.name]; +export const exceptionsSavedObjectTypes = [exceptionListType.name]; export const initSavedObjects = (savedObjects: CoreSetup['savedObjects']) => { types.forEach((type) => savedObjects.registerType(type)); From 63b85e46aa10c291eac27bd5c11047417288e9be Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Fri, 14 Nov 2025 17:51:07 -0500 Subject: [PATCH 34/85] fixes attack page merge conflicts --- .../detections/pages/attacks/attacks.test.tsx | 15 +++++++++++++-- .../public/detections/pages/attacks/attacks.tsx | 8 +++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx index 42d03b6407aff..f3a8c389c097a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx @@ -17,8 +17,10 @@ import { NO_INDEX_TEST_ID } from '../../components/alerts/empty_pages/no_index_e import { NO_INTEGRATION_CALLOUT_TEST_ID } from '../../components/callouts/no_api_integration_key_callout'; import { NEED_ADMIN_CALLOUT_TEST_ID } from '../../../detection_engine/rule_management/components/callouts/need_admin_for_update_rules_callout'; import { useMissingPrivileges } from '../../../common/hooks/use_missing_privileges'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; jest.mock('../../components/user_info'); +jest.mock('../../../common/components/user_privileges'); jest.mock('../../containers/detection_engine/lists/use_lists_config'); jest.mock('../../../sourcerer/containers/use_signal_helpers'); jest.mock('../../../common/hooks/use_missing_privileges'); @@ -26,9 +28,19 @@ jest.mock('../../components/attacks/wrapper', () => ({ Wrapper: () =>
, })); +const doMockRulesPrivileges = ({ read = false }) => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + rulesPrivileges: { + read, + edit: false, + }, + }); +}; + describe('', () => { beforeEach(() => { jest.clearAllMocks(); + doMockRulesPrivileges({}); }); describe('showing loading spinner', () => { @@ -221,7 +233,6 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: false, hasIndexRead: false, }, ]); @@ -253,10 +264,10 @@ describe('', () => { { loading: false, isAuthenticated: true, - canUserREAD: true, hasIndexRead: true, }, ]); + doMockRulesPrivileges({ read: true }); (useListsConfig as jest.Mock).mockReturnValue({ loading: false, needsConfiguration: false, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx index 83a63a4362d13..24d94de8847b3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx @@ -8,6 +8,7 @@ import { EuiFlexGroup, EuiLoadingSpinner } from '@elastic/eui'; import React, { memo, useMemo } from 'react'; import type { DocLinks } from '@kbn/doc-links'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { Wrapper } from '../../components/attacks/wrapper'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { NoApiIntegrationKeyCallOut } from '../../components/callouts/no_api_integration_key_callout'; @@ -29,7 +30,8 @@ export const ATTACKS_PAGE_LOADING_TEST_ID = 'attacks-page-loading'; * the actual content of the attacks page is rendered */ export const AttacksPage = memo(() => { - const [{ loading: userInfoLoading, isAuthenticated, canUserREAD, hasIndexRead }] = useUserData(); + const [{ loading: userInfoLoading, isAuthenticated, hasIndexRead }] = useUserData(); + const canReadAlerts = useUserPrivileges().rulesPrivileges.read; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { signalIndexNeedsInit } = useSignalHelpers(); @@ -47,8 +49,8 @@ export const AttacksPage = memo(() => { [needsListsConfiguration, signalIndexNeedsInit] ); const privilegesRequired: boolean = useMemo( - () => !signalIndexNeedsInit && (hasIndexRead === false || canUserREAD === false), - [canUserREAD, hasIndexRead, signalIndexNeedsInit] + () => !signalIndexNeedsInit && (hasIndexRead === false || canReadAlerts === false), + [canReadAlerts, hasIndexRead, signalIndexNeedsInit] ); if (loading) { From f0a7ff1d836c090d5e8349572e98a79638588814 Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Mon, 17 Nov 2025 16:03:08 -0500 Subject: [PATCH 35/85] typo lead to bug in UI where buttons were disabled --- .../security/plugins/security_solution/common/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/constants.ts index 70a9f59b49907..f6194901a1d67 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/constants.ts @@ -30,7 +30,7 @@ export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SERVER_APP_ID = 'siem' as const; export const SECURITY_FEATURE_ID = SECURITY_FEATURE_ID_V5; -export { RULES_FEATURE_ID_V2 as RULES_FEAUTRE_ID } from '@kbn/security-solution-features/constants'; +export { RULES_FEATURE_ID_V2 as RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; export const APP_NAME = 'Security' as const; export const APP_ICON_SOLUTION = 'logoSecurity' as const; export const APP_PATH = `/app/security` as const; From 5e99b8bdbd69a76730d35f085c8218e6ce72e704 Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Mon, 17 Nov 2025 22:38:22 -0500 Subject: [PATCH 36/85] continue registering rules v1 alongside rules v2, use alerting rules client function for create rule-exception route --- .../packages/features/product_features.ts | 2 +- .../lists/server/scripts/export_exceptions.sh | 26 ++++++++++++ .../lists/server/scripts/export_list_items.sh | 1 + .../server/scripts/get_exception_list.sh | 2 +- .../api/create_rule_exceptions/route.ts | 42 ++++++++++++------- .../product_features_service.ts | 2 + 6 files changed, 58 insertions(+), 17 deletions(-) create mode 100755 x-pack/solutions/security/plugins/lists/server/scripts/export_exceptions.sh diff --git a/x-pack/solutions/security/packages/features/product_features.ts b/x-pack/solutions/security/packages/features/product_features.ts index 7591cc2249a0a..4011f15f5f425 100644 --- a/x-pack/solutions/security/packages/features/product_features.ts +++ b/x-pack/solutions/security/packages/features/product_features.ts @@ -18,5 +18,5 @@ export { getAttackDiscoveryFeature } from './src/attack_discovery'; export { getTimelineFeature } from './src/timeline'; export { getNotesFeature } from './src/notes'; export { getSiemMigrationsFeature } from './src/siem_migrations'; -// export { getRulesFeature } from './src/rules'; +export { getRulesFeature } from './src/rules'; export { getRulesV2Feature } from './src/v2_rules'; diff --git a/x-pack/solutions/security/plugins/lists/server/scripts/export_exceptions.sh b/x-pack/solutions/security/plugins/lists/server/scripts/export_exceptions.sh new file mode 100755 index 0000000000000..d869bd43fc4c4 --- /dev/null +++ b/x-pack/solutions/security/plugins/lists/server/scripts/export_exceptions.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License +# 2.0; you may not use this file except in compliance with the Elastic License +# 2.0. +# + +set -e +./check_env_variables.sh + +# Uses a defaults if no argument is specified +LIST_ID=${2:-ips.txt} +L_ID=${1} + +echo $LIST_ID +echo $L_ID + +# Example to export +# ./export_list_items.sh > /tmp/ips.txt + +curl -s -k \ + -H 'kbn-xsrf: 123' \ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ + -X POST "${KIBANA_URL}${SPACE_URL}/api/exception_lists/_export?id=${L_ID}&list_id=${LIST_ID}&namespace_type=single" \ No newline at end of file diff --git a/x-pack/solutions/security/plugins/lists/server/scripts/export_list_items.sh b/x-pack/solutions/security/plugins/lists/server/scripts/export_list_items.sh index 30741222eb46e..33f067d46bf67 100755 --- a/x-pack/solutions/security/plugins/lists/server/scripts/export_list_items.sh +++ b/x-pack/solutions/security/plugins/lists/server/scripts/export_list_items.sh @@ -13,6 +13,7 @@ set -e # Uses a defaults if no argument is specified LIST_ID=${1:-ips.txt} +echo $LIST_ID # Example to export # ./export_list_items.sh > /tmp/ips.txt diff --git a/x-pack/solutions/security/plugins/lists/server/scripts/get_exception_list.sh b/x-pack/solutions/security/plugins/lists/server/scripts/get_exception_list.sh index 473ce4c671080..e036f1648b508 100755 --- a/x-pack/solutions/security/plugins/lists/server/scripts/get_exception_list.sh +++ b/x-pack/solutions/security/plugins/lists/server/scripts/get_exception_list.sh @@ -16,4 +16,4 @@ NAMESPACE_TYPE=${2-single} # Example: ./get_exception_list.sh {id} agnostic curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - -X GET "${KIBANA_URL}${SPACE_URL}/api/exception_lists?list_id=$1&namespace_type=${NAMESPACE_TYPE}" | jq . + -X GET "${KIBANA_URL}${SPACE_URL}/api/exception_lists?list_id=$1&namespace_type=${NAMESPACE_TYPE}" diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts index 1fa1cbc468c44..918836fa1b719 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts @@ -23,6 +23,7 @@ import { } from '@kbn/securitysolution-exceptions-common/api'; import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; import { CREATE_RULE_EXCEPTIONS_URL } from '../../../../../../common/api/detection_engine/rule_exceptions'; import { readRules } from '../../../rule_management/logic/detection_rules_client/read_rules'; @@ -90,6 +91,7 @@ export const createRuleExceptionsRoute = (router: SecuritySolutionPluginRouter) rule, listsClient, detectionRulesClient, + alertingRulesClient: rulesClient, }); return response.ok({ body: CreateRuleExceptionListItemsResponse.parse(createdItems) }); @@ -109,11 +111,13 @@ export const createRuleExceptions = async ({ rule, listsClient, detectionRulesClient, + alertingRulesClient, }: { items: CreateRuleExceptionListItemProps[]; + rule: SanitizedRule; listsClient: ExceptionListClient | null; detectionRulesClient: IDetectionRulesClient; - rule: SanitizedRule; + alertingRulesClient: RulesClient; }) => { const ruleDefaultLists = rule.params.exceptionsList.filter( (list) => list.type === ExceptionListTypeEnum.RULE_DEFAULT @@ -149,6 +153,7 @@ export const createRuleExceptions = async ({ listsClient, detectionRulesClient, removeOldAssociation: true, + alertingRulesClient, }); return createExceptionListItems({ items, defaultList, listsClient }); @@ -159,6 +164,7 @@ export const createRuleExceptions = async ({ listsClient, detectionRulesClient, removeOldAssociation: false, + alertingRulesClient, }); return createExceptionListItems({ items, defaultList, listsClient }); @@ -249,11 +255,13 @@ export const createAndAssociateDefaultExceptionList = async ({ listsClient, detectionRulesClient, removeOldAssociation, + alertingRulesClient, }: { rule: SanitizedRule; listsClient: ExceptionListClient | null; detectionRulesClient: IDetectionRulesClient; removeOldAssociation: boolean; + alertingRulesClient: RulesClient; }): Promise => { const exceptionListToAssociate = await createExceptionList({ rule, listsClient }); @@ -269,20 +277,24 @@ export const createAndAssociateDefaultExceptionList = async ({ ? existingRuleExceptionLists.filter((list) => list.type !== ExceptionListTypeEnum.RULE_DEFAULT) : existingRuleExceptionLists; - await detectionRulesClient.patchRule({ - rulePatch: { - rule_id: rule.params.ruleId, - ...rule.params, - exceptions_list: [ - ...ruleExceptionLists, - { - id: exceptionListToAssociate.id, - list_id: exceptionListToAssociate.list_id, - type: exceptionListToAssociate.type, - namespace_type: exceptionListToAssociate.namespace_type, - }, - ], - }, + // if patchRule fails, delete the exception list created above + await alertingRulesClient.bulkEditRuleParamsWithReadAuth({ + ids: [rule.id], + operations: [ + { + field: 'exceptionsList', + operation: 'set', + value: [ + ...ruleExceptionLists, + { + id: exceptionListToAssociate.id, + list_id: exceptionListToAssociate.list_id, + type: exceptionListToAssociate.type, + namespace_type: exceptionListToAssociate.namespace_type, + }, + ], + }, + ], }); return exceptionListToAssociate; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts index 6edb9d1606a5c..d0ab1140969ea 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts @@ -25,6 +25,7 @@ import { getNotesFeature, getSiemMigrationsFeature, getRulesV2Feature, + getRulesFeature, } from '@kbn/security-solution-features/product_features'; import { API_ACTION_PREFIX } from '@kbn/security-solution-features/actions'; import type { ExperimentalFeatures } from '../../../common'; @@ -81,6 +82,7 @@ export class ProductFeaturesService { getNotesFeature({ ...securityFeatureParams, savedObjects: securityNotesSavedObjects }), ]); this.productFeaturesRegistry.create('rules', [ + getRulesFeature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), getRulesV2Feature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), ]); if (!experimentalFeatures.siemMigrationsDisabled) { From 855dee4593a1d0c9d8996e93e838547c852465cb Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 18 Nov 2025 13:39:33 -0600 Subject: [PATCH 37/85] Allow users with Dashboard privileges to view the Automatic Migrations section Security:read users should be able to view this section. Co-authored-by: Jatin Kathuria --- .../plugins/security_solution/public/onboarding/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts index b646a97e9d377..cb9c574f4c286 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts @@ -43,6 +43,6 @@ export const onboardingConfig: TopicConfig[] = [ }), body: siemMigrationsBodyConfig, disabledExperimentalFlagRequired: 'siemMigrationsDisabled', - capabilitiesRequired: RULES_UI_DETECTIONS_PRIVILEGE, + capabilitiesRequired: [[`dashboard_v2.show`],[RULES_UI_DETECTIONS_PRIVILEGE]], }, ]; From 633e28ec226bffe9c2eb80b9b156a3bd563d6910 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 18 Nov 2025 20:06:02 +0000 Subject: [PATCH 38/85] Changes from node scripts/eslint_all_files --no-cache --fix --- .../plugins/security_solution/public/onboarding/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts b/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts index cb9c574f4c286..86b201a383e88 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/onboarding/config.ts @@ -43,6 +43,6 @@ export const onboardingConfig: TopicConfig[] = [ }), body: siemMigrationsBodyConfig, disabledExperimentalFlagRequired: 'siemMigrationsDisabled', - capabilitiesRequired: [[`dashboard_v2.show`],[RULES_UI_DETECTIONS_PRIVILEGE]], + capabilitiesRequired: [[`dashboard_v2.show`], [RULES_UI_DETECTIONS_PRIVILEGE]], }, ]; From 9a07fa93f77176ca860c0f325f5a8dd27a396fbf Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 18 Nov 2025 13:56:13 -0600 Subject: [PATCH 39/85] Update new Attacks links from upstream to use new Rules privileges This is new code since the RBAC branch was opened, so we need to make the appropriate updates here. NB that we are currently assuming that Attack Alerts will use Alerts privileges, and thus are making these links require the Rules-based UI privileges, which will later be refined to alerts-specific privileges. --- .../plugins/security_solution/public/detections/links.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts b/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts index e53255fce6c56..61b64a4347149 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/links.ts @@ -17,7 +17,6 @@ import { ALERTS_PATH, ATTACK_DISCOVERY_FEATURE_ID, ATTACKS_PATH, - SECURITY_FEATURE_ID, SecurityPageName, } from '../../common/constants'; import { ALERT_SUMMARY, ALERTS, ATTACKS } from '../app/translations'; @@ -46,9 +45,7 @@ const alertsSubLink: LinkItem = { }; const attacksSubLink: LinkItem = { - capabilities: [ - [`${SECURITY_FEATURE_ID}.show`, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], - ], + capabilities: [[RULES_UI_READ_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`]], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.attacks', { defaultMessage: 'Attacks', @@ -70,8 +67,8 @@ export const alertDetectionsLinks: LinkItem = { }), path: ALERT_DETECTIONS, capabilities: [ - [`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`], - [`${SECURITY_FEATURE_ID}.show`, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], + [RULES_UI_READ_PRIVILEGE, RULES_UI_DETECTIONS_PRIVILEGE], + [RULES_UI_READ_PRIVILEGE, `${ATTACK_DISCOVERY_FEATURE_ID}.attack-discovery`], ], globalNavPosition: 3, globalSearchKeywords: [ From 4000d0d5a24aac453b2ceb982026d8dd05743d23 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 19 Nov 2025 16:47:34 -0500 Subject: [PATCH 40/85] adds exceptions permissions to user privileges hook --- .../packages/features/src/constants.ts | 2 + .../features/src/v2_rules/kibana_features.ts | 1 - .../src/v2_rules/kibana_subfeatures.ts | 6 ++- .../user_privileges_context.tsx | 29 ++++++------- .../hooks/use_missing_privileges.test.tsx | 10 ++++- .../common/hooks/use_missing_privileges.ts | 4 +- .../public/common/utils/rules_capabilities.ts | 42 +++++++++++++++++++ .../promotion_rules/promotion_rules_table.tsx | 2 +- .../pages/rule_creation/index.tsx | 2 +- .../pages/rule_editing/index.tsx | 2 +- .../pages/rule_details/index.tsx | 2 +- .../rule_actions_overflow/index.test.tsx | 2 +- .../rule_actions_overflow/index.tsx | 2 +- .../all_exception_items_table/index.tsx | 6 +-- .../components/rule_backfills_info/index.tsx | 2 +- .../rule_gaps/components/rule_gaps/index.tsx | 2 +- .../rule_snooze_badge/rule_snooze_badge.tsx | 2 +- .../hooks/use_rule_update_callout.tsx | 2 +- .../pre_packaged_rules/load_empty_prompt.tsx | 2 +- .../add_prebuilt_rules_header_buttons.tsx | 2 +- .../add_prebuilt_rules_table.test.tsx | 30 ++++++++++--- .../add_prebuilt_rules_table_context.tsx | 2 +- .../use_add_prebuilt_rules_table_columns.tsx | 2 +- .../feature_tour/rules_feature_tour.tsx | 2 +- .../rules_table/rules_table_toolbar.tsx | 2 +- .../components/rules_table/rules_tables.tsx | 2 +- .../upgrade_prebuilt_rules_table_buttons.tsx | 2 +- ...e_upgrade_prebuilt_rules_table_columns.tsx | 2 +- .../technique_panel_popover.test.tsx | 10 ++++- .../technique_panel_popover.tsx | 2 +- .../pages/rule_management/index.tsx | 2 +- .../use_add_exception_actions.test.tsx | 14 +++---- .../use_add_exception_actions.tsx | 4 +- .../lists/use_lists_privileges.tsx | 15 ++++--- .../detections/pages/alerts/alerts.test.tsx | 6 ++- .../public/detections/pages/alerts/alerts.tsx | 2 +- .../detections/pages/attacks/attacks.test.tsx | 6 ++- .../detections/pages/attacks/attacks.tsx | 2 +- .../hooks/use_exceptions_list.card/index.tsx | 7 +++- .../hooks/use_list_detail_view/index.ts | 9 ++-- .../exceptions/pages/shared_lists/index.tsx | 7 ++-- .../pages/shared_lists/shared_lists.test.tsx | 5 ++- .../use_highlighted_fields_privilege.test.tsx | 4 +- .../use_highlighted_fields_privilege.tsx | 2 +- .../public/use_readonly_header.ts | 6 +-- 45 files changed, 178 insertions(+), 93 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/common/utils/rules_capabilities.ts diff --git a/x-pack/solutions/security/packages/features/src/constants.ts b/x-pack/solutions/security/packages/features/src/constants.ts index 2bb6c39b542b7..914975bf5c8f6 100644 --- a/x-pack/solutions/security/packages/features/src/constants.ts +++ b/x-pack/solutions/security/packages/features/src/constants.ts @@ -73,6 +73,8 @@ export const RULES_UI_DETECTIONS_PRIVILEGE = `${RULES_FEATURE_ID_V2}.${RULES_UI_DETECTIONS}` as const; export const RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE = `${RULES_FEATURE_ID_V2}.${RULES_UI_EXTERNAL_DETECTIONS}` as const; +export const EXCEPTIONS_UI_READ = 'readExceptions' as const; +export const EXCEPTIONS_UI_CRUD = 'crudExceptions' as const; // Same as the plugin id defined by Cloud Security Posture export const CLOUD_POSTURE_APP_ID = 'csp' as const; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts index 71360860a4f6e..e6544836e2679 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts @@ -69,7 +69,6 @@ export const getRulesV2BaseKibanaFeature = ( ), order: 1100, category: DEFAULT_APP_CATEGORIES.security, - // scope: [KibanaFeatureScope.Spaces, KibanaFeatureScope.Security], app: [RULES_FEATURE_ID_V2, 'kibana'], catalogue: [APP_ID], alerting: alertingFeatures, diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts index d029d9f163a65..92a8b91df9a4c 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts @@ -16,6 +16,8 @@ import { EXCEPTIONS_SUBFEATURE_ID_READ, LISTS_API_ALL, LISTS_API_READ, + EXCEPTIONS_UI_READ, + EXCEPTIONS_UI_CRUD, } from '../../constants'; import type { SecurityFeatureParams } from '../security/types'; @@ -60,7 +62,7 @@ export const getExceptionsSubFeaturesMap = ( all: savedObjects, read: savedObjects, }, - ui: ['readExceptions', 'crudExceptions'], + ui: [EXCEPTIONS_UI_READ, EXCEPTIONS_UI_CRUD], api: [EXCEPTIONS_API_READ, EXCEPTIONS_API_ALL, LISTS_API_ALL, LISTS_API_READ], }, { @@ -72,7 +74,7 @@ export const getExceptionsSubFeaturesMap = ( all: [], read: savedObjects, }, - ui: ['readExceptions'], + ui: [EXCEPTIONS_UI_READ], api: [EXCEPTIONS_API_READ, LISTS_API_READ], }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx index ac89eaa438ed9..38a823518af01 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/components/user_privileges/user_privileges_context.tsx @@ -7,14 +7,18 @@ import React, { createContext, useMemo } from 'react'; import type { Capabilities } from '@kbn/core/types'; -import { RULES_UI_EDIT, RULES_UI_READ } from '@kbn/security-solution-features/constants'; -import { SECURITY_FEATURE_ID, RULES_FEATURE_ID } from '../../../../common/constants'; +import { SECURITY_FEATURE_ID } from '../../../../common/constants'; import { useFetchListPrivileges } from '../../../detections/components/user_privileges/use_fetch_list_privileges'; import { useFetchDetectionEnginePrivileges } from '../../../detections/components/user_privileges/use_fetch_detection_engine_privileges'; import { getEndpointPrivilegesInitialState, useEndpointPrivileges } from './endpoint'; import type { EndpointPrivileges } from '../../../../common/endpoint/types'; import { extractTimelineCapabilities } from '../../utils/timeline_capabilities'; import { extractNotesCapabilities } from '../../utils/notes_capabilities'; +import type { RulesUICapabilities } from '../../utils/rules_capabilities'; +import { + extractRulesCapabilities, + getRulesCapabilitiesInitialState, +} from '../../utils/rules_capabilities'; export interface UserPrivilegesState { listPrivileges: ReturnType; @@ -23,7 +27,7 @@ export interface UserPrivilegesState { siemPrivileges: { crud: boolean; read: boolean }; timelinePrivileges: { crud: boolean; read: boolean }; notesPrivileges: { crud: boolean; read: boolean }; - rulesPrivileges: { read: boolean; edit: boolean }; + rulesPrivileges: RulesUICapabilities; } export const initialUserPrivilegesState = (): UserPrivilegesState => ({ @@ -33,7 +37,7 @@ export const initialUserPrivilegesState = (): UserPrivilegesState => ({ siemPrivileges: { crud: false, read: false }, timelinePrivileges: { crud: false, read: false }, notesPrivileges: { crud: false, read: false }, - rulesPrivileges: { read: false, edit: false }, + rulesPrivileges: getRulesCapabilitiesInitialState(), }); export const UserPrivilegesContext = createContext( initialUserPrivilegesState() @@ -51,11 +55,11 @@ export const UserPrivilegesProvider = ({ const crud: boolean = kibanaCapabilities[SECURITY_FEATURE_ID].crud === true; const read: boolean = kibanaCapabilities[SECURITY_FEATURE_ID].show === true; - const rulesCapabilities = kibanaCapabilities[RULES_FEATURE_ID]; - const readRules = rulesCapabilities?.[RULES_UI_READ] === true; - const editRules = rulesCapabilities?.[RULES_UI_EDIT] === true; - - const shouldFetchListPrivileges = read || readRules; + const rulesPrivileges = useMemo( + () => extractRulesCapabilities(kibanaCapabilities), + [kibanaCapabilities] + ); + const shouldFetchListPrivileges = read || rulesPrivileges.rules.read; const listPrivileges = useFetchListPrivileges(shouldFetchListPrivileges); const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(); @@ -79,13 +83,6 @@ export const UserPrivilegesProvider = ({ [kibanaCapabilities] ); - const rulesPrivileges = useMemo(() => { - return { - read: readRules, - edit: editRules, - }; - }, [readRules, editRules]); - const contextValue = useMemo( () => ({ listPrivileges, diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx index 789564eea1646..450f62d17a09f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.test.tsx @@ -113,7 +113,10 @@ describe('useMissingPrivileges', () => { it('reports missing rulesPrivileges if user cannot edit rules', () => { (useUserPrivileges as jest.Mock).mockReturnValue( buildUseUserPrivilegesMockReturn({ - rulesPrivileges: { edit: false, read: true }, + rulesPrivileges: { + rules: { edit: false, read: true }, + exceptions: { crud: false, read: true }, + }, }) ); @@ -154,7 +157,10 @@ describe('useMissingPrivileges', () => { it('reports no missing rule privileges if user can edit rules', () => { (useUserPrivileges as jest.Mock).mockReturnValue( buildUseUserPrivilegesMockReturn({ - rulesPrivileges: { edit: true, read: true }, + rulesPrivileges: { + rules: { edit: true, read: true }, + exceptions: { crud: true, read: true }, + }, }) ); diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts index 829c3ea293bca..ddb6cf93e939f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts @@ -65,7 +65,7 @@ export const useMissingPrivileges = (): MissingPrivileges => { }; } - if (rulesPrivileges.edit === false) { + if (rulesPrivileges.rules.edit === false) { featurePrivileges.push([RULES_FEATURE_ID_V2, ['all']]); } @@ -90,5 +90,5 @@ export const useMissingPrivileges = (): MissingPrivileges => { featurePrivileges, indexPrivileges, }; - }, [listPrivileges.result, detectionEnginePrivileges.result, rulesPrivileges.edit]); + }, [listPrivileges.result, detectionEnginePrivileges.result, rulesPrivileges.rules.edit]); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/utils/rules_capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/common/utils/rules_capabilities.ts new file mode 100644 index 0000000000000..31338dd1f1f78 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/common/utils/rules_capabilities.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Capabilities } from '@kbn/core/types'; +import { + EXCEPTIONS_UI_CRUD, + EXCEPTIONS_UI_READ, + RULES_UI_EDIT, + RULES_UI_READ, +} from '@kbn/security-solution-features/constants'; +import { RULES_FEATURE_ID } from '../../../common/constants'; + +export interface RulesUICapabilities { + rules: { read: boolean; edit: boolean }; + exceptions: { read: boolean; crud: boolean }; +} + +export const getRulesCapabilitiesInitialState = () => ({ + rules: { read: false, edit: false }, + exceptions: { read: false, crud: false }, +}); + +export const extractRulesCapabilities = (capabilities: Capabilities): RulesUICapabilities => { + const rulesCapabilities = capabilities[RULES_FEATURE_ID]; + + // Rules permissions + const readRules = rulesCapabilities?.[RULES_UI_READ] === true; + const editRules = rulesCapabilities?.[RULES_UI_EDIT] === true; + + // Exceptions permissions + const readExceptions = rulesCapabilities?.[EXCEPTIONS_UI_READ] === true; + const crudExceptions = rulesCapabilities?.[EXCEPTIONS_UI_CRUD] === true; + + return { + rules: { read: readRules, edit: editRules }, + exceptions: { read: readExceptions, crud: crudExceptions }, + }; +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx index fe56f9649c0fc..627f315c227ca 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/configurations/tabs/promotion_rules/promotion_rules_table.tsx @@ -176,7 +176,7 @@ interface ColumnsProps { } const useRulesColumns = ({ currentTab }: ColumnsProps): Array> => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const enabledColumn = useEnabledColumn({ hasCRUDPermissions: canEditRules, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index dc8fbca698ab1..5c37e662928bd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -113,7 +113,7 @@ MyEuiPanel.displayName = 'MyEuiPanel'; const CreateRulePageComponent: React.FC = () => { const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = useUserData(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { addSuccess } = useAppToasts(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index d008012202c07..ac1bc25ffb71f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -82,7 +82,7 @@ const EditRulePageComponent: FC<{ rule: RuleResponse }> = ({ rule }) => { useUserData(); const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { application, triggersActionsUi } = useKibana().services; const { navigateToApp } = application; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 6e615cf940f3b..23c3cf3bfb650 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -264,7 +264,7 @@ export const RuleDetailsPage = connector( hasIndexMaintenance, }, ] = useUserData(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx index e28af784f38ee..44707286f306a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx @@ -64,7 +64,7 @@ describe('RuleActionsOverflow', () => { }); (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { rules: { read: true, edit: true } }, }); }); describe('rules details menu panel', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx index 89d717f0380c3..78230317d575a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx @@ -81,7 +81,7 @@ const RuleActionsOverflowComponent = ({ const { bulkExport } = useBulkExport(); const downloadExportedRules = useDownloadExportedRules(); const { scheduleRuleRun } = useScheduleRuleRun(); - const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges.rules; const onRuleDeletedCallback = useCallback(() => { navigateToApp(APP_UI_ID, { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx index 3c6d0a78ed1ce..af8f9210560c3 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx @@ -99,7 +99,7 @@ const ExceptionsViewerComponent = ({ const { services } = useKibana(); const toasts = useToasts(); const [{ hasIndexWrite }] = useUserData(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canCrudExceptions = useUserPrivileges().rulesPrivileges.exceptions.crud; const exceptionListsToQuery = useMemo( () => rule != null && rule.exceptions_list != null @@ -461,8 +461,8 @@ const ExceptionsViewerComponent = ({ // User privileges checks useEffect((): void => { - setReadOnly(isViewReadOnly || !canEditRules || !hasIndexWrite); - }, [setReadOnly, isViewReadOnly, hasIndexWrite, canEditRules]); + setReadOnly(isViewReadOnly || !canCrudExceptions || !hasIndexWrite); + }, [setReadOnly, isViewReadOnly, hasIndexWrite, canCrudExceptions]); useEffect(() => { if (exceptionListsToQuery.length > 0) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx index e8ea87a747509..bfe10645acee1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_backfills_info/index.tsx @@ -135,7 +135,7 @@ const getBackfillsTableColumns = (canEditRules: boolean) => { export const RuleBackfillsInfo = React.memo<{ ruleId: string }>(({ ruleId }) => { const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { timelines } = useKibana().services; const { data, isLoading, isError, refetch, dataUpdatedAt } = useFindBackfillsForRules({ ruleIds: [ruleId], diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx index 13419eec26fda..24ec4581bca9b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_gaps/components/rule_gaps/index.tsx @@ -176,7 +176,7 @@ export const RuleGaps = ({ ruleId, enabled }: { ruleId: string; enabled: boolean end: 'now', }); const { timelines } = useKibana().services; - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const [refreshInterval, setRefreshInterval] = useState(1000); const [isPaused, setIsPaused] = useState(true); const [selectedStatuses, setSelectedStatuses] = useState([]); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx index 139a59c14c8a7..c4bf11ce80365 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/components/rule_snooze_badge/rule_snooze_badge.tsx @@ -26,7 +26,7 @@ export function RuleSnoozeBadge({ }: RuleSnoozeBadgeProps): JSX.Element { const RulesListNotifyBadge = useKibana().services.triggersActionsUi.getRulesListNotifyBadge; const { snoozeSettings, error } = useRuleSnoozeSettings(ruleId); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const invalidateFetchRuleSnoozeSettings = useInvalidateFetchRulesSnoozeSettingsQuery(); return ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx index 7cdece866adf6..d711cf5164c74 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_rule_update_callout.tsx @@ -23,7 +23,7 @@ export const useRuleUpdateCallout = ({ actionButton, onUpgrade, }: UseRuleUpdateCalloutProps): JSX.Element | null => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; return !rule || rule.rule_source.type !== 'external' || !canEditRules ? null : ( { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; return ( { }, actions: { installAllRules, installSelectedRules }, } = useAddPrebuiltRulesTableContext(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const numberOfSelectedRules = selectedRules.length ?? 0; const shouldDisplayInstallSelectedRulesButton = numberOfSelectedRules > 0; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx index ce219280fb464..4ff239aaa7bfa 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table.test.tsx @@ -103,7 +103,10 @@ describe('AddPrebuiltRulesTable', () => { it('disables `Install all` button if user has no write permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: false }, + }, }); render( @@ -124,7 +127,10 @@ describe('AddPrebuiltRulesTable', () => { it('disables `Install all` button if prebuilt package is being installed', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: true }, + }, }); (useIsUpgradingSecurityPackages as jest.Mock).mockReturnValueOnce(true); @@ -147,7 +153,10 @@ describe('AddPrebuiltRulesTable', () => { it('enables Install all` button when user has permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: true }, + }, }); render( @@ -173,7 +182,10 @@ describe('AddPrebuiltRulesTable', () => { async (_permissions, canEdit) => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: canEdit }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: canEdit }, + }, }); (usePrebuiltRulesInstallReview as jest.Mock).mockReturnValueOnce({ @@ -210,7 +222,10 @@ describe('AddPrebuiltRulesTable', () => { it('does not render `Install rule` on rule rows for users with no write permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: false }, + }, }); const id = 'rule-1'; @@ -258,7 +273,10 @@ describe('AddPrebuiltRulesTable', () => { it('renders `Install rule` on rule rows for users with write permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: true }, + }, }); const id = 'rule-1'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx index 66458f795da19..a0dbc806636dd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/add_prebuilt_rules_table_context.tsx @@ -112,7 +112,7 @@ export const AddPrebuiltRulesTableContextProvider = ({ const [loadingRules, setLoadingRules] = useState([]); const [selectedRules, setSelectedRules] = useState([]); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const [filterOptions, setFilterOptions] = useState({ filter: '', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx index c27d94b2d784c..47a428c6eb489 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx @@ -127,7 +127,7 @@ const createInstallButtonColumn = ( }); export const useAddPrebuiltRulesTableColumns = (): TableColumn[] => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const [showRelatedIntegrations] = useUiSetting$(SHOW_RELATED_INTEGRATIONS_SETTING); const { state: { loadingRules, isRefetching, isUpgradingSecurityPackages, isInstallingAllRules }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx index bbd1cf682cf19..87c59ec6e464f 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx @@ -77,7 +77,7 @@ export const RuleFeatureTour: FC = () => { }, [tourState, storage]); const isTourAnchorMounted = useIsElementMounted(CREATE_NEW_RULE_TOUR_ANCHOR); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; // Display the tour only if the user has permissions to create/edit rules, // otherwise they could not follow the tour steps const shouldShowRuleUpgradeTour = isTourAnchorMounted && canEditRules; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx index c2b62d8d9457e..77b97df6fd4a6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx @@ -28,7 +28,7 @@ export const RulesTableToolbar = React.memo(() => { const { data: ruleManagementFilters } = useRuleManagementFilters(); const { data: prebuiltRulesStatus } = usePrebuiltRulesStatus(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const installedTotal = (ruleManagementFilters?.rules_summary.custom_count ?? 0) + diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx index faab5590007a1..acb254d9f92d6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx @@ -74,7 +74,7 @@ const NO_ITEMS_MESSAGE = ( export const RulesTables = React.memo(({ selectedTab }) => { const modalTitleId = useGeneratedHtmlId(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages(); const rulesTableContext = useRulesTableContext(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx index b8991fb3eac13..f7e9c531f0d3c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/upgrade_prebuilt_rules_table_buttons.tsx @@ -25,7 +25,7 @@ export const UpgradePrebuiltRulesTableButtons = ({ actions: { upgradeRules, upgradeAllRules }, } = useUpgradePrebuiltRulesTableContext(); const { isRulesCustomizationEnabled } = usePrebuiltRulesCustomizationStatus(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const numberOfSelectedRules = selectedRules.length ?? 0; const shouldDisplayUpgradeSelectedRulesButton = numberOfSelectedRules > 0; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx index c405e4763e4d2..5acfcf615e2e8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx @@ -241,7 +241,7 @@ const createUpgradeButtonColumn = ( }); export const useUpgradePrebuiltRulesTableColumns = (): TableColumn[] => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const [showRelatedIntegrations] = useUiSetting$(SHOW_RELATED_INTEGRATIONS_SETTING); const { state: { loadingRules, isRefetching, isUpgradingSecurityPackages }, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx index 44b1efa3bbcee..18f1778f44ac6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx @@ -39,7 +39,10 @@ describe('CoverageOverviewMitreTechniquePanelPopover', () => { }); (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: true }, + }, }); }); @@ -114,7 +117,10 @@ describe('CoverageOverviewMitreTechniquePanelPopover', () => { test('"Enable all disabled" button is disabled when user does not have CRUD permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + rules: { read: true, edit: false }, + }, }); const wrapper = renderTechniquePanelPopover(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx index 2e478ad1f5a7b..95088e5cda8d8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx @@ -37,7 +37,7 @@ export interface CoverageOverviewMitreTechniquePanelPopoverProps { const CoverageOverviewMitreTechniquePanelPopoverComponent = ({ technique, }: CoverageOverviewMitreTechniquePanelPopoverProps) => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const closePopover = useCallback(() => setIsPopoverOpen(false), []); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index 6a1803e3e0e6b..76cfbe47549e6 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -47,7 +47,7 @@ const RulesPageComponent: React.FC = () => { const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = useUserData(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { loading: listsConfigLoading, canWriteIndex: canWriteListsIndex, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx index 19c37ee462796..3d90767059150 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx @@ -28,7 +28,7 @@ describe('useAlertExceptionActions', () => { it('should return both add rule exception and add endpoint exception menu items with all privileges', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -47,7 +47,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding endpoint exceptions when user has no endpoint exceptions ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -66,7 +66,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding endpoint exceptions when alert is not an endpoint alert', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -86,7 +86,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding rule exceptions when user has no security:ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: false } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: false } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -105,7 +105,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding rule exceptions when user has no index write privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -124,7 +124,7 @@ describe('useAlertExceptionActions', () => { it('should not return menu items when user has neither security:ALL nor endpoint exceptions ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: false } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: false } } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -137,7 +137,7 @@ describe('useAlertExceptionActions', () => { it('should not return menu items when user has neither index write and it is not an endpoint alert', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { edit: true } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx index 4c28358df6848..71bcaa6e4f1b1 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.tsx @@ -23,7 +23,7 @@ export const useAlertExceptionActions = ({ isEndpointAlert, onAddExceptionTypeClick, }: UseExceptionActionProps) => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canCrudExceptions = useUserPrivileges().rulesPrivileges.exceptions.crud; const [{ hasIndexWrite }] = useUserData(); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); @@ -36,7 +36,7 @@ export const useAlertExceptionActions = ({ }, [onAddExceptionTypeClick]); const disabledAddEndpointException = !canWriteEndpointExceptions || !isEndpointAlert; - const disabledAddException = !canEditRules || !hasIndexWrite; + const disabledAddException = !canCrudExceptions || !hasIndexWrite; const exceptionActionItems: AlertTableContextMenuItem[] = useMemo( () => diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx index 3b88e5b50ad51..627f800355d6b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/lists/use_lists_privileges.tsx @@ -57,7 +57,10 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { canWriteIndex: null, }); - const { listPrivileges, rulesPrivileges } = useUserPrivileges(); + const { + listPrivileges, + rulesPrivileges: { rules }, + } = useUserPrivileges(); // handleReadResult useEffect(() => { @@ -72,16 +75,12 @@ export const useListsPrivileges = (): UseListsPrivilegesReturn => { isAuthenticated, canReadIndex: canReadIndex(listsPrivileges) && canReadIndex(listItemsPrivileges), canManageIndex: - rulesPrivileges.edit && - canManageIndex(listsPrivileges) && - canManageIndex(listItemsPrivileges), + rules.edit && canManageIndex(listsPrivileges) && canManageIndex(listItemsPrivileges), canWriteIndex: - rulesPrivileges.edit && - canWriteIndex(listsPrivileges) && - canWriteIndex(listItemsPrivileges), + rules.edit && canWriteIndex(listsPrivileges) && canWriteIndex(listItemsPrivileges), }); } - }, [listPrivileges.result, rulesPrivileges.edit]); + }, [listPrivileges.result, rules.edit]); // handleReadError useEffect(() => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx index ca068a9397376..48f60c7eb5b5a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.test.tsx @@ -31,8 +31,10 @@ jest.mock('../../components/alerts/wrapper', () => ({ const doMockRulesPrivileges = ({ read = false }) => { (useUserPrivileges as jest.Mock).mockReturnValue({ rulesPrivileges: { - read, - edit: false, + rules: { + read, + edit: false, + }, }, }); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx index 8fd6acbd9e20c..1a4597be642e7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/alerts/alerts.tsx @@ -31,7 +31,7 @@ export const ALERTS_PAGE_LOADING_TEST_ID = 'alerts-page-loading'; */ export const AlertsPage = memo(() => { const [{ loading: userInfoLoading, isAuthenticated, hasIndexRead }] = useUserData(); - const canReadAlerts = useUserPrivileges().rulesPrivileges.read; + const canReadAlerts = useUserPrivileges().rulesPrivileges.rules.read; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { signalIndexNeedsInit } = useSignalHelpers(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx index f3a8c389c097a..fa169f5b31021 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.test.tsx @@ -31,8 +31,10 @@ jest.mock('../../components/attacks/wrapper', () => ({ const doMockRulesPrivileges = ({ read = false }) => { (useUserPrivileges as jest.Mock).mockReturnValue({ rulesPrivileges: { - read, - edit: false, + rules: { + read, + edit: false, + }, }, }); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx index 24d94de8847b3..ff9c125e25e06 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/pages/attacks/attacks.tsx @@ -31,7 +31,7 @@ export const ATTACKS_PAGE_LOADING_TEST_ID = 'attacks-page-loading'; */ export const AttacksPage = memo(() => { const [{ loading: userInfoLoading, isAuthenticated, hasIndexRead }] = useUserData(); - const canReadAlerts = useUserPrivileges().rulesPrivileges.read; + const canReadAlerts = useUserPrivileges().rulesPrivileges.rules.read; const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = useListsConfig(); const { signalIndexNeedsInit } = useSignalHelpers(); diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx index e56d31f24fbcb..00d0bf8e71b49 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx @@ -71,6 +71,9 @@ export const useExceptionsListCard = ({ const [showEditExceptionFlyout, setShowEditExceptionFlyout] = useState(false); const [showIncludeExpiredExceptionsModal, setShowIncludeExpiredExceptionsModal] = useState(null); + // TODO: test with endpoint exceptions + // const { read: canReadExceptions, crud: canCrudExceptions } = + // useUserPrivileges().rulesPrivileges.exceptions; const { name: listName, @@ -117,7 +120,7 @@ export const useExceptionsListCard = ({ const [toggleAccordion, setToggleAccordion] = useState(false); const openAccordionId = useGeneratedHtmlId({ prefix: 'openAccordion' }); - const listCannotBeEdited = checkIfListCannotBeEdited(exceptionsList); + const listCannotBeEdited = checkIfListCannotBeEdited(exceptionsList); // TODO: test with endpoint exceptions || !canCrudExceptions; const emptyViewerTitle = useMemo(() => { return viewerStatus === ViewerStatus.EMPTY ? i18n.EXCEPTION_LIST_EMPTY_VIEWER_TITLE : ''; @@ -154,6 +157,7 @@ export const useExceptionsListCard = ({ setShowIncludeExpiredExceptionsModal(CHECK_EXCEPTION_TTL_ACTION_TYPES.EXPORT); } }, + // disabled: !canReadExceptions, // TODO: test this with endpoint exceptions usage }, { key: 'Duplicate', @@ -188,6 +192,7 @@ export const useExceptionsListCard = ({ }, ], [ + // canReadExceptions, listCannotBeEdited, listType, handleExport, diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts index adca7eeb4f237..8d03432bc6c6a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts @@ -54,13 +54,14 @@ export const useListDetailsView = (exceptionListId: string) => { const { navigateToApp } = services.application; const { exportExceptionList, deleteExceptionList, duplicateExceptionList } = useApi(http); - const { read: canReadRules, edit: canEditRules } = useUserPrivileges().rulesPrivileges; + const { read: canReadExceptions, crud: canCrudExceptions } = + useUserPrivileges().rulesPrivileges.exceptions; const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); const canUserWriteCurrentList = exceptionListId === ENDPOINT_ARTIFACT_LISTS.endpointExceptions.id ? canWriteEndpointExceptions - : canEditRules; + : canCrudExceptions; const [isLoading, setIsLoading] = useState(); const [showManageButtonLoader, setShowManageButtonLoader] = useState(false); @@ -411,12 +412,12 @@ export const useListDetailsView = (exceptionListId: string) => { return { isLoading, invalidListId, - isReadOnly: !!(!canUserWriteCurrentList && canReadRules), + isReadOnly: !!(!canUserWriteCurrentList && canReadExceptions), list, listName: list?.name, listDescription: list?.description, listId: exceptionListId, - canUserEditList, + canUserEditList: canUserEditList && canCrudExceptions, linkedRules, exportedList, handleOnDownload, diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx index 0b9d71e243c8e..58567c377af2d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx @@ -86,7 +86,8 @@ const ExceptionsTable = styled(EuiFlexGroup)` `; export const SharedLists = React.memo(() => { - const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { crud: canCrudExceptions, read: canReadExceptions } = + useUserPrivileges().rulesPrivileges.exceptions; const { loading: listsConfigLoading } = useListsConfig(); const loading = listsConfigLoading; @@ -445,7 +446,7 @@ export const SharedLists = React.memo(() => { }; const onCreateExceptionListOpenClick = () => setDisplayCreateSharedListFlyout(true); - const isReadOnly = canReadRules && !canEditRules; + const isReadOnly = canReadExceptions && !canCrudExceptions; useEffect(() => { if (isSearchingExceptions && hasNoExceptions) { @@ -529,7 +530,7 @@ export const SharedLists = React.memo(() => { ]} /> , - (!isReadOnly || canWriteEndpointExceptions) && ( + (canCrudExceptions || canWriteEndpointExceptions) && ( { it('renders overflow card button as disabled if user is read only', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { + rules: { read: true, edit: false }, + exceptions: { read: true, crud: false }, + }, }); const wrapper = render( diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx index c99bdd13f1b4d..2694f7dba0d74 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.test.tsx @@ -41,7 +41,7 @@ describe('useHighlightedFieldsPrivilege', () => { jest.clearAllMocks(); (useUserPrivileges as jest.Mock).mockReturnValue({ ...getUserPrivilegesMockDefaultValue(), - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { rules: { read: true, edit: true } }, }); (hasMlAdminPermissions as jest.Mock).mockReturnValue(false); (hasMlLicense as jest.Mock).mockReturnValue(false); @@ -71,7 +71,7 @@ describe('useHighlightedFieldsPrivilege', () => { it('should return isDisabled as true when user does not have CRUD privileges', () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...getUserPrivilegesMockDefaultValue(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { rules: { read: true, edit: false } }, }); const { result } = renderUseHighlightedFieldsPrivilege(defaultProps); expect(result.current.isDisabled).toBe(true); diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx index d9d73d47edef1..e56acb0944138 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/hooks/use_highlighted_fields_privilege.tsx @@ -45,7 +45,7 @@ export const useHighlightedFieldsPrivilege = ({ rule, isExistingRule, }: UseHighlightedFieldsPrivilegeParams): UseHighlightedFieldsPrivilegeResult => { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const mlCapabilities = useMlCapabilities(); const hasMlPermissions = hasMlLicense(mlCapabilities) && hasMlAdminPermissions(mlCapabilities); diff --git a/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts b/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts index 018fb479a2ae0..6c41c2ca015d8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/use_readonly_header.ts @@ -17,11 +17,11 @@ import { useUserPrivileges } from './common/components/user_privileges'; * privileges */ export function useReadonlyHeader(tooltip: string) { - const { rulesPrivileges } = useUserPrivileges(); + const { read, edit } = useUserPrivileges().rulesPrivileges.rules; const chrome = useKibana().services.chrome; useEffect(() => { - if (rulesPrivileges.read && !rulesPrivileges.edit) { + if (read && !edit) { chrome.setBadge({ text: i18n.READ_ONLY_BADGE_TEXT, tooltip, @@ -33,5 +33,5 @@ export function useReadonlyHeader(tooltip: string) { return () => { chrome.setBadge(); }; - }, [chrome, tooltip, rulesPrivileges.read, rulesPrivileges.edit]); + }, [chrome, tooltip, read, edit]); } From 55f5afb2e3a2235d1a92720dc3b1cdc8f6a6e447 Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Wed, 19 Nov 2025 17:40:29 -0500 Subject: [PATCH 41/85] assign exception so management to subfeature --- .../packages/shared/kbn-es/src/serverless_resources/users | 2 +- .../shared/kbn-es/src/serverless_resources/users_roles | 1 + .../shared/alerting/server/rules_client/rules_client.ts | 5 +++++ .../packages/features/src/v2_rules/kibana_features.ts | 8 +++++--- .../packages/features/src/v2_rules/kibana_subfeatures.ts | 7 ++++--- .../product_features_service/product_features_service.ts | 7 ++++++- .../product_features_service/security_saved_objects.ts | 7 ++----- 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/users b/src/platform/packages/shared/kbn-es/src/serverless_resources/users index 4ed7023a64b1f..6704fc9f22783 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/users +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/users @@ -11,4 +11,4 @@ detections_admin:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW platform_engineer:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW endpoint_operations_analyst:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW endpoint_policy_manager:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW - +norules:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles b/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles index a4d6c1987ce6d..af70b19a9745d 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles @@ -10,3 +10,4 @@ detections_admin:detections_admin platform_engineer:platform_engineer endpoint_operations_analyst:endpoint_operations_analyst endpoint_policy_manager:endpoint_policy_manager +norules:norules diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/rules_client.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/rules_client.ts index f72593d94883a..f61ac4e29db2d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/rules_client.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/rules_client.ts @@ -190,6 +190,11 @@ export class RulesClient { bulkDeleteRules(this.context, options); public bulkEdit = (options: BulkEditOptions) => bulkEditRules(this.context, options); + /** + * For use by the security solution + * @param options + * @returns + */ public bulkEditRuleParamsWithReadAuth = ( options: BulkEditRuleParamsOptions ) => bulkEditRuleParamsWithReadAuth(this.context, options); diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts index 71360860a4f6e..c6af946a30274 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts @@ -18,6 +18,8 @@ import { THRESHOLD_RULE_TYPE_ID, NEW_TERMS_RULE_TYPE_ID, } from '@kbn/securitysolution-rules'; +import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; + import { ALERTS_API_ALL, ALERTS_API_READ, @@ -81,8 +83,8 @@ export const getRulesV2BaseKibanaFeature = ( app: [RULES_FEATURE_ID_V2, 'kibana'], catalogue: [APP_ID], savedObject: { - all: params.savedObjects, - read: params.savedObjects, + all: params.savedObjects.filter((so) => so !== EXCEPTION_LIST_NAMESPACE), + read: params.savedObjects.filter((so) => so !== EXCEPTION_LIST_NAMESPACE), }, alerting: { rule: { all: alertingFeatures }, @@ -112,7 +114,7 @@ export const getRulesV2BaseKibanaFeature = ( catalogue: [APP_ID], savedObject: { all: [], - read: params.savedObjects, + read: params.savedObjects.filter((so) => so !== EXCEPTION_LIST_NAMESPACE), }, alerting: { rule: { read: alertingFeatures }, diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts index d029d9f163a65..180782e887388 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; import { APP_ID, EXCEPTIONS_API_READ, @@ -57,8 +58,8 @@ export const getExceptionsSubFeaturesMap = ( includeIn: 'all', name: TRANSLATIONS.all, savedObject: { - all: savedObjects, - read: savedObjects, + all: [EXCEPTION_LIST_NAMESPACE], + read: [EXCEPTION_LIST_NAMESPACE], }, ui: ['readExceptions', 'crudExceptions'], api: [EXCEPTIONS_API_READ, EXCEPTIONS_API_ALL, LISTS_API_ALL, LISTS_API_READ], @@ -70,7 +71,7 @@ export const getExceptionsSubFeaturesMap = ( catalogue: [APP_ID], savedObject: { all: [], - read: savedObjects, + read: [EXCEPTION_LIST_NAMESPACE], }, ui: ['readExceptions'], api: [EXCEPTIONS_API_READ, LISTS_API_READ], diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts index d0ab1140969ea..2d1f9ec8a8b9f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.ts @@ -33,6 +33,8 @@ import { ProductFeatures } from './product_features'; import { casesProductFeatureParams } from './cases_product_feature_params'; import { rulesSavedObjects, + rulesV2SavedObjects, + securityExceptionsSavedObjects, securityNotesSavedObjects, securityTimelineSavedObjects, securityV1SavedObjects, @@ -83,7 +85,10 @@ export class ProductFeaturesService { ]); this.productFeaturesRegistry.create('rules', [ getRulesFeature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), - getRulesV2Feature({ ...securityFeatureParams, savedObjects: rulesSavedObjects }), + getRulesV2Feature({ + ...securityFeatureParams, + savedObjects: [...rulesV2SavedObjects, ...securityExceptionsSavedObjects], + }), ]); if (!experimentalFeatures.siemMigrationsDisabled) { this.productFeaturesRegistry.create('siemMigrations', [getSiemMigrationsFeature()]); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts index 56379d5648861..a7fca677fde87 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/security_saved_objects.ts @@ -71,10 +71,7 @@ export const securityTimelineSavedObjects = timelineSavedObjectTypes; export const securityNotesSavedObjects = notesSavedObjectTypes; -export const rulesSavedObjects = [ - 'exception-list', - EXCEPTION_LIST_NAMESPACE_AGNOSTIC, - prebuiltRuleAssetType.name, -]; +export const rulesSavedObjects = ['exception-list', prebuiltRuleAssetType.name]; +export const rulesV2SavedObjects = [prebuiltRuleAssetType.name]; export const securityExceptionsSavedObjects = exceptionsSavedObjectTypes; From 60852d94221e00f5b64bfd3517c0f0b8a5825f0c Mon Sep 17 00:00:00 2001 From: Edgar Santos Date: Tue, 21 Oct 2025 14:09:54 +0200 Subject: [PATCH 42/85] update the siem migrations required permissions Instead of requiring siemVX read/all, it now requires securitySolutionRulesV1 read/all From 1068cbe85286f1366136b70b17f6f47c7640477e Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Thu, 23 Oct 2025 09:13:01 +0200 Subject: [PATCH 43/85] fix: siem migration privs --- .../common/service/capabilities.ts | 26 ++++++---------- .../common/service/migrations_service_base.ts | 30 +++++-------------- .../public/siem_migrations/links.ts | 11 +++++-- .../rules/service/capabilities.ts | 29 ++++++++++++++++++ .../rules/service/rule_migrations_service.ts | 21 +++++++++++++ 5 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts index d6e2803cba4db..348ddec9edf06 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts @@ -7,9 +7,8 @@ import type { Capabilities } from '@kbn/core/public'; import { - SIEM_MIGRATIONS_FEATURE_ID, RULES_UI_READ_PRIVILEGE, - RULES_UI_EDIT_PRIVILEGE, + SIEM_MIGRATIONS_FEATURE_ID, } from '@kbn/security-solution-features/constants'; import { i18n } from '@kbn/i18n'; import { CapabilitiesChecker } from '../../../common/lib/capabilities'; @@ -19,14 +18,7 @@ export interface MissingCapability { description: string; } -const minimumCapabilities: MissingCapability[] = [ - { - capability: RULES_UI_READ_PRIVILEGE, - description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', - { defaultMessage: 'Security > Rules: Read' } - ), - }, +const minimumSiemMigrationCapabilities: MissingCapability[] = [ { capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, description: i18n.translate( @@ -34,16 +26,16 @@ const minimumCapabilities: MissingCapability[] = [ { defaultMessage: 'Security > SIEM migrations: All' } ), }, -]; - -const allCapabilities: MissingCapability[] = [ { - capability: RULES_UI_EDIT_PRIVILEGE, + capability: RULES_UI_READ_PRIVILEGE, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', - { defaultMessage: 'Security > Rules: All' } + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', + { defaultMessage: 'Security > Rules: Read' } ), }, +]; + +const allCapabilities: MissingCapability[] = [ { capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, description: i18n.translate( @@ -65,7 +57,7 @@ export type CapabilitiesLevel = 'minimum' | 'all'; export type CapabilitiesByLevel = Record; export const requiredSiemMigrationCapabilities: CapabilitiesByLevel = { - minimum: minimumCapabilities, + minimum: minimumSiemMigrationCapabilities, all: allCapabilities, }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts index b4a8c0f57450b..2a57b00db6a15 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts @@ -17,13 +17,7 @@ import { import type { MigrationTaskStats } from '../../../../common/siem_migrations/model/common.gen'; import { SiemMigrationTaskStatus } from '../../../../common/siem_migrations/constants'; import type { StartPluginsDependencies } from '../../../types'; -import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; -import { licenseService } from '../../../common/hooks/use_license'; -import { - getMissingCapabilitiesChecker, - type MissingCapability, - type CapabilitiesLevel, -} from './capabilities'; +import { type MissingCapability, type CapabilitiesLevel } from './capabilities'; import { MigrationsStorage } from './storage'; import * as i18n from './translations'; import type { GetMigrationStatsParams, GetMigrationsStatsAllParams } from '../types'; @@ -39,6 +33,9 @@ export abstract class SiemMigrationsServiceBase { protected abstract fetchMigrationsStatsAll(params: GetMigrationsStatsAllParams): Promise; protected abstract sendFinishedMigrationNotification(taskStats: T): void; + public abstract isAvailable(): boolean; + public abstract getMissingCapabilities(level?: CapabilitiesLevel): MissingCapability[]; + private readonly latestStats$: BehaviorSubject; private isPolling = false; public connectorIdStorage: MigrationsStorage; @@ -58,7 +55,9 @@ export abstract class SiemMigrationsServiceBase { this.plugins.spaces.getActiveSpace().then((space) => { this.connectorIdStorage.setSpaceId(space.id); - this.startPolling(); + if (this.isAvailable()) { + this.startPolling(); + } }); } @@ -67,26 +66,11 @@ export abstract class SiemMigrationsServiceBase { return this.latestStats$.asObservable().pipe(distinctUntilChanged(isEqual)); } - /** Returns any missing capabilities for the user to use this feature */ - public getMissingCapabilities(level?: CapabilitiesLevel): MissingCapability[] { - const getMissingCapabilities = getMissingCapabilitiesChecker(); - return getMissingCapabilities(this.core.application.capabilities, level); - } - /** Checks if the user has any missing capabilities for this feature */ public hasMissingCapabilities(level?: CapabilitiesLevel): boolean { return this.getMissingCapabilities(level).length > 0; } - /** Checks if the service is available based on the `license`, `capabilities` and `experimentalFeatures` */ - public isAvailable() { - return ( - !ExperimentalFeaturesService.get().siemMigrationsDisabled && - licenseService.isEnterprise() && - !this.hasMissingCapabilities('minimum') - ); - } - /** Starts polling the migrations stats if not already polling and if the feature is available to the user */ public startPolling() { if (this.isPolling || !this.isAvailable()) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 2f316b860b64a..4182c76302637 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { RULES_UI_READ_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, SIEM_MIGRATIONS_FEATURE_ID, } from '@kbn/security-solution-features/constants'; import { @@ -49,7 +50,10 @@ const subLinks: LinkItem[] = [ ), landingIcon: IconDashboards, path: SIEM_MIGRATIONS_DASHBOARDS_PATH, - capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + // dashboard page will only show up is user has security show privilege so we need to include both + capabilities: [ + [`dashboardv2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + ], skipUrlState: true, hideTimeline: true, hideWhenExperimentalKey: 'siemMigrationsDisabled', @@ -69,7 +73,10 @@ export const links: LinkItem = { defaultMessage: 'Migrations', }), path: SIEM_MIGRATIONS_LANDING_PATH, - capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + capabilities: [ + [SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + [RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + ], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.migrations', { defaultMessage: 'Migrations', diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts new file mode 100644 index 0000000000000..8802dec99fab6 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { RULES_UI_EDIT_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { + requiredSiemMigrationCapabilities, + type CapabilitiesLevel, + type MissingCapability, +} from '../../common/service/capabilities'; + +const allRuleMigrationCapabilities: MissingCapability[] = [ + { + capability: RULES_UI_EDIT_PRIVILEGE, + description: i18n.translate( + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', + { defaultMessage: 'Security > Rules: All' } + ), + }, +]; + +export const requiredRuleMigrationCapabilities: Record = { + minimum: requiredSiemMigrationCapabilities.minimum, + all: [...requiredSiemMigrationCapabilities.all, ...allRuleMigrationCapabilities], +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts index 1de46051cd29c..ffc25106be281 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts @@ -6,6 +6,8 @@ */ import type { CoreStart } from '@kbn/core/public'; +import { licenseService } from '../../../common/hooks/use_license'; +import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; import type { TelemetryServiceStart } from '../../../common/lib/telemetry'; import type { CreateRuleMigrationRulesRequestBody, @@ -20,14 +22,17 @@ import * as api from '../api'; import type { RuleMigrationSettings, RuleMigrationStats } from '../types'; import * as i18n from './translations'; import { SiemRulesMigrationsTelemetry } from './telemetry'; +import type { CapabilitiesLevel, MissingCapability } from '../../common/service'; import { SiemMigrationsServiceBase, + getMissingCapabilitiesChecker, getMissingCapabilitiesToast, getNoConnectorToast, } from '../../common/service'; import type { GetMigrationStatsParams, GetMigrationsStatsAllParams } from '../../common/types'; import { raiseSuccessToast } from './notification/success_notification'; import { START_STOP_POLLING_SLEEP_SECONDS } from '../../common/constants'; +import { requiredRuleMigrationCapabilities } from './capabilities'; const CREATE_MIGRATION_BODY_BATCH_SIZE = 50; @@ -43,6 +48,22 @@ export class SiemRulesMigrationsService extends SiemMigrationsServiceBase Date: Thu, 23 Oct 2025 09:34:34 +0200 Subject: [PATCH 44/85] fix: tests --- .../service/migrations_service_base.test.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts index 0ec056998e1b7..333286d350dcb 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts @@ -16,10 +16,13 @@ import type { CoreStart } from '@kbn/core/public'; import { firstValueFrom } from 'rxjs'; import { SiemMigrationTaskStatus } from '../../../../common/siem_migrations/constants'; import type { StartPluginsDependencies } from '../../../types'; -import { getMissingCapabilitiesChecker } from './capabilities'; +import type { CapabilitiesLevel, MissingCapability } from './capabilities'; +import { getMissingCapabilitiesChecker, requiredSiemMigrationCapabilities } from './capabilities'; import { SiemMigrationsServiceBase } from './migrations_service_base'; import type { MigrationTaskStats } from '../../../../common/siem_migrations/model/common.gen'; import { TASK_STATS_POLLING_SLEEP_SECONDS } from '../constants'; +import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; +import { licenseService } from '../../../common/hooks/use_license'; // --- Mocks for external modules --- @@ -59,6 +62,21 @@ class TestMigrationsService extends SiemMigrationsServiceBase Date: Thu, 20 Nov 2025 17:01:48 -0600 Subject: [PATCH 45/85] fix: privilege requirements for Migrations components * Refactors MigrationServiceBase to defer certain method implementations to child classes * Migration Service does not _require_ `rules:read`, but it is an optional capability * Dashboard Migrations depend on `dashboard:show` AND `siemv5:show` * Rule Migrations depend on `rules:read` * Migrations Landing page depends on `rules:read` OR `siemv5:show` --- .../common/service/capabilities.ts | 24 +++++---------- .../common/service/migrations_service_base.ts | 30 +++++-------------- .../public/siem_migrations/links.ts | 11 +++++-- .../rules/service/capabilities.ts | 29 ++++++++++++++++++ .../rules/service/rule_migrations_service.ts | 21 +++++++++++++ 5 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts index d6e2803cba4db..60564866956dd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts @@ -9,7 +9,6 @@ import type { Capabilities } from '@kbn/core/public'; import { SIEM_MIGRATIONS_FEATURE_ID, RULES_UI_READ_PRIVILEGE, - RULES_UI_EDIT_PRIVILEGE, } from '@kbn/security-solution-features/constants'; import { i18n } from '@kbn/i18n'; import { CapabilitiesChecker } from '../../../common/lib/capabilities'; @@ -19,14 +18,7 @@ export interface MissingCapability { description: string; } -const minimumCapabilities: MissingCapability[] = [ - { - capability: RULES_UI_READ_PRIVILEGE, - description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', - { defaultMessage: 'Security > Rules: Read' } - ), - }, +const minimumSiemMigrationCapabilities: MissingCapability[] = [ { capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, description: i18n.translate( @@ -34,16 +26,16 @@ const minimumCapabilities: MissingCapability[] = [ { defaultMessage: 'Security > SIEM migrations: All' } ), }, -]; - -const allCapabilities: MissingCapability[] = [ { - capability: RULES_UI_EDIT_PRIVILEGE, + capability: RULES_UI_READ_PRIVILEGE, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', - { defaultMessage: 'Security > Rules: All' } + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', + { defaultMessage: 'Security > Rules: Read' } ), }, +]; + +const allCapabilities: MissingCapability[] = [ { capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, description: i18n.translate( @@ -65,7 +57,7 @@ export type CapabilitiesLevel = 'minimum' | 'all'; export type CapabilitiesByLevel = Record; export const requiredSiemMigrationCapabilities: CapabilitiesByLevel = { - minimum: minimumCapabilities, + minimum: minimumSiemMigrationCapabilities, all: allCapabilities, }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts index b4a8c0f57450b..2a57b00db6a15 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.ts @@ -17,13 +17,7 @@ import { import type { MigrationTaskStats } from '../../../../common/siem_migrations/model/common.gen'; import { SiemMigrationTaskStatus } from '../../../../common/siem_migrations/constants'; import type { StartPluginsDependencies } from '../../../types'; -import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; -import { licenseService } from '../../../common/hooks/use_license'; -import { - getMissingCapabilitiesChecker, - type MissingCapability, - type CapabilitiesLevel, -} from './capabilities'; +import { type MissingCapability, type CapabilitiesLevel } from './capabilities'; import { MigrationsStorage } from './storage'; import * as i18n from './translations'; import type { GetMigrationStatsParams, GetMigrationsStatsAllParams } from '../types'; @@ -39,6 +33,9 @@ export abstract class SiemMigrationsServiceBase { protected abstract fetchMigrationsStatsAll(params: GetMigrationsStatsAllParams): Promise; protected abstract sendFinishedMigrationNotification(taskStats: T): void; + public abstract isAvailable(): boolean; + public abstract getMissingCapabilities(level?: CapabilitiesLevel): MissingCapability[]; + private readonly latestStats$: BehaviorSubject; private isPolling = false; public connectorIdStorage: MigrationsStorage; @@ -58,7 +55,9 @@ export abstract class SiemMigrationsServiceBase { this.plugins.spaces.getActiveSpace().then((space) => { this.connectorIdStorage.setSpaceId(space.id); - this.startPolling(); + if (this.isAvailable()) { + this.startPolling(); + } }); } @@ -67,26 +66,11 @@ export abstract class SiemMigrationsServiceBase { return this.latestStats$.asObservable().pipe(distinctUntilChanged(isEqual)); } - /** Returns any missing capabilities for the user to use this feature */ - public getMissingCapabilities(level?: CapabilitiesLevel): MissingCapability[] { - const getMissingCapabilities = getMissingCapabilitiesChecker(); - return getMissingCapabilities(this.core.application.capabilities, level); - } - /** Checks if the user has any missing capabilities for this feature */ public hasMissingCapabilities(level?: CapabilitiesLevel): boolean { return this.getMissingCapabilities(level).length > 0; } - /** Checks if the service is available based on the `license`, `capabilities` and `experimentalFeatures` */ - public isAvailable() { - return ( - !ExperimentalFeaturesService.get().siemMigrationsDisabled && - licenseService.isEnterprise() && - !this.hasMissingCapabilities('minimum') - ); - } - /** Starts polling the migrations stats if not already polling and if the feature is available to the user */ public startPolling() { if (this.isPolling || !this.isAvailable()) { diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 2f316b860b64a..e015a13e6a651 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -8,6 +8,7 @@ import { i18n } from '@kbn/i18n'; import { RULES_UI_READ_PRIVILEGE, + SECURITY_UI_SHOW_PRIVILEGE, SIEM_MIGRATIONS_FEATURE_ID, } from '@kbn/security-solution-features/constants'; import { @@ -49,7 +50,10 @@ const subLinks: LinkItem[] = [ ), landingIcon: IconDashboards, path: SIEM_MIGRATIONS_DASHBOARDS_PATH, - capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + // dashboard page requires both the Security:Read and Dashboard:Read privileges + capabilities: [ + [`dashboard_v2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + ], skipUrlState: true, hideTimeline: true, hideWhenExperimentalKey: 'siemMigrationsDisabled', @@ -69,7 +73,10 @@ export const links: LinkItem = { defaultMessage: 'Migrations', }), path: SIEM_MIGRATIONS_LANDING_PATH, - capabilities: [[RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], + capabilities: [ + [SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + [RULES_UI_READ_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + ], globalSearchKeywords: [ i18n.translate('xpack.securitySolution.appLinks.migrations', { defaultMessage: 'Migrations', diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts new file mode 100644 index 0000000000000..8802dec99fab6 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { RULES_UI_EDIT_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { + requiredSiemMigrationCapabilities, + type CapabilitiesLevel, + type MissingCapability, +} from '../../common/service/capabilities'; + +const allRuleMigrationCapabilities: MissingCapability[] = [ + { + capability: RULES_UI_EDIT_PRIVILEGE, + description: i18n.translate( + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', + { defaultMessage: 'Security > Rules: All' } + ), + }, +]; + +export const requiredRuleMigrationCapabilities: Record = { + minimum: requiredSiemMigrationCapabilities.minimum, + all: [...requiredSiemMigrationCapabilities.all, ...allRuleMigrationCapabilities], +}; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts index 1de46051cd29c..ffc25106be281 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.ts @@ -6,6 +6,8 @@ */ import type { CoreStart } from '@kbn/core/public'; +import { licenseService } from '../../../common/hooks/use_license'; +import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; import type { TelemetryServiceStart } from '../../../common/lib/telemetry'; import type { CreateRuleMigrationRulesRequestBody, @@ -20,14 +22,17 @@ import * as api from '../api'; import type { RuleMigrationSettings, RuleMigrationStats } from '../types'; import * as i18n from './translations'; import { SiemRulesMigrationsTelemetry } from './telemetry'; +import type { CapabilitiesLevel, MissingCapability } from '../../common/service'; import { SiemMigrationsServiceBase, + getMissingCapabilitiesChecker, getMissingCapabilitiesToast, getNoConnectorToast, } from '../../common/service'; import type { GetMigrationStatsParams, GetMigrationsStatsAllParams } from '../../common/types'; import { raiseSuccessToast } from './notification/success_notification'; import { START_STOP_POLLING_SLEEP_SECONDS } from '../../common/constants'; +import { requiredRuleMigrationCapabilities } from './capabilities'; const CREATE_MIGRATION_BODY_BATCH_SIZE = 50; @@ -43,6 +48,22 @@ export class SiemRulesMigrationsService extends SiemMigrationsServiceBase Date: Thu, 20 Nov 2025 17:34:09 -0600 Subject: [PATCH 46/85] Fix types in test class implementation The previous commit made these part of the abstract class, so we need to define them here. --- .../common/service/migrations_service_base.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts index 0ec056998e1b7..5417c619af305 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts @@ -59,6 +59,11 @@ class TestMigrationsService extends SiemMigrationsServiceBase Date: Fri, 21 Nov 2025 05:28:26 +0100 Subject: [PATCH 47/85] fix: dashboard and rules privs --- .../common/service/capabilities.ts | 14 ++--------- .../dashboards/service/capabilities.ts | 9 +++++++- .../public/siem_migrations/links.ts | 2 +- .../rules/service/capabilities.ts | 23 +++++++++++++++---- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts index 348ddec9edf06..0eb194c7811c4 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/capabilities.ts @@ -6,10 +6,7 @@ */ import type { Capabilities } from '@kbn/core/public'; -import { - RULES_UI_READ_PRIVILEGE, - SIEM_MIGRATIONS_FEATURE_ID, -} from '@kbn/security-solution-features/constants'; +import { SIEM_MIGRATIONS_FEATURE_ID } from '@kbn/security-solution-features/constants'; import { i18n } from '@kbn/i18n'; import { CapabilitiesChecker } from '../../../common/lib/capabilities'; @@ -26,13 +23,6 @@ const minimumSiemMigrationCapabilities: MissingCapability[] = [ { defaultMessage: 'Security > SIEM migrations: All' } ), }, - { - capability: RULES_UI_READ_PRIVILEGE, - description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', - { defaultMessage: 'Security > Rules: Read' } - ), - }, ]; const allCapabilities: MissingCapability[] = [ @@ -56,7 +46,7 @@ export type CapabilitiesLevel = 'minimum' | 'all'; export type CapabilitiesByLevel = Record; -export const requiredSiemMigrationCapabilities: CapabilitiesByLevel = { +export const requiredSiemMigrationCapabilities = { minimum: minimumSiemMigrationCapabilities, all: allCapabilities, }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/dashboards/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/dashboards/service/capabilities.ts index a6b6eb6f42b7c..8034979c8194d 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/dashboards/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/dashboards/service/capabilities.ts @@ -12,6 +12,13 @@ import { type MissingCapability, } from '../../common/service/capabilities'; +const minimumDashboardMigrationCapability = { + capability: `dashboard_v2.show`, + description: i18n.translate( + 'xpack.securitySolution.siemMigrations.service.capabilities.dashboardsRead', + { defaultMessage: 'Analytics > Dashboards: Read' } + ), +}; const dashboardCapability = { capability: `dashboard_v2.createNew`, description: i18n.translate( @@ -24,6 +31,6 @@ export const requiredDashboardMigrationCapabilities: Record< CapabilitiesLevel, MissingCapability[] > = { - minimum: requiredSiemMigrationCapabilities.minimum, + minimum: [...requiredSiemMigrationCapabilities.minimum, minimumDashboardMigrationCapability], all: [...requiredSiemMigrationCapabilities.all, dashboardCapability], }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 4182c76302637..821de942c63b2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -52,7 +52,7 @@ const subLinks: LinkItem[] = [ path: SIEM_MIGRATIONS_DASHBOARDS_PATH, // dashboard page will only show up is user has security show privilege so we need to include both capabilities: [ - [`dashboardv2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], + [`dashboard_v2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], ], skipUrlState: true, hideTimeline: true, diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts index 8802dec99fab6..99c6c88eab421 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts @@ -6,7 +6,10 @@ */ import { i18n } from '@kbn/i18n'; -import { RULES_UI_EDIT_PRIVILEGE } from '@kbn/security-solution-features/constants'; +import { + RULES_UI_READ_PRIVILEGE, + SIEM_MIGRATIONS_FEATURE_ID, +} from '@kbn/security-solution-features/constants'; import { requiredSiemMigrationCapabilities, type CapabilitiesLevel, @@ -15,15 +18,25 @@ import { const allRuleMigrationCapabilities: MissingCapability[] = [ { - capability: RULES_UI_EDIT_PRIVILEGE, + capability: RULES_UI_READ_PRIVILEGE, + description: i18n.translate( + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesRead', + { defaultMessage: 'Security > Rules: Read' } + ), + }, +]; + +const minimumRuleMigrationCapabilities: MissingCapability[] = [ + { + capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', - { defaultMessage: 'Security > Rules: All' } + 'xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll', + { defaultMessage: 'Security > SIEM migrations: All' } ), }, ]; export const requiredRuleMigrationCapabilities: Record = { - minimum: requiredSiemMigrationCapabilities.minimum, + minimum: [...requiredSiemMigrationCapabilities.minimum, ...minimumRuleMigrationCapabilities], all: [...requiredSiemMigrationCapabilities.all, ...allRuleMigrationCapabilities], }; From 89f39fc099bdf1533961f1c6f18a88996e4458f2 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Fri, 21 Nov 2025 05:30:36 +0100 Subject: [PATCH 48/85] revert unncessary change --- .../plugins/security_solution/public/siem_migrations/links.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index 821de942c63b2..e015a13e6a651 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -50,7 +50,7 @@ const subLinks: LinkItem[] = [ ), landingIcon: IconDashboards, path: SIEM_MIGRATIONS_DASHBOARDS_PATH, - // dashboard page will only show up is user has security show privilege so we need to include both + // dashboard page requires both the Security:Read and Dashboard:Read privileges capabilities: [ [`dashboard_v2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], ], From b26ecf1bb59c030ac6ceafa7bc22cb9009493cc2 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Fri, 21 Nov 2025 11:01:51 -0500 Subject: [PATCH 49/85] lets shared exception list page be viewed with no rules/endpoint exceptions --- .../src/exception_item_card/meta/index.tsx | 24 ++++++++++--------- .../edit_exception_flyout/index.tsx | 6 +++-- .../use_add_to_lists_table.tsx | 16 ++++++++----- .../hooks/use_all_exception_lists/index.tsx | 23 +++++++++++------- .../hooks/use_list_detail_view/index.ts | 6 ++--- .../hooks/use_list_exception_items/index.ts | 6 +++-- .../exceptions/pages/shared_lists/index.tsx | 11 +++++---- .../security_solution/public/rules/links.ts | 3 ++- 8 files changed, 58 insertions(+), 37 deletions(-) diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx index f076d18f24217..8cf8343a2d271 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/exception_item_card/meta/index.tsx @@ -104,17 +104,19 @@ export const ExceptionItemCardMetaInfo = memo( )} )} - - - + {referencedLinks != null && ( + + + + )} ); } diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx index 8def74269dc40..d0c6bc0e7fdb4 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx @@ -39,6 +39,7 @@ import { import type { Moment } from 'moment'; import moment from 'moment'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; import { isEqlRule, isNewTermsRule, @@ -108,6 +109,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ const { isLoading, indexPatterns, getExtendedFields } = useFetchIndexPatterns(rules); const [isSubmitting, submitEditExceptionItems] = useEditExceptionItems(); const [isClosingAlerts, closeAlerts] = useCloseAlertsFromExceptions(); + const { read: canReadRules } = useUserPrivileges().rulesPrivileges; const [ { @@ -158,7 +160,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ useFindExceptionListReferences(); useEffect(() => { - if (fetchReferences != null) { + if (fetchReferences != null && canReadRules) { fetchReferences([ { id: list.id, @@ -167,7 +169,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ }, ]); } - }, [list, fetchReferences]); + }, [list, fetchReferences, canReadRules]); /** * Reducer action dispatchers diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx index 6d853e2718041..39b3a3d4dbe08 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx @@ -20,6 +20,7 @@ import type { import type { ExceptionListSchema, ListArray } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; import type { ExceptionListRuleReferencesSchema } from '../../../../../../common/api/detection_engine/rule_exceptions'; import { getExceptionItemsReferences } from '../../../../../exceptions/api'; import * as i18n from './translations'; @@ -48,6 +49,7 @@ export const useAddToSharedListTable = ({ }: ExceptionsAddToListsComponentProps) => { const [listsToDisplay, setListsToDisplay] = useState([]); const [isLoading, setIsLoading] = useState(false); + const { read: canReadRules } = useUserPrivileges().rulesPrivileges; const listsToFetch = useMemo(() => { return showAllSharedLists ? [] : sharedExceptionLists; @@ -67,15 +69,17 @@ export const useAddToSharedListTable = ({ const getReferences = useCallback(async () => { try { setIsLoading(true); - return getExceptionItemsReferences( - (!listsToFetch.length - ? [{ namespace_type: 'single' }] - : listsToFetch) as ExceptionListSchema[] - ); + return canReadRules + ? getExceptionItemsReferences( + (!listsToFetch.length + ? [{ namespace_type: 'single' }] + : listsToFetch) as ExceptionListSchema[] + ) + : {}; } catch (err) { setError(i18n.REFERENCES_FETCH_ERROR); } - }, [listsToFetch]); + }, [canReadRules, listsToFetch]); const fillListsToDisplay = useCallback(async () => { const result = (await getReferences()) as RuleReferences; diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_all_exception_lists/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_all_exception_lists/index.tsx index 36f7fc132cc84..3cbdec24dc543 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_all_exception_lists/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_all_exception_lists/index.tsx @@ -8,6 +8,7 @@ import { useCallback, useEffect, useState } from 'react'; import type { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import type { Rule } from '../../../detection_engine/rule_management/logic'; import { fetchRules } from '../../../detection_engine/rule_management/api/api'; export interface ExceptionListInfo extends ExceptionListSchema { @@ -39,6 +40,7 @@ export const useAllExceptionLists = ({ const [exceptionsListsInfo, setExceptionsListInfo] = useState>( {} ); + const { read: canReadRules } = useUserPrivileges().rulesPrivileges; const handleExceptionsInfo = useCallback( (rules: Rule[]): Record => { @@ -91,13 +93,18 @@ export const useAllExceptionLists = ({ try { setLoading(true); - const { data: rules } = await fetchRules({ - pagination: { - page: 1, - perPage: 10000, - }, - signal: abortCtrl.signal, - }); + const rules: Rule[] = []; + + if (canReadRules) { + const { data: rulesResponse } = await fetchRules({ + pagination: { + page: 1, + perPage: 10000, + }, + signal: abortCtrl.signal, + }); + rules.push(...rulesResponse); + } const updatedLists = handleExceptionsInfo(rules); @@ -124,7 +131,7 @@ export const useAllExceptionLists = ({ isSubscribed = false; abortCtrl.abort(); }; - }, [exceptionLists.length, handleExceptionsInfo]); + }, [canReadRules, exceptionLists.length, handleExceptionsInfo]); return [loading, exceptions, exceptionsListsInfo]; }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts index adca7eeb4f237..1fee270581b77 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_detail_view/index.ts @@ -112,11 +112,11 @@ export const useListDetailsView = (exceptionListId: string) => { const initializeListRules = useCallback( async (result: Awaited>) => { if (result) { - const listRules = await getListRules(result.list_id); + const listRules = canReadRules ? await getListRules(result.list_id) : []; setLinkedRules(listRules); } }, - [] + [canReadRules] ); const initializeList = useCallback(async () => { @@ -411,7 +411,7 @@ export const useListDetailsView = (exceptionListId: string) => { return { isLoading, invalidListId, - isReadOnly: !!(!canUserWriteCurrentList && canReadRules), + isReadOnly: !canUserWriteCurrentList, list, listName: list?.name, listDescription: list?.description, diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts index bacd0377982a5..ac232e754d759 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts @@ -15,6 +15,7 @@ import type { ExceptionListItemSchema, ExceptionListSchema, } from '@kbn/securitysolution-io-ts-list-types'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { useKibana, useToasts } from '../../../common/lib/kibana'; import { deleteException, @@ -56,6 +57,7 @@ export const useListExceptionItems = ({ }); const [lastUpdated, setLastUpdated] = useState(null); const [viewerStatus, setViewerStatus] = useState(''); + const { read: canReadRules } = useUserPrivileges().rulesPrivileges; const handleErrorStatus = useCallback( (error: Error, errorTitle?: string, errorDescription?: string) => { @@ -70,12 +72,12 @@ export const useListExceptionItems = ({ const getReferences = useCallback(async () => { try { - const result: RuleReferences = await getExceptionItemsReferences([list]); + const result: RuleReferences = canReadRules ? await getExceptionItemsReferences([list]) : {}; setExceptionListReferences(result); } catch (error) { handleErrorStatus(error); } - }, [handleErrorStatus, list, setExceptionListReferences]); + }, [canReadRules, handleErrorStatus, list]); const updateViewer = useCallback( ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx index 0b9d71e243c8e..74038ce6d3119 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/index.tsx @@ -112,12 +112,15 @@ export const SharedLists = React.memo(() => { const [viewerStatus, setViewStatus] = useState(ViewerStatus.LOADING); const exceptionListTypes = useMemo(() => { - const lists = [ExceptionListTypeEnum.DETECTION]; + const lists = []; + if (canReadRules) { + lists.push(ExceptionListTypeEnum.DETECTION); + } if (canAccessEndpointExceptions) { lists.push(ExceptionListTypeEnum.ENDPOINT); } return lists; - }, [canAccessEndpointExceptions]); + }, [canAccessEndpointExceptions, canReadRules]); const [ loadingExceptions, exceptions, @@ -495,7 +498,7 @@ export const SharedLists = React.memo(() => { {i18n.CREATE_BUTTON} @@ -529,7 +532,7 @@ export const SharedLists = React.memo(() => { ]} /> , - (!isReadOnly || canWriteEndpointExceptions) && ( + (canEditRules || canWriteEndpointExceptions) && ( Date: Fri, 21 Nov 2025 14:47:13 -0500 Subject: [PATCH 50/85] updates routes with exception subfeature authz strings --- .../lists/server/routes/create_exception_list_item_route.ts | 4 ++-- .../lists/server/routes/create_exception_list_route.ts | 4 ++-- .../lists/server/routes/delete_exception_list_item_route.ts | 4 ++-- .../lists/server/routes/delete_exception_list_route.ts | 4 ++-- .../lists/server/routes/duplicate_exception_list_route.ts | 4 ++-- .../lists/server/routes/export_exception_list_route.ts | 4 ++-- .../lists/server/routes/find_exception_list_item_route.ts | 4 ++-- .../plugins/lists/server/routes/find_exception_list_route.ts | 4 ++-- .../plugins/lists/server/routes/import_exceptions_route.ts | 4 ++-- .../lists/server/routes/read_exception_list_item_route.ts | 4 ++-- .../plugins/lists/server/routes/read_exception_list_route.ts | 4 ++-- .../lists/server/routes/update_exception_list_item_route.ts | 4 ++-- .../lists/server/routes/update_exception_list_route.ts | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts index a3c17034d8247..da84c5b44d110 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -13,7 +13,7 @@ import { CreateExceptionListItemRequestBody, CreateExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -29,7 +29,7 @@ export const createExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts index fcc089dc4d566..214e257e089c7 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/create_exception_list_route.ts @@ -13,7 +13,7 @@ import { CreateExceptionListRequestBody, CreateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -26,7 +26,7 @@ export const createExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts index fae33f8fdcf90..f3ed486713f00 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_item_route.ts @@ -12,7 +12,7 @@ import { DeleteExceptionListItemRequestQuery, DeleteExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -29,7 +29,7 @@ export const deleteExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts index 0b7e746182be0..ce9d3aaa65bae 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/delete_exception_list_route.ts @@ -12,7 +12,7 @@ import { DeleteExceptionListRequestQuery, DeleteExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const deleteExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts index c8ed978b65940..843044c6f85c3 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/duplicate_exception_list_route.ts @@ -12,7 +12,7 @@ import { DuplicateExceptionListRequestQuery, DuplicateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const duplicateExceptionsRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_duplicate`, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts index de27a9778be3c..6ba8fe00221cb 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/export_exception_list_route.ts @@ -9,7 +9,7 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { ExportExceptionListRequestQuery } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -22,7 +22,7 @@ export const exportExceptionsRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_export`, security: { authz: { - requiredPrivileges: [LISTS_API_READ], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts index bd5a0465bae34..889c601907d1e 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_item_route.ts @@ -12,7 +12,7 @@ import { FindExceptionListItemsRequestQuery, FindExceptionListItemsResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const findExceptionListItemRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_ITEM_URL}/_find`, security: { authz: { - requiredPrivileges: [LISTS_API_READ], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts index 85e2ff63eea18..df372dde0c0a8 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/find_exception_list_route.ts @@ -12,7 +12,7 @@ import { FindExceptionListsRequestQuery, FindExceptionListsResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const findExceptionListRoute = (router: ListsPluginRouter): void => { path: `${EXCEPTION_LIST_URL}/_find`, security: { authz: { - requiredPrivileges: [LISTS_API_READ], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts index a35efffde1c9f..4a59db3cd4a25 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/import_exceptions_route.ts @@ -15,7 +15,7 @@ import { ImportExceptionListRequestQuery, ImportExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; import type { ConfigType } from '../config'; @@ -40,7 +40,7 @@ export const importExceptionsRoute = (router: ListsPluginRouter, config: ConfigT path: `${EXCEPTION_LIST_URL}/_import`, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts index 55f875388310a..b174b744f6513 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_item_route.ts @@ -12,7 +12,7 @@ import { ReadExceptionListItemRequestQuery, ReadExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -29,7 +29,7 @@ export const readExceptionListItemRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: [LISTS_API_READ], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts index 3f89d3feceba9..58705b814e859 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/read_exception_list_route.ts @@ -12,7 +12,7 @@ import { ReadExceptionListRequestQuery, ReadExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_READ } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_READ } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const readExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: [LISTS_API_READ], + requiredPrivileges: [EXCEPTIONS_API_READ], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts index b0fd92e52e732..932a81a883e60 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -12,7 +12,7 @@ import { UpdateExceptionListItemRequestBody, UpdateExceptionListItemResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -28,7 +28,7 @@ export const updateExceptionListItemRoute = (router: ListsPluginRouter): void => path: EXCEPTION_LIST_ITEM_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) diff --git a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts index dda81dcf1e54f..07d6b5d87133b 100644 --- a/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts +++ b/x-pack/solutions/security/plugins/lists/server/routes/update_exception_list_route.ts @@ -12,7 +12,7 @@ import { UpdateExceptionListRequestBody, UpdateExceptionListResponse, } from '@kbn/securitysolution-exceptions-common/api'; -import { LISTS_API_ALL } from '@kbn/security-solution-features/constants'; +import { EXCEPTIONS_API_ALL } from '@kbn/security-solution-features/constants'; import type { ListsPluginRouter } from '../types'; @@ -25,7 +25,7 @@ export const updateExceptionListRoute = (router: ListsPluginRouter): void => { path: EXCEPTION_LIST_URL, security: { authz: { - requiredPrivileges: [LISTS_API_ALL], + requiredPrivileges: [EXCEPTIONS_API_ALL], }, }, }) From e70ac86e29fc9f8ce7cefea348276b907879381c Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Fri, 21 Nov 2025 16:02:21 -0500 Subject: [PATCH 51/85] remove exceptions api authz strings from rules v2 feature, should only be granted via exceptions subfeature --- .../packages/shared/kbn-es/src/serverless_resources/users | 1 + .../shared/kbn-es/src/serverless_resources/users_roles | 1 + .../packages/features/src/v2_rules/kibana_features.ts | 5 ----- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/users b/src/platform/packages/shared/kbn-es/src/serverless_resources/users index 6704fc9f22783..706b157113926 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/users +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/users @@ -12,3 +12,4 @@ platform_engineer:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW endpoint_operations_analyst:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW endpoint_policy_manager:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW norules:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW +editrules:$2a$10$nN6sRtQl2KX9Gn8kV/.NpOLSk6Jwn8TehEDnZ7aaAgzyl/dy5PYzW diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles b/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles index af70b19a9745d..851e261fd6f1f 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/users_roles @@ -11,3 +11,4 @@ platform_engineer:platform_engineer endpoint_operations_analyst:endpoint_operations_analyst endpoint_policy_manager:endpoint_policy_manager norules:norules +editrules:editrules diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts index d081b404ef92b..722f93fee4b0d 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts @@ -24,8 +24,6 @@ import { ALERTS_API_ALL, ALERTS_API_READ, APP_ID, - EXCEPTIONS_API_ALL, - EXCEPTIONS_API_READ, INITIALIZE_SECURITY_SOLUTION, LEGACY_NOTIFICATIONS_ID, LISTS_API_ALL, @@ -98,8 +96,6 @@ export const getRulesV2BaseKibanaFeature = ( RULES_API_READ, ALERTS_API_ALL, ALERTS_API_READ, - EXCEPTIONS_API_ALL, - EXCEPTIONS_API_READ, LISTS_API_ALL, LISTS_API_READ, LISTS_API_SUMMARY, @@ -126,7 +122,6 @@ export const getRulesV2BaseKibanaFeature = ( api: [ RULES_API_READ, ALERTS_API_READ, - EXCEPTIONS_API_READ, LISTS_API_READ, USERS_API_READ, INITIALIZE_SECURITY_SOLUTION, From 0dc0d80ca137078801da8120b3669241e7f59883 Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Mon, 24 Nov 2025 15:03:33 -0500 Subject: [PATCH 52/85] linking rules should use the edit + read rules authz function --- .../methods/patch_rule.ts | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts index 113576e8d02e2..b4653b328c39d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts @@ -39,7 +39,7 @@ export const patchRule = async ({ }: PatchRuleOptions): Promise => { const { rule_id: ruleId, id } = rulePatch; - const existingRule = await getRuleByIdOrRuleId({ + let existingRule = await getRuleByIdOrRuleId({ rulesClient, ruleId, id, @@ -54,6 +54,45 @@ export const patchRule = async ({ validateNonCustomizablePatchFields(rulePatch, existingRule); + // Use alerting edit + read auth function + // for exceptions, then follow on with + // applying patch for other rule properties + if (rulePatch.exceptions_list != null) { + const ruleExceptionLists = existingRule.exceptions_list; + await rulesClient.bulkEditRuleParamsWithReadAuth({ + ids: [existingRule.id], + operations: [ + { + field: 'exceptionsList', + operation: 'set', + value: [ + ...ruleExceptionLists, + ...rulePatch.exceptions_list.map((exceptionList) => ({ + id: exceptionList.id, + list_id: exceptionList.list_id, + type: exceptionList.type, + namespace_type: exceptionList.namespace_type, + })), + ], + }, + ], + }); + // TODO: clean up + delete rulePatch.exceptions_list; + existingRule = await getRuleByIdOrRuleId({ + rulesClient, + ruleId, + id, + }); + // have to follow up the fetch rule with this code + // or else typescript complains in other areas we + // use existingRule + if (existingRule == null) { + const error = getIdError({ id, ruleId }); + throw new ClientError(error.message, error.statusCode); + } + } + const patchedRule = await applyRulePatch({ prebuiltRuleAssetClient, existingRule, From 84062f2a6b35f85368006eb0f58ad5cf07ca86ba Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 24 Nov 2025 17:53:32 -0500 Subject: [PATCH 53/85] updates shared list UI page to handle RBAC edge cases --- .../security/packages/features/src/constants.ts | 4 ++++ .../src/search_bar/index.tsx | 2 +- .../rule_actions_overflow/index.test.tsx | 5 ++++- .../rule_details/rule_actions_overflow/index.tsx | 11 ++++++++--- .../components/edit_exception_flyout/index.tsx | 6 +++--- .../add_to_lists_table/use_add_to_lists_table.tsx | 6 +++--- .../components/exceptions_list_card/index.tsx | 2 +- .../components/list_with_search/index.tsx | 14 ++++++++++---- .../hooks/use_all_exception_lists/index.tsx | 2 +- .../hooks/use_exceptions_list.card/index.tsx | 12 ++++++------ .../hooks/use_list_exception_items/index.ts | 8 +++++--- .../security_solution/public/rules/links.ts | 6 +++++- 12 files changed, 51 insertions(+), 27 deletions(-) diff --git a/x-pack/solutions/security/packages/features/src/constants.ts b/x-pack/solutions/security/packages/features/src/constants.ts index 914975bf5c8f6..edcc4f7171752 100644 --- a/x-pack/solutions/security/packages/features/src/constants.ts +++ b/x-pack/solutions/security/packages/features/src/constants.ts @@ -75,6 +75,10 @@ export const RULES_UI_EXTERNAL_DETECTIONS_PRIVILEGE = `${RULES_FEATURE_ID_V2}.${RULES_UI_EXTERNAL_DETECTIONS}` as const; export const EXCEPTIONS_UI_READ = 'readExceptions' as const; export const EXCEPTIONS_UI_CRUD = 'crudExceptions' as const; +export const EXCEPTIONS_UI_READ_PRIVILEGES = + `${RULES_FEATURE_ID_V2}.${EXCEPTIONS_UI_READ}` as const; +export const EXCEPTIONS_UI_CRUD_PRIVILEGES = + `${RULES_FEATURE_ID_V2}.${EXCEPTIONS_UI_CRUD}` as const; // Same as the plugin id defined by Cloud Security Posture export const CLOUD_POSTURE_APP_ID = 'csp' as const; diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx index dd36c16b9bd8d..16fb75d8cd14f 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/index.tsx @@ -98,7 +98,7 @@ const SearchBarComponent: FC = ({ onChange={handleOnSearch} /> - {!canAddException && ( + {canAddException && ( { }); (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { rules: { read: true, edit: true } }, + rulesPrivileges: { + rules: { read: true, edit: true }, + exceptions: { read: true, crud: true }, + }, }); }); describe('rules details menu panel', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx index 78230317d575a..ee28528a35057 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.tsx @@ -81,7 +81,10 @@ const RuleActionsOverflowComponent = ({ const { bulkExport } = useBulkExport(); const downloadExportedRules = useDownloadExportedRules(); const { scheduleRuleRun } = useScheduleRuleRun(); - const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges.rules; + const { + rules: { edit: canEditRules, read: canReadRules }, + exceptions: { crud: canCrudExceptions }, + } = useUserPrivileges().rulesPrivileges; const onRuleDeletedCallback = useCallback(() => { navigateToApp(APP_UI_ID, { @@ -107,8 +110,9 @@ const RuleActionsOverflowComponent = ({ onClick={async () => { startTransaction({ name: SINGLE_RULE_ACTIONS.DUPLICATE }); closePopover(); - const modalDuplicationConfirmationResult = - await showBulkDuplicateExceptionsConfirmation(); + const modalDuplicationConfirmationResult = canCrudExceptions + ? await showBulkDuplicateExceptionsConfirmation() + : DuplicateOptions.withoutExceptions; if (modalDuplicationConfirmationResult === null) { return; } @@ -245,6 +249,7 @@ const RuleActionsOverflowComponent = ({ doesBaseVersionExist, startTransaction, closePopover, + canCrudExceptions, showBulkDuplicateExceptionsConfirmation, executeBulkAction, navigateToApp, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx index d0c6bc0e7fdb4..c5ae16c6e7a7c 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx @@ -109,7 +109,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ const { isLoading, indexPatterns, getExtendedFields } = useFetchIndexPatterns(rules); const [isSubmitting, submitEditExceptionItems] = useEditExceptionItems(); const [isClosingAlerts, closeAlerts] = useCloseAlertsFromExceptions(); - const { read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { read: canReadExceptions } = useUserPrivileges().rulesPrivileges.exceptions; const [ { @@ -160,7 +160,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ useFindExceptionListReferences(); useEffect(() => { - if (fetchReferences != null && canReadRules) { + if (fetchReferences != null && canReadExceptions) { fetchReferences([ { id: list.id, @@ -169,7 +169,7 @@ const EditExceptionFlyoutComponent: React.FC = ({ }, ]); } - }, [list, fetchReferences, canReadRules]); + }, [list, fetchReferences, canReadExceptions]); /** * Reducer action dispatchers diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx index 39b3a3d4dbe08..0d7cbb673b8f5 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/use_add_to_lists_table.tsx @@ -49,7 +49,7 @@ export const useAddToSharedListTable = ({ }: ExceptionsAddToListsComponentProps) => { const [listsToDisplay, setListsToDisplay] = useState([]); const [isLoading, setIsLoading] = useState(false); - const { read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { read: canReadExceptions } = useUserPrivileges().rulesPrivileges.exceptions; const listsToFetch = useMemo(() => { return showAllSharedLists ? [] : sharedExceptionLists; @@ -69,7 +69,7 @@ export const useAddToSharedListTable = ({ const getReferences = useCallback(async () => { try { setIsLoading(true); - return canReadRules + return canReadExceptions ? getExceptionItemsReferences( (!listsToFetch.length ? [{ namespace_type: 'single' }] @@ -79,7 +79,7 @@ export const useAddToSharedListTable = ({ } catch (err) { setError(i18n.REFERENCES_FETCH_ERROR); } - }, [canReadRules, listsToFetch]); + }, [canReadExceptions, listsToFetch]); const fillListsToDisplay = useCallback(async () => { const result = (await getReferences()) as RuleReferences; diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx index a4f87272c80ac..c2ec04fa25e19 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/exceptions_list_card/index.tsx @@ -206,7 +206,7 @@ export const ExceptionsListCard = memo( diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx index 904589d4179c8..c00b1fb78037b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/components/list_with_search/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import type { FC } from 'react'; import { EuiPanel } from '@elastic/eui'; @@ -17,6 +17,7 @@ import { EmptyViewerState, ViewerStatus, } from '@kbn/securitysolution-exception-list-components'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { useEndpointExceptionsCapability } from '../../hooks/use_endpoint_exceptions_capability'; import { AddExceptionFlyout } from '../../../detection_engine/rule_exceptions/components/add_exception_flyout'; import { EditExceptionFlyout } from '../../../detection_engine/rule_exceptions/components/edit_exception_flyout'; @@ -59,6 +60,13 @@ const ListWithSearchComponent: FC = ({ handleConfirmExceptionFlyout, } = useListWithSearchComponent(list, refreshExceptions); const canWriteEndpointExceptions = useEndpointExceptionsCapability('crudEndpointExceptions'); + const canCrudExceptions = useUserPrivileges().rulesPrivileges.exceptions.crud; + + const canAddException = useMemo( + () => + listType === ExceptionListTypeEnum.ENDPOINT ? canWriteEndpointExceptions : canCrudExceptions, + [canCrudExceptions, canWriteEndpointExceptions, listType] + ); return ( <> @@ -109,9 +117,7 @@ const ListWithSearchComponent: FC = ({ isSearching={viewerStatus === ViewerStatus.SEARCHING} isButtonFilled={false} buttonIconType="plusInCircle" - canAddException={ - !(listType === ExceptionListTypeEnum.ENDPOINT && canWriteEndpointExceptions) - } + canAddException={canAddException} /> >( {} ); - const { read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { read: canReadRules } = useUserPrivileges().rulesPrivileges.rules; const handleExceptionsInfo = useCallback( (rules: Rule[]): Record => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx index 00d0bf8e71b49..5c18d12572fca 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx @@ -14,6 +14,7 @@ import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { ViewerStatus } from '@kbn/securitysolution-exception-list-components'; import { useGeneratedHtmlId } from '@elastic/eui'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { useGetSecuritySolutionLinkProps } from '../../../common/components/links'; import { SecurityPageName } from '../../../../common/constants'; import type { ExceptionListInfo } from '../use_all_exception_lists'; @@ -71,9 +72,8 @@ export const useExceptionsListCard = ({ const [showEditExceptionFlyout, setShowEditExceptionFlyout] = useState(false); const [showIncludeExpiredExceptionsModal, setShowIncludeExpiredExceptionsModal] = useState(null); - // TODO: test with endpoint exceptions - // const { read: canReadExceptions, crud: canCrudExceptions } = - // useUserPrivileges().rulesPrivileges.exceptions; + const { read: canReadExceptions, crud: canCrudExceptions } = + useUserPrivileges().rulesPrivileges.exceptions; const { name: listName, @@ -120,7 +120,7 @@ export const useExceptionsListCard = ({ const [toggleAccordion, setToggleAccordion] = useState(false); const openAccordionId = useGeneratedHtmlId({ prefix: 'openAccordion' }); - const listCannotBeEdited = checkIfListCannotBeEdited(exceptionsList); // TODO: test with endpoint exceptions || !canCrudExceptions; + const listCannotBeEdited = checkIfListCannotBeEdited(exceptionsList) || !canCrudExceptions; const emptyViewerTitle = useMemo(() => { return viewerStatus === ViewerStatus.EMPTY ? i18n.EXCEPTION_LIST_EMPTY_VIEWER_TITLE : ''; @@ -157,7 +157,7 @@ export const useExceptionsListCard = ({ setShowIncludeExpiredExceptionsModal(CHECK_EXCEPTION_TTL_ACTION_TYPES.EXPORT); } }, - // disabled: !canReadExceptions, // TODO: test this with endpoint exceptions usage + disabled: !canReadExceptions, }, { key: 'Duplicate', @@ -192,7 +192,7 @@ export const useExceptionsListCard = ({ }, ], [ - // canReadExceptions, + canReadExceptions, listCannotBeEdited, listType, handleExport, diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts index ac232e754d759..e32a953ac380a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_list_exception_items/index.ts @@ -57,7 +57,7 @@ export const useListExceptionItems = ({ }); const [lastUpdated, setLastUpdated] = useState(null); const [viewerStatus, setViewerStatus] = useState(''); - const { read: canReadRules } = useUserPrivileges().rulesPrivileges; + const { read: canReadExceptions } = useUserPrivileges().rulesPrivileges.exceptions; const handleErrorStatus = useCallback( (error: Error, errorTitle?: string, errorDescription?: string) => { @@ -72,12 +72,14 @@ export const useListExceptionItems = ({ const getReferences = useCallback(async () => { try { - const result: RuleReferences = canReadRules ? await getExceptionItemsReferences([list]) : {}; + const result: RuleReferences = canReadExceptions + ? await getExceptionItemsReferences([list]) + : {}; setExceptionListReferences(result); } catch (error) { handleErrorStatus(error); } - }, [canReadRules, handleErrorStatus, list]); + }, [canReadExceptions, handleErrorStatus, list]); const updateViewer = useCallback( ( diff --git a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts index 57a1ddf2a3243..dc530edc9fa7b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { + EXCEPTIONS_UI_READ_PRIVILEGES, RULES_UI_DETECTIONS_PRIVILEGE, RULES_UI_READ_PRIVILEGE, SECURITY_UI_SHOW_PRIVILEGE, @@ -84,7 +85,10 @@ export const links: LinkItem = { }), landingIcon: IconConsoleCloud, path: EXCEPTIONS_PATH, - capabilities: [RULES_UI_READ_PRIVILEGE, `${SECURITY_FEATURE_ID}.showEndpointExceptions`], + capabilities: [ + EXCEPTIONS_UI_READ_PRIVILEGES, + `${SECURITY_FEATURE_ID}.showEndpointExceptions`, + ], skipUrlState: true, hideTimeline: true, globalSearchKeywords: [ From 06aff3b1d18246113e51d29b0e327c00dd047f07 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 25 Nov 2025 06:01:34 +0000 Subject: [PATCH 54/85] Changes from node scripts/regenerate_moon_projects.js --update --- x-pack/platform/packages/shared/kbn-evals/moon.yml | 1 + .../packages/shared/onechat/kbn-evals-suite-onechat/moon.yml | 1 + x-pack/solutions/security/plugins/lists/moon.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/x-pack/platform/packages/shared/kbn-evals/moon.yml b/x-pack/platform/packages/shared/kbn-evals/moon.yml index 446644cf07d57..4275a7a991462 100644 --- a/x-pack/platform/packages/shared/kbn-evals/moon.yml +++ b/x-pack/platform/packages/shared/kbn-evals/moon.yml @@ -33,6 +33,7 @@ dependsOn: - '@kbn/std' - '@kbn/test' - '@kbn/inference-prompt-utils' + - '@kbn/tracing-utils' tags: - test-helper - package diff --git a/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml b/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml index 8c7fabec4b6a9..349a6078823af 100644 --- a/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml +++ b/x-pack/platform/packages/shared/onechat/kbn-evals-suite-onechat/moon.yml @@ -22,6 +22,7 @@ dependsOn: - '@kbn/onechat-common' - '@kbn/tooling-log' - '@kbn/core' + - '@kbn/scout' tags: - functional-tests - package diff --git a/x-pack/solutions/security/plugins/lists/moon.yml b/x-pack/solutions/security/plugins/lists/moon.yml index 8ed78ffe9a96f..a277c14b8d891 100644 --- a/x-pack/solutions/security/plugins/lists/moon.yml +++ b/x-pack/solutions/security/plugins/lists/moon.yml @@ -53,6 +53,7 @@ dependsOn: - '@kbn/core-http-server-mocks' - '@kbn/core-http-server-utils' - '@kbn/react-query' + - '@kbn/security-solution-features' tags: - plugin - prod From b1fc5f3cca9e1f69fe37eeef74435734d47ca286 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Tue, 25 Nov 2025 11:44:11 +0100 Subject: [PATCH 55/85] fix: tests + types --- .../common/service/migrations_service_base.test.ts | 5 +---- .../rules/service/rule_migrations_service.test.ts | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts index cf3f4d71f3598..5417c619af305 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/common/service/migrations_service_base.test.ts @@ -16,13 +16,10 @@ import type { CoreStart } from '@kbn/core/public'; import { firstValueFrom } from 'rxjs'; import { SiemMigrationTaskStatus } from '../../../../common/siem_migrations/constants'; import type { StartPluginsDependencies } from '../../../types'; -import type { CapabilitiesLevel, MissingCapability } from './capabilities'; -import { getMissingCapabilitiesChecker, requiredSiemMigrationCapabilities } from './capabilities'; +import { getMissingCapabilitiesChecker } from './capabilities'; import { SiemMigrationsServiceBase } from './migrations_service_base'; import type { MigrationTaskStats } from '../../../../common/siem_migrations/model/common.gen'; import { TASK_STATS_POLLING_SLEEP_SECONDS } from '../constants'; -import { ExperimentalFeaturesService } from '../../../common/experimental_features_service'; -import { licenseService } from '../../../common/hooks/use_license'; // --- Mocks for external modules --- diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.test.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.test.ts index 490df2464cf50..93159a345be54 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/rule_migrations_service.test.ts @@ -52,6 +52,7 @@ jest.mock('../api', () => ({ })); jest.mock('../../common/service/capabilities', () => ({ + ...jest.requireActual('../../common/service/capabilities'), getMissingCapabilitiesChecker: jest.fn(() => []), })); From a1b8de053b7c79055baa8c50421e8d5c721d8d41 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Nov 2025 14:01:40 -0500 Subject: [PATCH 56/85] refactors feature config code to match other features --- .../packages/features/product_features.ts | 3 +- .../packages/features/src/exceptions/index.ts | 17 ---- .../src/exceptions/kibana_features.ts | 51 ----------- .../src/exceptions/product_feature_config.ts | 37 -------- .../features/src/product_features_keys.ts | 16 ++-- .../packages/features/src/rules/index.ts | 21 ++++- .../features/src/rules/kibana_sub_features.ts | 75 ++++++++++++++++ .../packages/features/src/rules/types.ts | 7 +- .../{ => v1_features}/kibana_features.ts | 6 +- .../v2_features}/kibana_features.ts | 6 +- .../rules/v2_features/kibana_sub_features.ts | 24 +++++ .../packages/features/src/v2_rules/index.ts | 20 ----- .../src/v2_rules/kibana_subfeatures.ts | 89 ------------------- .../src/v2_rules/product_feature_config.ts | 36 -------- .../packages/features/src/v2_rules/types.ts | 11 --- 15 files changed, 136 insertions(+), 283 deletions(-) delete mode 100644 x-pack/solutions/security/packages/features/src/exceptions/index.ts delete mode 100644 x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts delete mode 100644 x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts create mode 100644 x-pack/solutions/security/packages/features/src/rules/kibana_sub_features.ts rename x-pack/solutions/security/packages/features/src/rules/{ => v1_features}/kibana_features.ts (96%) rename x-pack/solutions/security/packages/features/src/{v2_rules => rules/v2_features}/kibana_features.ts (95%) create mode 100644 x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_sub_features.ts delete mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/index.ts delete mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts delete mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts delete mode 100644 x-pack/solutions/security/packages/features/src/v2_rules/types.ts diff --git a/x-pack/solutions/security/packages/features/product_features.ts b/x-pack/solutions/security/packages/features/product_features.ts index 4011f15f5f425..cda26e94ee370 100644 --- a/x-pack/solutions/security/packages/features/product_features.ts +++ b/x-pack/solutions/security/packages/features/product_features.ts @@ -18,5 +18,4 @@ export { getAttackDiscoveryFeature } from './src/attack_discovery'; export { getTimelineFeature } from './src/timeline'; export { getNotesFeature } from './src/notes'; export { getSiemMigrationsFeature } from './src/siem_migrations'; -export { getRulesFeature } from './src/rules'; -export { getRulesV2Feature } from './src/v2_rules'; +export { getRulesFeature, getRulesV2Feature } from './src/rules'; diff --git a/x-pack/solutions/security/packages/features/src/exceptions/index.ts b/x-pack/solutions/security/packages/features/src/exceptions/index.ts deleted file mode 100644 index c1e8e551d2bf3..0000000000000 --- a/x-pack/solutions/security/packages/features/src/exceptions/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// import { getExceptionsBaseKibanaFeature } from './kibana_features'; -// import type { ProductFeatureParams } from '../types'; -// import type { SecurityFeatureParams } from '../security/types'; -// import { EXCEPTIONS_SUBFEATURE_ID } from '../../constants'; - -// export const getExceptionsFeature = (params: SecurityFeatureParams): ProductFeatureParams => ({ -// baseKibanaFeature: getExceptionsBaseKibanaFeature(params), -// baseKibanaSubFeatureIds: [EXCEPTIONS_SUBFEATURE_ID], -// subFeaturesMap: new Map(), -// }); diff --git a/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts b/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts deleted file mode 100644 index 4ee74fd1d4b2a..0000000000000 --- a/x-pack/solutions/security/packages/features/src/exceptions/kibana_features.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; -// import { i18n } from '@kbn/i18n'; - -// import { APP_ID, EXCEPTIONS_FEATURE_ID } from '../constants'; -// import { type BaseKibanaFeatureConfig } from '../types'; -// import type { SecurityFeatureParams } from '../security/types'; - -// export const getExceptionsBaseKibanaFeature = ( -// params: SecurityFeatureParams -// ): BaseKibanaFeatureConfig => ({ -// id: EXCEPTIONS_FEATURE_ID, -// name: i18n.translate( -// 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionExceptionsTitle', -// { -// defaultMessage: 'Exceptions', -// } -// ), -// order: 1100, -// category: DEFAULT_APP_CATEGORIES.security, -// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], -// catalogue: [APP_ID], -// privileges: { -// all: { -// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], -// catalogue: [APP_ID], -// savedObject: { -// all: params.savedObjects, -// read: params.savedObjects, -// }, -// ui: ['read', 'crud'], -// api: ['exceptions_read', 'exceptions_write'], -// }, -// read: { -// app: [EXCEPTIONS_FEATURE_ID, 'kibana'], -// catalogue: [APP_ID], -// savedObject: { -// all: [], -// read: params.savedObjects, -// }, -// ui: ['read'], -// api: ['exceptions_read'], -// }, -// }, -// }); diff --git a/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts deleted file mode 100644 index 3824e266502da..0000000000000 --- a/x-pack/solutions/security/packages/features/src/exceptions/product_feature_config.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -// import { ProductFeatureRulesKey } from '../product_features_keys'; -// import type { ProductFeatureKibanaConfig } from '../types'; - -// /** -// * App features privileges configuration for the Rules feature. -// * These are the configs that are shared between both offering types (ess and serverless). -// * They can be extended on each offering plugin to register privileges using different way on each offering type. -// * -// * Privileges can be added in different ways: -// * - `privileges`: the privileges that will be added directly into the main Security feature. -// * - `subFeatureIds`: the ids of the sub-features that will be added into the Security subFeatures entry. -// * - `subFeaturesPrivileges`: the privileges that will be added into the existing Security subFeature with the privilege `id` specified. -// */ -// export const rulesDefaultProductFeaturesConfig: Record< -// ProductFeatureRulesKey, -// ProductFeatureKibanaConfig -// > = { -// [ProductFeatureRulesKey.rules]: { -// privileges: { -// all: { -// api: ['exceptions_read', 'exceptions_write'], -// ui: ['read', 'crud'], -// }, -// read: { -// api: ['exceptions_read'], -// ui: ['read'], -// }, -// }, -// }, -// }; diff --git a/x-pack/solutions/security/packages/features/src/product_features_keys.ts b/x-pack/solutions/security/packages/features/src/product_features_keys.ts index 83d473c8b228c..af8c724ab4668 100644 --- a/x-pack/solutions/security/packages/features/src/product_features_keys.ts +++ b/x-pack/solutions/security/packages/features/src/product_features_keys.ts @@ -170,13 +170,6 @@ export enum ProductFeatureRulesKey { exceptions = 'exceptions', } -export enum ProductFeatureExceptionsFeatureKey { - /** - * Enables Exceptions - */ - exceptions = 'exceptions', -} - // Merges the two enums. export const ProductFeatureKey = { ...ProductFeatureSecurityKey, @@ -187,7 +180,6 @@ export const ProductFeatureKey = { ...ProductFeatureTimelineKey, ...ProductFeatureNotesKey, ...ProductFeatureRulesKey, - ...ProductFeatureExceptionsFeatureKey, }; // We need to merge the value and the type and export both to replicate how enum works. export type ProductFeatureKeyType = @@ -198,8 +190,7 @@ export type ProductFeatureKeyType = | ProductFeatureSiemMigrationsKey | ProductFeatureTimelineKey | ProductFeatureNotesKey - | ProductFeatureRulesKey - | ProductFeatureExceptionsFeatureKey; + | ProductFeatureRulesKey; export const ALL_PRODUCT_FEATURE_KEYS = Object.freeze(Object.values(ProductFeatureKey)); @@ -243,3 +234,8 @@ export enum AssistantSubFeatureId { export enum AttackDiscoverySubFeatureId { updateSchedule = 'updateScheduleSubFeature', } + +/** Sub-features IDs for Security Rules */ +export enum RulesSubFeatureId { + exceptions = 'exceptionsSubFeature', +} diff --git a/x-pack/solutions/security/packages/features/src/rules/index.ts b/x-pack/solutions/security/packages/features/src/rules/index.ts index 9544ddd09d22c..a0b78e72dae39 100644 --- a/x-pack/solutions/security/packages/features/src/rules/index.ts +++ b/x-pack/solutions/security/packages/features/src/rules/index.ts @@ -5,14 +5,31 @@ * 2.0. */ -import { getRulesBaseKibanaFeature } from './kibana_features'; +import { getRulesBaseKibanaFeature } from './v1_features/kibana_features'; import type { ProductFeatureParams } from '../types'; import type { SecurityFeatureParams } from '../security/types'; import { rulesDefaultProductFeaturesConfig } from './product_feature_config'; +import { getRulesV2BaseKibanaFeature } from './v2_features/kibana_features'; +import { + getRulesBaseKibanaSubFeatureIdsV2, + getRulesSubFeaturesMapV2, +} from './v2_features/kibana_sub_features'; +import type { ProductFeatureRulesKey, RulesSubFeatureId } from '../product_features_keys'; -export const getRulesFeature = (params: SecurityFeatureParams): ProductFeatureParams => ({ +export const getRulesFeature = ( + params: SecurityFeatureParams +): ProductFeatureParams => ({ baseKibanaFeature: getRulesBaseKibanaFeature(params), baseKibanaSubFeatureIds: [], subFeaturesMap: new Map(), productFeatureConfig: rulesDefaultProductFeaturesConfig, }); + +export const getRulesV2Feature = ( + params: SecurityFeatureParams +): ProductFeatureParams => ({ + baseKibanaFeature: getRulesV2BaseKibanaFeature(params), + baseKibanaSubFeatureIds: getRulesBaseKibanaSubFeatureIdsV2(), + subFeaturesMap: getRulesSubFeaturesMapV2(), + productFeatureConfig: rulesDefaultProductFeaturesConfig, +}); diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/rules/kibana_sub_features.ts new file mode 100644 index 0000000000000..f9c5a2a5314c1 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/kibana_sub_features.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; +import { + APP_ID, + EXCEPTIONS_API_ALL, + EXCEPTIONS_API_READ, + EXCEPTIONS_SUBFEATURE_ID_ALL, + EXCEPTIONS_SUBFEATURE_ID_READ, + EXCEPTIONS_UI_CRUD, + EXCEPTIONS_UI_READ, + LISTS_API_ALL, + LISTS_API_READ, +} from '../../constants'; + +const TRANSLATIONS = Object.freeze({ + all: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.subFeatures.allPrivilegeName', + { + defaultMessage: 'All', + } + ), + read: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName', + { + defaultMessage: 'Read', + } + ), +}); + +export const getExceptionsSubFeature = (): SubFeatureConfig => ({ + name: i18n.translate( + 'securitySolutionPackages.features.featureRegistry.exceptionsSubFeatureName', + { + defaultMessage: 'Exceptions', + } + ), + privilegeGroups: [ + { + groupType: 'mutually_exclusive', + privileges: [ + { + id: EXCEPTIONS_SUBFEATURE_ID_ALL, + includeIn: 'all', + name: TRANSLATIONS.all, + savedObject: { + all: [EXCEPTION_LIST_NAMESPACE], + read: [EXCEPTION_LIST_NAMESPACE], + }, + ui: [EXCEPTIONS_UI_READ, EXCEPTIONS_UI_CRUD], + api: [EXCEPTIONS_API_READ, EXCEPTIONS_API_ALL, LISTS_API_ALL, LISTS_API_READ], + }, + { + id: EXCEPTIONS_SUBFEATURE_ID_READ, + includeIn: 'read', + name: TRANSLATIONS.read, + catalogue: [APP_ID], + savedObject: { + all: [], + read: [EXCEPTION_LIST_NAMESPACE], + }, + ui: [EXCEPTIONS_UI_READ], + api: [EXCEPTIONS_API_READ, LISTS_API_READ], + }, + ], + }, + ], +}); diff --git a/x-pack/solutions/security/packages/features/src/rules/types.ts b/x-pack/solutions/security/packages/features/src/rules/types.ts index af9bf035239c9..736679e06dac1 100644 --- a/x-pack/solutions/security/packages/features/src/rules/types.ts +++ b/x-pack/solutions/security/packages/features/src/rules/types.ts @@ -5,7 +5,10 @@ * 2.0. */ -import type { ProductFeatureRulesKey } from '../product_features_keys'; +import type { ProductFeatureRulesKey, RulesSubFeatureId } from '../product_features_keys'; import type { ProductFeaturesConfig } from '../types'; -export type RulesProductFeaturesConfig = ProductFeaturesConfig; +export type RulesProductFeaturesConfig = ProductFeaturesConfig< + ProductFeatureRulesKey, + RulesSubFeatureId +>; diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts similarity index 96% rename from x-pack/solutions/security/packages/features/src/rules/kibana_features.ts rename to x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts index 59ceb3ccd6df2..c8860859c63a8 100644 --- a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts @@ -39,9 +39,9 @@ import { USERS_API_READ, EXCEPTIONS_SUBFEATURE_ID_ALL, EXCEPTIONS_SUBFEATURE_ID_READ, -} from '../constants'; -import { type BaseKibanaFeatureConfig } from '../types'; -import type { SecurityFeatureParams } from '../security/types'; +} from '../../constants'; +import { type BaseKibanaFeatureConfig } from '../../types'; +import type { SecurityFeatureParams } from '../../security/types'; const SECURITY_RULE_TYPES = [ LEGACY_NOTIFICATIONS_ID, diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_features.ts similarity index 95% rename from x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts rename to x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_features.ts index 722f93fee4b0d..542b896e64b4e 100644 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_features.ts @@ -36,9 +36,9 @@ import { RULES_UI_READ, SERVER_APP_ID, USERS_API_READ, -} from '../constants'; -import { type BaseKibanaFeatureConfig } from '../types'; -import type { SecurityFeatureParams } from '../security/types'; +} from '../../constants'; +import { type BaseKibanaFeatureConfig } from '../../types'; +import type { SecurityFeatureParams } from '../../security/types'; const SECURITY_RULE_TYPES = [ LEGACY_NOTIFICATIONS_ID, diff --git a/x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_sub_features.ts b/x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_sub_features.ts new file mode 100644 index 0000000000000..e5f88fc3993d8 --- /dev/null +++ b/x-pack/solutions/security/packages/features/src/rules/v2_features/kibana_sub_features.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SubFeatureConfig } from '@kbn/features-plugin/common'; +import { RulesSubFeatureId } from '../../product_features_keys'; +import { getExceptionsSubFeature } from '../kibana_sub_features'; + +export const getRulesBaseKibanaSubFeatureIdsV2 = (): RulesSubFeatureId[] => [ + RulesSubFeatureId.exceptions, +]; + +/** + * Defines all the Security Solution Rules subFeatures available. + * The order of the subFeatures is the order they will be displayed + */ +export const getRulesSubFeaturesMapV2 = () => { + return new Map([ + [RulesSubFeatureId.exceptions, getExceptionsSubFeature()], + ]); +}; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/index.ts b/x-pack/solutions/security/packages/features/src/v2_rules/index.ts deleted file mode 100644 index 80d41396b691b..0000000000000 --- a/x-pack/solutions/security/packages/features/src/v2_rules/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getRulesV2BaseKibanaFeature } from './kibana_features'; -import type { ProductFeatureParams } from '../types'; -import type { SecurityFeatureParams } from '../security/types'; -import { rulesDefaultProductFeaturesConfig } from './product_feature_config'; -import { getExceptionsSubFeaturesMap } from './kibana_subfeatures'; -import { EXCEPTIONS_SUBFEATURE_ID } from '../constants'; - -export const getRulesV2Feature = (params: SecurityFeatureParams): ProductFeatureParams => ({ - baseKibanaFeature: getRulesV2BaseKibanaFeature(params), - baseKibanaSubFeatureIds: [EXCEPTIONS_SUBFEATURE_ID], - subFeaturesMap: getExceptionsSubFeaturesMap(params.savedObjects), - productFeatureConfig: rulesDefaultProductFeaturesConfig, -}); diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts b/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts deleted file mode 100644 index 5b44904b553aa..0000000000000 --- a/x-pack/solutions/security/packages/features/src/v2_rules/kibana_subfeatures.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import type { SubFeatureConfig } from '@kbn/features-plugin/common'; -import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; -import { - APP_ID, - EXCEPTIONS_API_READ, - EXCEPTIONS_API_ALL, - EXCEPTIONS_SUBFEATURE_ID, - EXCEPTIONS_SUBFEATURE_ID_ALL, - EXCEPTIONS_SUBFEATURE_ID_READ, - LISTS_API_ALL, - LISTS_API_READ, - EXCEPTIONS_UI_READ, - EXCEPTIONS_UI_CRUD, -} from '../../constants'; -import type { SecurityFeatureParams } from '../security/types'; - -const TRANSLATIONS = Object.freeze({ - all: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.allPrivilegeName', - { - defaultMessage: 'All', - } - ), - read: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.subFeatures.readPrivilegeName', - { - defaultMessage: 'Read', - } - ), -}); - -/** - * Defines all the Security Solution Cases subFeatures available. - * The order of the subFeatures is the order they will be displayed - */ -export const getExceptionsSubFeaturesMap = ( - savedObjects: SecurityFeatureParams['savedObjects'] -) => { - const exceptionsSubFeature: SubFeatureConfig = { - name: i18n.translate( - 'securitySolutionPackages.features.featureRegistry.exceptionsSubFeatureName', - { - defaultMessage: 'Exceptions', - } - ), - privilegeGroups: [ - { - groupType: 'mutually_exclusive', - privileges: [ - { - id: EXCEPTIONS_SUBFEATURE_ID_ALL, - includeIn: 'all', - name: TRANSLATIONS.all, - savedObject: { - all: [EXCEPTION_LIST_NAMESPACE], - read: [EXCEPTION_LIST_NAMESPACE], - }, - ui: [EXCEPTIONS_UI_READ, EXCEPTIONS_UI_CRUD], - api: [EXCEPTIONS_API_READ, EXCEPTIONS_API_ALL, LISTS_API_ALL, LISTS_API_READ], - }, - { - id: EXCEPTIONS_SUBFEATURE_ID_READ, - includeIn: 'read', - name: TRANSLATIONS.read, - catalogue: [APP_ID], - savedObject: { - all: [], - read: [EXCEPTION_LIST_NAMESPACE], - }, - ui: [EXCEPTIONS_UI_READ], - api: [EXCEPTIONS_API_READ, LISTS_API_READ], - }, - ], - }, - ], - }; - - return new Map([ - [EXCEPTIONS_SUBFEATURE_ID, exceptionsSubFeature], - ]); -}; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts b/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts deleted file mode 100644 index b78ae93bfe48e..0000000000000 --- a/x-pack/solutions/security/packages/features/src/v2_rules/product_feature_config.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ProductFeatureRulesKey } from '../product_features_keys'; -import type { RulesProductFeaturesConfig } from './types'; - -export const rulesDefaultProductFeaturesConfig: RulesProductFeaturesConfig = { - [ProductFeatureRulesKey.externalDetections]: { - privileges: { - all: { - ui: ['external_detections'], - api: [], - }, - read: { - ui: ['external_detections'], - api: [], - }, - }, - }, - [ProductFeatureRulesKey.detections]: { - privileges: { - all: { - ui: ['detections'], - api: ['cloud-security-posture-all', 'cloud-security-posture-read', 'bulkGetUserProfiles'], - }, - read: { - ui: ['detections'], - api: ['cloud-security-posture-read', 'bulkGetUserProfiles'], - }, - }, - }, -}; diff --git a/x-pack/solutions/security/packages/features/src/v2_rules/types.ts b/x-pack/solutions/security/packages/features/src/v2_rules/types.ts deleted file mode 100644 index af9bf035239c9..0000000000000 --- a/x-pack/solutions/security/packages/features/src/v2_rules/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { ProductFeatureRulesKey } from '../product_features_keys'; -import type { ProductFeaturesConfig } from '../types'; - -export type RulesProductFeaturesConfig = ProductFeaturesConfig; From ee43150601e2fc4cfaa2895fb16ca146dda6625b Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Nov 2025 15:40:04 -0500 Subject: [PATCH 57/85] fix types --- .../detection_engine/alerts/use_alerts_privileges.test.tsx | 2 +- .../shared/components/take_action_dropdown.test.tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx index 263edb0377c7e..6943fbb6dbdb8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_alerts_privileges.test.tsx @@ -78,7 +78,7 @@ const userPrivilegesInitial: ReturnType = { siemPrivileges: { crud: true, read: true }, timelinePrivileges: { crud: true, read: true }, notesPrivileges: { crud: true, read: true }, - rulesPrivileges: { edit: true, read: true }, + rulesPrivileges: { rules: { edit: true, read: true }, exceptions: { read: true, crud: false } }, }; describe('useAlertsPrivileges', () => { diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index d6e5099ab7374..cfe7c614e1766 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -383,7 +383,12 @@ describe('take action dropdown', () => { beforeEach(() => { (useUserPrivileges as jest.Mock).mockReturnValue( - getUserPrivilegesMockDefaultValue({ rulesPrivileges: { read: true, edit: true } }) + getUserPrivilegesMockDefaultValue({ + rulesPrivileges: { + rules: { read: true, edit: true }, + exceptions: { read: true, crud: true }, + }, + }) ); }); From 65795596518c9a009bcae921f792b55758a2cdee Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Nov 2025 17:02:51 -0500 Subject: [PATCH 58/85] updates server features mock --- .../server/lib/product_features_service/mocks.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts index d855b805f48e0..0aa4f499ac840 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/mocks.ts @@ -88,6 +88,11 @@ jest.mock('@kbn/security-solution-features/product_features', () => ({ baseKibanaSubFeatureIds: [], subFeaturesMap: new Map(), })), + getRulesV2Feature: jest.fn(() => ({ + baseKibanaFeature: {}, + baseKibanaSubFeatureIds: [], + subFeaturesMap: new Map(), + })), })); export const createProductFeaturesServiceMock = ( From b5221072edf4a8bda509d57e43415796ffeddf4e Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 25 Nov 2025 16:46:48 -0600 Subject: [PATCH 59/85] Simplify permissions for migration dashboard link This feature only cares about the dashboard and Migrations feature privileges; while intermediate privileges may not have any effect on this behavior, they are an unnecessary complication and make this feature more inflexible in the future. --- .../security_solution/public/siem_migrations/links.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts index e015a13e6a651..faf36b6c305e2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/links.ts @@ -50,10 +50,7 @@ const subLinks: LinkItem[] = [ ), landingIcon: IconDashboards, path: SIEM_MIGRATIONS_DASHBOARDS_PATH, - // dashboard page requires both the Security:Read and Dashboard:Read privileges - capabilities: [ - [`dashboard_v2.show`, SECURITY_UI_SHOW_PRIVILEGE, `${SIEM_MIGRATIONS_FEATURE_ID}.all`], - ], + capabilities: [[`dashboard_v2.show`, `${SIEM_MIGRATIONS_FEATURE_ID}.all`]], skipUrlState: true, hideTimeline: true, hideWhenExperimentalKey: 'siemMigrationsDisabled', From 635e19501f4c069801ad96c8025df7289975543d Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 25 Nov 2025 22:03:06 -0500 Subject: [PATCH 60/85] update product features service mock --- .../product_features_service/product_features_service.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts index 0001428c8469c..6e4c0d0e6c912 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/product_features_service/product_features_service.test.ts @@ -43,6 +43,7 @@ jest.mock('@kbn/security-solution-features/product_features', () => ({ getSecurityV4Feature: () => mockGetFeature(), getSecurityV5Feature: () => mockGetFeature(), getRulesFeature: () => mockGetFeature(), + getRulesV2Feature: () => mockGetFeature(), getCasesFeature: () => mockGetFeature(), getCasesV2Feature: () => mockGetFeature(), getCasesV3Feature: () => mockGetFeature(), From 12c778144aadaf0b2f3e537855c54df7c28909f1 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 26 Nov 2025 14:28:54 -0500 Subject: [PATCH 61/85] fix exception list jest tests --- .../common/suites/create.agnostic.ts | 2 +- .../use_add_exception_actions.test.tsx | 14 +++---- .../hooks/use_exceptions_list.card/index.tsx | 2 +- .../pages/shared_lists/shared_lists.test.tsx | 40 ++++++++++++++++--- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts index 3f5d3f95b3adc..e313f6a9ecfb5 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/create.agnostic.ts @@ -92,7 +92,7 @@ export function createTestSuiteFactory({ getService }: DeploymentAgnosticFtrProv 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', - 'securitySolutionRulesV1', + 'securitySolutionRulesV2', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', 'siemV5', diff --git a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx index 3d90767059150..5e52992dcf7af 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_exception_actions.test.tsx @@ -28,7 +28,7 @@ describe('useAlertExceptionActions', () => { it('should return both add rule exception and add endpoint exception menu items with all privileges', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -47,7 +47,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding endpoint exceptions when user has no endpoint exceptions ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -66,7 +66,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding endpoint exceptions when alert is not an endpoint alert', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -86,7 +86,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding rule exceptions when user has no security:ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: false } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: false } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -105,7 +105,7 @@ describe('useAlertExceptionActions', () => { it('should disable adding rule exceptions when user has no index write privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( @@ -124,7 +124,7 @@ describe('useAlertExceptionActions', () => { it('should not return menu items when user has neither security:ALL nor endpoint exceptions ALL privilege', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: true }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: false } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: false } } }); mockUseEndpointExceptionsCapability.mockReturnValue(false); const { result } = renderHook( @@ -137,7 +137,7 @@ describe('useAlertExceptionActions', () => { it('should not return menu items when user has neither index write and it is not an endpoint alert', () => { mockUseUserData.mockReturnValue([{ hasIndexWrite: false }]); - mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { edit: true } } }); + mockUseUserPrivileges.mockReturnValue({ rulesPrivileges: { exceptions: { crud: true } } }); mockUseEndpointExceptionsCapability.mockReturnValue(true); const { result } = renderHook( diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx index 5c18d12572fca..935c197c6446e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/hooks/use_exceptions_list.card/index.tsx @@ -157,7 +157,7 @@ export const useExceptionsListCard = ({ setShowIncludeExpiredExceptionsModal(CHECK_EXCEPTION_TTL_ACTION_TYPES.EXPORT); } }, - disabled: !canReadExceptions, + disabled: listType === ExceptionListTypeEnum.ENDPOINT ? false : !canReadExceptions, }, { key: 'Duplicate', diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx index 29d56cdcbb666..952a439fca576 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/pages/shared_lists/shared_lists.test.tsx @@ -201,8 +201,10 @@ describe('SharedLists', () => { }); }); - it('disables the "endpoint_list" overflow card button when user is restricted to only READ Endpoint Exceptions', async () => { - (useEndpointExceptionsCapability as jest.Mock).mockReturnValue(false); + it('enables the export "endpoint_list" overflow card button when user is restricted to only READ Endpoint Exceptions', async () => { + (useEndpointExceptionsCapability as jest.Mock).mockImplementation((feature: string) => + feature === 'showEndpointExceptions' ? true : false + ); const wrapper = render( @@ -210,7 +212,12 @@ describe('SharedLists', () => { ); const allMenuActions = wrapper.getAllByTestId('sharedListOverflowCardButtonIcon'); - expect(allMenuActions[0]).toBeDisabled(); + fireEvent.click(allMenuActions[1]); + + await waitFor(() => { + const allExportActions = wrapper.getAllByTestId('sharedListOverflowCardActionItemExport'); + expect(allExportActions[0]).toBeEnabled(); + }); }); it('renders delete option as disabled if list is "endpoint_list"', async () => { @@ -228,7 +235,25 @@ describe('SharedLists', () => { }); }); - it('renders overflow card button as disabled if user is read only', async () => { + it('renders overflow card button as enabled if user is read only', async () => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { + rules: { read: true, edit: false }, + exceptions: { read: true, crud: false }, + }, + }); + + const wrapper = render( + + + + ); + const allMenuActions = wrapper.getAllByTestId('sharedListOverflowCardButtonIcon'); + expect(allMenuActions[1]).toBeEnabled(); + }); + + it('renders overflow card export action as enabled if user is read only', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), rulesPrivileges: { @@ -243,6 +268,11 @@ describe('SharedLists', () => { ); const allMenuActions = wrapper.getAllByTestId('sharedListOverflowCardButtonIcon'); - expect(allMenuActions[1]).toBeDisabled(); + fireEvent.click(allMenuActions[0]); + + await waitFor(() => { + const allExportActions = wrapper.getAllByTestId('sharedListOverflowCardActionItemExport'); + expect(allExportActions[0]).toBeEnabled(); + }); }); }); From e77cd1c754d012f4ab8424ec46dbd58b7939ebec Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Thu, 27 Nov 2025 02:16:57 -0500 Subject: [PATCH 62/85] fixes take action dropdown jest tests --- .../pages/rule_details/rule_actions_overflow/index.test.tsx | 5 ++++- .../shared/components/take_action_dropdown.test.tsx | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx index 38cd5e65b6271..d3a41e595df25 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_actions_overflow/index.test.tsx @@ -191,7 +191,10 @@ describe('RuleActionsOverflow', () => { test('should be enabled when user only has rule read permissions', async () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...initialUserPrivilegesState(), - rulesPrivileges: { read: true, edit: false }, + rulesPrivileges: { + rules: { read: true, edit: false }, + exceptions: { read: true, crud: false }, + }, }); const { getByTestId } = render( diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index cfe7c614e1766..43b92545996f7 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -157,7 +157,10 @@ describe('take action dropdown', () => { (useUserPrivileges as jest.Mock).mockReturnValue({ ...getUserPrivilegesMockDefaultValue(), timelinePrivileges: { read: true }, - rulesPrivileges: { read: true, edit: true }, + rulesPrivileges: { + rules: { read: true, edit: true }, + exceptions: { read: true, crud: true }, + }, }); wrapper = mount( From 7fc5507562a78234d154bb2dfe30b441f39caa0f Mon Sep 17 00:00:00 2001 From: Devin Hurley Date: Mon, 1 Dec 2025 10:06:44 -0500 Subject: [PATCH 63/85] applies patch rules using new alerting bulk edit rules function if all fields are part of the read authz editable fields --- .../project_roles/security/roles.yml | 131 +++++ .../serverless_resources/security_roles.json | 539 +++++++----------- .../shared/alerting/common/constants/index.ts | 2 + .../constants/valid_fields_with_read_auth.ts | 15 + .../bulk_edit_rule_params_option_schemas.ts | 4 +- .../methods/patch_rule.ts | 65 +-- .../detection_rules_client/utils.test.ts | 197 ++++--- .../logic/detection_rules_client/utils.ts | 153 ++++- 8 files changed, 607 insertions(+), 499 deletions(-) create mode 100644 x-pack/platform/plugins/shared/alerting/common/constants/valid_fields_with_read_auth.ts diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/project_roles/security/roles.yml b/src/platform/packages/shared/kbn-es/src/serverless_resources/project_roles/security/roles.yml index f5da7abf6ce81..1246ac16e5e1c 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/project_roles/security/roles.yml +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/project_roles/security/roles.yml @@ -938,6 +938,137 @@ endpoint_policy_manager: - feature_savedQueryManagement.all resources: '*' +# siemv4 roles to test new rules and exceptions subfeature +readrules: + cluster: [] + indices: + - names: + - '.alerts-security*' + - '.siem-signals-*' + privileges: + - read + - write + - maintenance + - names: + - .lists* + - .items* + - apm-*-transaction* + - traces-apm* + - auditbeat-* + - endgame-* + - filebeat-* + - logs-* + - packetbeat-* + - winlogbeat-* + - logstash-* + - metrics-endpoint.metadata_current_* + - '.fleet-agents*' + - '.fleet-actions*' + - risk-score.risk-score-* + - .asset-criticality.asset-criticality-* + - .entities.v1.latest.security_* + - .entities.v1.history.*.security_* + - .entities.v1.updates.security_* + - '.ml-anomalies-*' + - security_solution-*.misconfiguration_latest* + - .entity_analytics.monitoring* + privileges: + - read + applications: + - application: 'kibana-.kibana' + privileges: + - feature_ml.read + - feature_siemV4.read + - feature_siemV4.read_alerts + - feature_siemV4.endpoint_list_read + - feature_securitySolutionCasesV2.read + - feature_securitySolutionTimeline.read + - feature_securitySolutionNotes.read + - feature_actions.read + - feature_builtInAlerts.read + - feature_osquery.read + - feature_osquery.run_saved_queries + - feature_discover_v2.all + - feature_dashboard_v2.all + - feature_maps_v2.all + - feature_visualize_v2.all + - feature_savedQueryManagement.all + resources: '*' + +editrules: + cluster: ['manage_index_templates', 'manage_transform'] + indices: + - names: + - apm-*-transaction* + - traces-apm* + - auditbeat-* + - endgame-* + - filebeat-* + - logs-* + - packetbeat-* + - winlogbeat-* + - logstash-* + - .lists* + - .items* + - .alerts-security* + - .siem-signals-* + - .preview.alerts-security* + - .internal.preview.alerts-security* + - .adhoc.alerts-security* + - .internal.adhoc.alerts-security* + - security_solution-*.misconfiguration_latest* + privileges: + - read + - write + - manage + - names: + - metrics-endpoint.metadata_current_* + - .fleet-agents* + - .fleet-actions* + - '.ml-anomalies-*' + - .entity_analytics.monitoring* + privileges: + - read + - names: + - risk-score.risk-score-* + privileges: + - all + - names: + - .asset-criticality.asset-criticality-* + - .entities.v1.latest.security_* + - .entities.v1.history.*.security_* + - .entities.v1.updates.security_* + privileges: + - read + - write + - names: + - .entities.v1.latest.security_* + privileges: + - delete + applications: + - application: 'kibana-.kibana' + privileges: + - feature_ml.all + - feature_siemV4.all + - feature_siemV4.read_alerts + - feature_siemV4.crud_alerts + - feature_siemV4.global_artifact_management_all + - feature_siemV4.endpoint_exceptions_all + - feature_securitySolutionCasesV2.all + - feature_securitySolutionAssistant.all + - feature_securitySolutionAttackDiscovery.all + - feature_securitySolutionTimeline.all + - feature_securitySolutionNotes.all + - feature_actions.all + - feature_builtInAlerts.all + - feature_dev_tools.all + - feature_discover_v2.all + - feature_dashboard_v2.all + - feature_maps_v2.all + - feature_visualize_v2.all + - feature_savedQueryManagement.all + resources: '*' + # admin role defined in elasticsearch controller admin: cluster: ['all'] diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index aecec6532056e..0a25f359e2ee4 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -5,15 +5,8 @@ "cluster": [], "indices": [ { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { "names": [ @@ -31,9 +24,7 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -41,38 +32,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV4": [ - "read", - "read_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "read" - ], - "securitySolutionTimeline": [ - "read" - ], - "securitySolutionNotes": [ - "read" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "read" - ] + "ml": ["read"], + "siemV4": ["read", "read_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["read"], + "builtInAlerts": ["read"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -83,15 +53,8 @@ "cluster": [], "indices": [ { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { "names": [ @@ -111,9 +74,7 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -121,38 +82,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV4": [ - "read", - "read_alerts" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "read" - ], - "securitySolutionTimeline": [ - "read" - ], - "securitySolutionNotes": [ - "read" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "read" - ] + "ml": ["read"], + "siemV4": ["read", "read_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["read"], + "builtInAlerts": ["read"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -175,31 +115,15 @@ "logstash-*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { - "names": [ - ".alerts-security*", - ".siem-signals-*" - ], - "privileges": [ - "read", - "write", - "maintenance" - ] + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { - "names": [ - ".lists*", - ".items*" - ], - "privileges": [ - "read", - "write" - ] + "names": [".lists*", ".items*"], + "privileges": ["read", "write"] }, { "names": [ @@ -213,9 +137,7 @@ ".entities.v1.updates.security_*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -223,9 +145,7 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], + "ml": ["read"], "siemV4": [ "all", "read_alerts", @@ -242,49 +162,21 @@ "actions_log_management_all", "file_operations_all" ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ], - "osquery": [ - "all" - ], - "discover_v2": [ - "all" - ], - "dashboard_v2": [ - "all" - ], - "maps_v2": [ - "all" - ], - "visualize_v2": [ - "all" - ], - "savedQueryManagement": [ - "all" - ] + "securitySolutionCasesV2": ["all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"], + "osquery": ["all"], + "discover_v2": ["all"], + "dashboard_v2": ["all"], + "maps_v2": ["all"], + "visualize_v2": ["all"], + "savedQueryManagement": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -308,10 +200,7 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { "names": [ @@ -322,12 +211,7 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "read", - "write", - "maintenance", - "view_index_metadata" - ] + "privileges": ["read", "write", "maintenance", "view_index_metadata"] }, { "names": [ @@ -336,9 +220,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -346,40 +228,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV4": [ - "all", - "read_alerts", - "crud_alerts", - "endpoint_exceptions_all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ] + "ml": ["read"], + "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -403,10 +262,7 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "read", - "write" - ] + "privileges": ["read", "write"] }, { "names": [ @@ -417,11 +273,7 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "read", - "write", - "manage" - ] + "privileges": ["read", "write", "manage"] }, { "names": [ @@ -430,9 +282,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -440,40 +290,17 @@ "kibana": [ { "feature": { - "ml": [ - "read" - ], - "siemV4": [ - "all", - "read_alerts", - "crud_alerts", - "endpoint_exceptions_all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "all" - ], - "builtInAlerts": [ - "all" - ] + "ml": ["read"], + "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["all"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -481,9 +308,7 @@ "detections_admin": { "name": "detections_admin", "elasticsearch": { - "cluster": [ - "manage" - ], + "cluster": ["manage"], "indices": [ { "names": [ @@ -505,11 +330,7 @@ "winlogbeat-*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "manage", - "write", - "read" - ] + "privileges": ["manage", "write", "read"] }, { "names": [ @@ -518,9 +339,7 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -528,43 +347,18 @@ "kibana": [ { "feature": { - "ml": [ - "all" - ], - "siemV4": [ - "all", - "read_alerts", - "crud_alerts", - "endpoint_exceptions_all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "read" - ], - "builtInAlerts": [ - "all" - ], - "dev_tools": [ - "all" - ] + "ml": ["all"], + "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["read"], + "builtInAlerts": ["all"], + "dev_tools": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] @@ -572,18 +366,11 @@ "platform_engineer": { "name": "platform_engineer", "elasticsearch": { - "cluster": [ - "manage" - ], + "cluster": ["manage"], "indices": [ { - "names": [ - ".lists*", - ".items*" - ], - "privileges": [ - "all" - ] + "names": [".lists*", ".items*"], + "privileges": ["all"] }, { "names": [ @@ -600,9 +387,7 @@ ".fleet-actions*", ".asset-criticality.asset-criticality-*" ], - "privileges": [ - "all" - ] + "privileges": ["all"] }, { "names": [ @@ -613,17 +398,58 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": [ - "all" - ] + "privileges": ["all"] + }, + { + "names": [".entity_analytics.monitoring*"], + "privileges": ["read"] + } + ], + "run_as": [] + }, + "kibana": [ + { + "feature": { + "ml": ["all"], + "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["all"], + "securitySolutionTimeline": ["all"], + "securitySolutionNotes": ["all"], + "actions": ["all"], + "builtInAlerts": ["all"] + }, + "spaces": ["*"], + "base": [] + } + ] + }, + "readrules": { + "elasticsearch": { + "cluster": [], + "indices": [ + { + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] }, { "names": [ + "apm-*-transaction*", + "traces-apm*", + "auditbeat-*", + "endgame-*", + "filebeat-*", + "logs-*", + "packetbeat-*", + "winlogbeat-*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*", + ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": [ - "read" - ] + "privileges": ["read"] } ], "run_as": [] @@ -631,42 +457,65 @@ "kibana": [ { "feature": { - "ml": [ - "all" - ], - "siemV4": [ - "all", - "read_alerts", - "crud_alerts", - "endpoint_exceptions_all" - ], - "securitySolutionAssistant": [ - "all" - ], - "securitySolutionAttackDiscovery": [ - "all" - ], - "securitySolutionCasesV2": [ - "all" - ], - "securitySolutionTimeline": [ - "all" - ], - "securitySolutionNotes": [ - "all" - ], - "actions": [ - "all" + "siemV4": ["read", "read_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["read"], + "builtInAlerts": ["read"] + }, + "spaces": ["*"], + "base": [] + } + ] + }, + "editrules": { + "elasticsearch": { + "cluster": [], + "indices": [ + { + "names": [".alerts-security*", ".siem-signals-*"], + "privileges": ["read", "write", "maintenance"] + }, + { + "names": [ + "apm-*-transaction*", + "traces-apm*", + "auditbeat-*", + "endgame-*", + "filebeat-*", + "logs-*", + "packetbeat-*", + "winlogbeat-*", + "metrics-endpoint.metadata_current_*", + ".fleet-agents*", + ".fleet-actions*", + ".asset-criticality.asset-criticality-*", + ".entity_analytics.monitoring*" ], - "builtInAlerts": [ - "all" - ] + "privileges": ["read"] + } + ], + "run_as": [] + }, + "kibana": [ + { + "feature": { + "ml": ["read"], + "siemV4": ["all", "all_alerts"], + "securitySolutionAssistant": ["all"], + "securitySolutionAttackDiscovery": ["all"], + "securitySolutionCasesV2": ["read"], + "securitySolutionTimeline": ["read"], + "securitySolutionNotes": ["read"], + "actions": ["all"], + "builtInAlerts": ["all"] }, - "spaces": [ - "*" - ], + "spaces": ["*"], "base": [] } ] } -} \ No newline at end of file +} diff --git a/x-pack/platform/plugins/shared/alerting/common/constants/index.ts b/x-pack/platform/plugins/shared/alerting/common/constants/index.ts index 3e8978b61d6df..db190b8a13a00 100644 --- a/x-pack/platform/plugins/shared/alerting/common/constants/index.ts +++ b/x-pack/platform/plugins/shared/alerting/common/constants/index.ts @@ -18,3 +18,5 @@ export type { GapStatus } from './gap_status'; export { alertDeleteCategoryIds } from './alert_delete'; export type { BackfillInitiator } from './backfill'; export { backfillInitiator } from './backfill'; +export type { ValidReadAuthEditFields } from './valid_fields_with_read_auth'; +export { validFields } from './valid_fields_with_read_auth'; diff --git a/x-pack/platform/plugins/shared/alerting/common/constants/valid_fields_with_read_auth.ts b/x-pack/platform/plugins/shared/alerting/common/constants/valid_fields_with_read_auth.ts new file mode 100644 index 0000000000000..8b19f6eaeb5b9 --- /dev/null +++ b/x-pack/platform/plugins/shared/alerting/common/constants/valid_fields_with_read_auth.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/** + * used by the security solution + */ +export const validFields = { + EXCEPTIONS_LIST: 'exceptionsList', +} as const; + +export type ValidReadAuthEditFields = (typeof validFields)[keyof typeof validFields]; diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit_params/schemas/bulk_edit_rule_params_option_schemas.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit_params/schemas/bulk_edit_rule_params_option_schemas.ts index 39f90915325b2..884c21e0db676 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit_params/schemas/bulk_edit_rule_params_option_schemas.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/bulk_edit_params/schemas/bulk_edit_rule_params_option_schemas.ts @@ -5,9 +5,9 @@ * 2.0. */ import { schema } from '@kbn/config-schema'; +import { validFields } from '../../../../../../common/constants'; -const bulkEditExceptionListField = schema.literal('exceptionsList'); - +const bulkEditExceptionListField = schema.literal(validFields.EXCEPTIONS_LIST); export const bulkEditParamsOperationSchema = schema.object({ operation: schema.literal('set'), field: schema.oneOf([bulkEditExceptionListField]), diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts index b4653b328c39d..3fb0ced8e5e3b 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts @@ -14,12 +14,10 @@ import type { } from '../../../../../../../common/api/detection_engine/model/rule_schema'; import type { MlAuthz } from '../../../../../machine_learning/authz'; import type { IPrebuiltRuleAssetsClient } from '../../../../prebuilt_rules/logic/rule_assets/prebuilt_rule_assets_client'; -import { applyRulePatch } from '../mergers/apply_rule_patch'; import { getIdError } from '../../../utils/utils'; import { validateNonCustomizablePatchFields } from '../../../utils/validate'; import { convertAlertingRuleToRuleResponse } from '../converters/convert_alerting_rule_to_rule_response'; -import { convertRuleResponseToAlertingRule } from '../converters/convert_rule_response_to_alerting_rule'; -import { ClientError, toggleRuleEnabledOnUpdate, validateMlAuth } from '../utils'; +import { ClientError, validateMlAuth, patchApplicator } from '../utils'; import { getRuleByIdOrRuleId } from './get_rule_by_id_or_rule_id'; interface PatchRuleOptions { @@ -39,7 +37,7 @@ export const patchRule = async ({ }: PatchRuleOptions): Promise => { const { rule_id: ruleId, id } = rulePatch; - let existingRule = await getRuleByIdOrRuleId({ + const existingRule = await getRuleByIdOrRuleId({ rulesClient, ruleId, id, @@ -54,57 +52,12 @@ export const patchRule = async ({ validateNonCustomizablePatchFields(rulePatch, existingRule); - // Use alerting edit + read auth function - // for exceptions, then follow on with - // applying patch for other rule properties - if (rulePatch.exceptions_list != null) { - const ruleExceptionLists = existingRule.exceptions_list; - await rulesClient.bulkEditRuleParamsWithReadAuth({ - ids: [existingRule.id], - operations: [ - { - field: 'exceptionsList', - operation: 'set', - value: [ - ...ruleExceptionLists, - ...rulePatch.exceptions_list.map((exceptionList) => ({ - id: exceptionList.id, - list_id: exceptionList.list_id, - type: exceptionList.type, - namespace_type: exceptionList.namespace_type, - })), - ], - }, - ], - }); - // TODO: clean up - delete rulePatch.exceptions_list; - existingRule = await getRuleByIdOrRuleId({ - rulesClient, - ruleId, - id, - }); - // have to follow up the fetch rule with this code - // or else typescript complains in other areas we - // use existingRule - if (existingRule == null) { - const error = getIdError({ id, ruleId }); - throw new ClientError(error.message, error.statusCode); - } - } - - const patchedRule = await applyRulePatch({ - prebuiltRuleAssetClient, - existingRule, + const appliedInternalPatches = await patchApplicator( + rulesClient, + actionsClient, rulePatch, - }); - - const patchedInternalRule = await rulesClient.update({ - id: existingRule.id, - data: convertRuleResponseToAlertingRule(patchedRule, actionsClient), - }); - - const { enabled } = await toggleRuleEnabledOnUpdate(rulesClient, existingRule, patchedRule); - - return convertAlertingRuleToRuleResponse({ ...patchedInternalRule, enabled }); + existingRule, + prebuiltRuleAssetClient + ); + return convertAlertingRuleToRuleResponse(appliedInternalPatches); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.test.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.test.ts index 8f8aff876a950..5ebe920ba5251 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.test.ts @@ -6,111 +6,120 @@ */ import { getRulesSchemaMock } from '../../../../../../common/api/detection_engine/model/rule_schema/rule_response_schema.mock'; -import { mergeExceptionLists } from './utils'; +import { mergeExceptionLists, isEveryReadKeyValid } from './utils'; -describe('mergeExceptionLists', () => { - test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { - const ruleAsset1 = getRulesSchemaMock(); - ruleAsset1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleAsset1.rule_id = 'rule-1'; - ruleAsset1.version = 2; +describe('utils', () => { + describe('mergeExceptionLists', () => { + test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { + const ruleAsset1 = getRulesSchemaMock(); + ruleAsset1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleAsset1.rule_id = 'rule-1'; + ruleAsset1.version = 2; - const installedRule1 = getRulesSchemaMock(); - installedRule1.rule_id = 'rule-1'; - installedRule1.version = 1; - installedRule1.exceptions_list = []; + const installedRule1 = getRulesSchemaMock(); + installedRule1.rule_id = 'rule-1'; + installedRule1.version = 1; + installedRule1.exceptions_list = []; - const update = mergeExceptionLists(ruleAsset1, installedRule1); - expect(update.exceptions_list).toEqual(ruleAsset1.exceptions_list); - }); + const update = mergeExceptionLists(ruleAsset1, installedRule1); + expect(update.exceptions_list).toEqual(ruleAsset1.exceptions_list); + }); - test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { - const ruleAsset1 = getRulesSchemaMock(); - ruleAsset1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleAsset1.rule_id = 'rule-1'; - ruleAsset1.version = 2; + test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { + const ruleAsset1 = getRulesSchemaMock(); + ruleAsset1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleAsset1.rule_id = 'rule-1'; + ruleAsset1.version = 2; - const installedRule1 = getRulesSchemaMock(); - installedRule1.rule_id = 'rule-1'; - installedRule1.version = 1; - installedRule1.exceptions_list = [ - { - id: 'second_exception_list', - list_id: 'some-other-id', - namespace_type: 'single', - type: 'detection', - }, - ]; + const installedRule1 = getRulesSchemaMock(); + installedRule1.rule_id = 'rule-1'; + installedRule1.version = 1; + installedRule1.exceptions_list = [ + { + id: 'second_exception_list', + list_id: 'some-other-id', + namespace_type: 'single', + type: 'detection', + }, + ]; - const update = mergeExceptionLists(ruleAsset1, installedRule1); - expect(update.exceptions_list).toEqual([ - ...ruleAsset1.exceptions_list, - ...installedRule1.exceptions_list, - ]); - }); + const update = mergeExceptionLists(ruleAsset1, installedRule1); + expect(update.exceptions_list).toEqual([ + ...ruleAsset1.exceptions_list, + ...installedRule1.exceptions_list, + ]); + }); - test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { - const ruleAsset1 = getRulesSchemaMock(); - ruleAsset1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; - ruleAsset1.rule_id = 'rule-1'; - ruleAsset1.version = 2; + test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { + const ruleAsset1 = getRulesSchemaMock(); + ruleAsset1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; + ruleAsset1.rule_id = 'rule-1'; + ruleAsset1.version = 2; - const installedRule1 = getRulesSchemaMock(); - installedRule1.rule_id = 'rule-1'; - installedRule1.version = 1; - installedRule1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; + const installedRule1 = getRulesSchemaMock(); + installedRule1.rule_id = 'rule-1'; + installedRule1.version = 1; + installedRule1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; - const update = mergeExceptionLists(ruleAsset1, installedRule1); - expect(update.exceptions_list).toEqual(ruleAsset1.exceptions_list); - }); + const update = mergeExceptionLists(ruleAsset1, installedRule1); + expect(update.exceptions_list).toEqual(ruleAsset1.exceptions_list); + }); - test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { - const ruleAsset1 = getRulesSchemaMock(); - ruleAsset1.exceptions_list = []; - ruleAsset1.rule_id = 'rule-1'; - ruleAsset1.version = 2; + test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { + const ruleAsset1 = getRulesSchemaMock(); + ruleAsset1.exceptions_list = []; + ruleAsset1.rule_id = 'rule-1'; + ruleAsset1.version = 2; - const installedRule1 = getRulesSchemaMock(); - installedRule1.rule_id = 'rule-1'; - installedRule1.version = 1; - installedRule1.exceptions_list = [ - { - id: 'endpoint_list', - list_id: 'endpoint_list', - namespace_type: 'agnostic', - type: 'endpoint', - }, - ]; + const installedRule1 = getRulesSchemaMock(); + installedRule1.rule_id = 'rule-1'; + installedRule1.version = 1; + installedRule1.exceptions_list = [ + { + id: 'endpoint_list', + list_id: 'endpoint_list', + namespace_type: 'agnostic', + type: 'endpoint', + }, + ]; - const update = mergeExceptionLists(ruleAsset1, installedRule1); - expect(update.exceptions_list).toEqual(installedRule1.exceptions_list); + const update = mergeExceptionLists(ruleAsset1, installedRule1); + expect(update.exceptions_list).toEqual(installedRule1.exceptions_list); + }); + }); + describe('validReadAuthzFields', () => { + it('should accept valid fields', () => { + expect( + Object.keys({ exceptions_list: 'test value' }).every((key) => isEveryReadKeyValid(key)) + ).toBe(true); + }); }); }); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts index 61e1b73ec8c51..7cd8492348480 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts @@ -7,14 +7,24 @@ /* eslint-disable max-classes-per-file */ -import type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { BulkOperationError, RulesClient } from '@kbn/alerting-plugin/server'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import { camelCase, isEmpty } from 'lodash'; +import type { ValidReadAuthEditFields } from '@kbn/alerting-plugin/common/constants'; +import { validFields } from '@kbn/alerting-plugin/common/constants'; +import type { ActionsClient } from '@kbn/actions-plugin/server'; +import type { BulkEditResult } from '@kbn/alerting-plugin/server/rules_client/common/bulk_edit/types'; + import type { MlAuthz } from '../../../../machine_learning/authz'; import type { RuleSignatureId } from '../../../../../../common/api/detection_engine/model/rule_schema/common_attributes.gen'; import { throwAuthzError } from '../../../../machine_learning/validation'; -import type { RuleResponse } from '../../../../../../common/api/detection_engine'; +import type { RulePatchProps, RuleResponse } from '../../../../../../common/api/detection_engine'; +import type { RuleParams } from '../../../rule_schema'; +import { convertRuleResponseToAlertingRule } from './converters/convert_rule_response_to_alerting_rule'; +import type { IPrebuiltRuleAssetsClient } from '../../../prebuilt_rules/logic/rule_assets/prebuilt_rule_assets_client'; +import { applyRulePatch } from './mergers/apply_rule_patch'; export const toggleRuleEnabledOnUpdate = async ( rulesClient: RulesClient, @@ -93,3 +103,142 @@ export const mergeExceptionLists = ( return latestPrebuiltRule; } }; + +/** + * Typeguard to determine if given key is one of + * valid string literals for editable rule fields + * with read authz + * @param someKey unknown + * @returns boolean + */ +export const isEveryReadKeyValid = (someKey: unknown): someKey is ValidReadAuthEditFields => + someKey != null && + typeof someKey === 'string' && + Object.values(validFields).includes(camelCase(someKey) as ValidReadAuthEditFields); + +/** + * utility for throwing errors found in bulk patch response + * @param appliedPatchesWithReadPrivs Array> + */ +export const gatherErrors = (appliedPatchesWithReadPrivs: Array>) => { + if ( + appliedPatchesWithReadPrivs.some( + (patchResp) => patchResp.errors != null || !isEmpty(patchResp.errors) + ) + ) { + // gather errors + const errors = appliedPatchesWithReadPrivs.reduce((acc, patches) => { + const theErrors = patches.errors; + return patches.errors != null ? acc.concat(theErrors) : acc; + }, [] as BulkOperationError[]); + throw new Error(errors.reduce((acc, error) => `${acc}\n${error.message}`, '')); + } +}; + +/** + * Generate parameter for editable rule field + * with read authz + * @param field + * @param rulePatch + * @param existingRule + * @returns + */ +export const getReadAuthFieldValue = ( + field: string, + rulePatch: RulePatchProps, + existingRule: RuleResponse +) => { + if ( + camelCase(field) === validFields.EXCEPTIONS_LIST && + !isEmpty(rulePatch.exceptions_list) && + rulePatch.exceptions_list != null + ) { + const ruleExceptionLists = existingRule.exceptions_list; + return [ + ...ruleExceptionLists, + ...rulePatch.exceptions_list.map((exceptionList) => ({ + id: exceptionList.id, + list_id: exceptionList.list_id, + type: exceptionList.type, + namespace_type: exceptionList.namespace_type, + })), + ]; + } +}; + +/** + * Applies the `bulkEditRUleParamsWithReadAuth` function + * to patch rule field values + * @param rulesClient + * @param rulePatch + * @param existingRule + * @returns + */ +export const applyPatchRuleWithReadPrivileges = async ( + rulesClient: RulesClient, + rulePatch: RulePatchProps, // make this a type + existingRule: RuleResponse +): Promise>> => { + const validFieldValues = Object.values(validFields); + return Promise.all( + validFieldValues.map(async (field) => + rulesClient.bulkEditRuleParamsWithReadAuth({ + ids: [existingRule.id], + operations: [ + { + field, + operation: 'set', + value: getReadAuthFieldValue(field, rulePatch, existingRule), + }, + ], + }) + ) + ); +}; + +/** + * Determines which patch function to apply to + * the rule object based on the fields we are patching + * + * If the fields are all included in the `validFields` type + * we can check if the user has read authz privileges for rules + * and use the special function provided to us by the alerting + * rules client. Otherwise the user will need `all` privilegs + * for rules. + * properties we are patching on the rule. + * @param rulesClient + * @param rulePatch + * @param existingRule + * @returns SanitizedRule + */ +export const patchApplicator = async ( + rulesClient: RulesClient, + actionsClient: ActionsClient, + rulePatch: RulePatchProps, + existingRule: RuleResponse, + prebuiltRuleAssetClient: IPrebuiltRuleAssetsClient +) => { + if (Object.keys(rulePatch).every((key) => isEveryReadKeyValid(key))) { + const appliedPatchesWithReadPrivs: Array> = + await applyPatchRuleWithReadPrivileges(rulesClient, rulePatch, existingRule); + + // gather and throw errors from bulk operation + gatherErrors(appliedPatchesWithReadPrivs); + return appliedPatchesWithReadPrivs[0].rules[0]; + } else { + const patchedRule = await applyRulePatch({ + prebuiltRuleAssetClient, + existingRule, + rulePatch, + }); + + const patchedInternalRule = await rulesClient.update({ + id: existingRule.id, + data: convertRuleResponseToAlertingRule(patchedRule, actionsClient), + }); + + const { enabled } = await toggleRuleEnabledOnUpdate(rulesClient, existingRule, patchedRule); + + return { ...patchedInternalRule, enabled }; + } +}; From e27b5733eea10f383de5367d276f2ea26dd95010 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Mon, 1 Dec 2025 17:48:45 +0100 Subject: [PATCH 64/85] fix: privs --- .../siem_migrations/rules/service/capabilities.ts | 12 ++++++------ .../lib/siem_migrations/common/api/util/authz.ts | 2 +- .../lib/siem_migrations/dashboards/api/create.ts | 2 +- .../dashboards/api/dashboards/create.ts | 2 +- .../dashboards/api/dashboards/get.ts | 2 +- .../lib/siem_migrations/dashboards/api/delete.ts | 2 +- .../dashboards/api/evaluation/evaluate.ts | 2 +- .../lib/siem_migrations/dashboards/api/get.ts | 2 +- .../lib/siem_migrations/dashboards/api/install.ts | 2 +- .../siem_migrations/dashboards/api/resources/get.ts | 2 +- .../dashboards/api/resources/missing.ts | 2 +- .../dashboards/api/resources/upsert.ts | 2 +- .../lib/siem_migrations/dashboards/api/start.ts | 2 +- .../lib/siem_migrations/dashboards/api/stats.ts | 2 +- .../lib/siem_migrations/dashboards/api/stats_all.ts | 2 +- .../lib/siem_migrations/dashboards/api/stop.ts | 2 +- .../dashboards/api/translation_stats.ts | 2 +- .../lib/siem_migrations/dashboards/api/update.ts | 2 +- .../siem_migrations/dashboards/api/util/authz.ts | 12 ++++++++++++ .../server/lib/siem_migrations/rules/api/create.ts | 2 +- .../server/lib/siem_migrations/rules/api/delete.ts | 2 +- .../rules/api/evaluation/evaluate.ts | 2 +- .../server/lib/siem_migrations/rules/api/get.ts | 2 +- .../siem_migrations/rules/api/get_integrations.ts | 2 +- .../siem_migrations/rules/api/get_prebuilt_rules.ts | 2 +- .../server/lib/siem_migrations/rules/api/install.ts | 2 +- .../siem_migrations/rules/api/integrations_stats.ts | 2 +- .../rules/api/privileges/get_missing_privileges.ts | 2 +- .../lib/siem_migrations/rules/api/resources/get.ts | 2 +- .../siem_migrations/rules/api/resources/missing.ts | 2 +- .../siem_migrations/rules/api/resources/upsert.ts | 2 +- .../lib/siem_migrations/rules/api/rules/create.ts | 2 +- .../lib/siem_migrations/rules/api/rules/get.ts | 2 +- .../rules/api/rules/qradar/create.ts | 2 +- .../lib/siem_migrations/rules/api/rules/update.ts | 2 +- .../server/lib/siem_migrations/rules/api/start.ts | 2 +- .../server/lib/siem_migrations/rules/api/stats.ts | 2 +- .../lib/siem_migrations/rules/api/stats_all.ts | 2 +- .../server/lib/siem_migrations/rules/api/stop.ts | 2 +- .../siem_migrations/rules/api/translation_stats.ts | 2 +- .../server/lib/siem_migrations/rules/api/update.ts | 2 +- .../rules/api/update_index_pattern.ts | 2 +- .../lib/siem_migrations/rules/api/util/authz.ts | 13 +++++++++++++ 43 files changed, 71 insertions(+), 46 deletions(-) create mode 100644 x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/util/authz.ts create mode 100644 x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/util/authz.ts diff --git a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts index 99c6c88eab421..c28f9d94a0b9e 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/siem_migrations/rules/service/capabilities.ts @@ -7,8 +7,8 @@ import { i18n } from '@kbn/i18n'; import { + RULES_UI_EDIT_PRIVILEGE, RULES_UI_READ_PRIVILEGE, - SIEM_MIGRATIONS_FEATURE_ID, } from '@kbn/security-solution-features/constants'; import { requiredSiemMigrationCapabilities, @@ -16,7 +16,7 @@ import { type MissingCapability, } from '../../common/service/capabilities'; -const allRuleMigrationCapabilities: MissingCapability[] = [ +const minimumRuleMigrationCapabilities: MissingCapability[] = [ { capability: RULES_UI_READ_PRIVILEGE, description: i18n.translate( @@ -26,12 +26,12 @@ const allRuleMigrationCapabilities: MissingCapability[] = [ }, ]; -const minimumRuleMigrationCapabilities: MissingCapability[] = [ +const allRuleMigrationCapabilities: MissingCapability[] = [ { - capability: `${SIEM_MIGRATIONS_FEATURE_ID}.all`, + capability: RULES_UI_EDIT_PRIVILEGE, description: i18n.translate( - 'xpack.securitySolution.siemMigrations.service.capabilities.siemMigrationsAll', - { defaultMessage: 'Security > SIEM migrations: All' } + 'xpack.securitySolution.siemMigrations.service.capabilities.rulesAll', + { defaultMessage: 'Security > Rules: All' } ), }, ]; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts index 8513addb5b064..83e958d439b59 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts @@ -8,6 +8,6 @@ import { SIEM_MIGRATIONS_API_ACTION_ALL } from '@kbn/security-solution-features/actions'; import { RULES_API_READ } from '@kbn/security-solution-features/constants'; -export const authz = { +export const commonAuthz = { requiredPrivileges: [RULES_API_READ, SIEM_MIGRATIONS_API_ACTION_ALL], }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/create.ts index 399c44354d42d..d316b866007ac 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/create.ts @@ -10,7 +10,7 @@ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import type { IKibanaResponse } from '@kbn/core/server'; import { SIEM_DASHBOARD_MIGRATIONS_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import type { CreateDashboardMigrationResponse } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { CreateDashboardMigrationRequestBody } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { withLicense } from '../../common/api/util/with_license'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/create.ts index e2e13b29b0ec8..54f3e6ccfe524 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/create.ts @@ -15,7 +15,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_DASHBOARDS_PATH } from '../../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import type { CreateMigrationItemInput } from '../../../common/data/siem_migrations_data_item_client'; import { DashboardResourceIdentifier } from '../../../../../../common/siem_migrations/dashboards/resources'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/get.ts index 2b7b2a52c4812..e01e68298d7ee 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/dashboards/get.ts @@ -15,7 +15,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_DASHBOARDS_PATH } from '../../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/delete.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/delete.ts index 53d96b801bd0c..4763d2feb4db0 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/delete.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/delete.ts @@ -10,7 +10,7 @@ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { DeleteDashboardMigrationRequestParams } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/evaluation/evaluate.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/evaluation/evaluate.ts index a3bd7b0738aaa..29518cfece843 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/evaluation/evaluate.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/evaluation/evaluate.ts @@ -13,7 +13,7 @@ import { DashboardMigrationTaskExecutionSettings } from '../../../../../../commo import { LangSmithEvaluationOptions } from '../../../../../../common/siem_migrations/model/common.gen'; import { SIEM_DASHBOARD_MIGRATION_EVALUATE_PATH } from '../../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; const REQUEST_TIMEOUT = 10 * 60 * 1000; // 10 minutes diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/get.ts index fc8214b1444aa..232aaf3e15cb7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/get.ts @@ -11,7 +11,7 @@ import type { GetDashboardMigrationResponse } from '../../../../../common/siem_m import { GetDashboardMigrationRequestParams } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; import { withLicense } from '../../common/api/util/with_license'; import { MIGRATION_ID_NOT_FOUND } from '../../common/translations'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/install.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/install.ts index 5ee1a17c726a9..0f129aa4ed007 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/install.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/install.ts @@ -14,7 +14,7 @@ import { InstallMigrationDashboardsRequestBody, InstallMigrationDashboardsRequestParams, } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/get.ts index 5410fffe70a79..56805f00a9202 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/get.ts @@ -15,7 +15,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/missing.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/missing.ts index a5e0370eb2b23..450039e99b873 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/missing.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/missing.ts @@ -15,7 +15,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_RESOURCES_MISSING_PATH } from '../../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/upsert.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/upsert.ts index d98734e1066f3..f1c9eed0e0ee1 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/upsert.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/resources/upsert.ts @@ -17,7 +17,7 @@ import { import { DashboardResourceIdentifier } from '../../../../../../common/siem_migrations/dashboards/resources'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import type { CreateSiemMigrationResourceInput } from '../../../common/data/siem_migrations_data_resources_client'; import { processLookups } from '../../../rules/api/util/lookups'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/start.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/start.ts index 4886c75f177c0..05e7760914154 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/start.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/start.ts @@ -15,7 +15,7 @@ import { } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { getRetryFilter } from '../../common/api/util/retry'; import { withLicense } from '../../common/api/util/with_license'; import { createTracersCallbacks } from '../../common/api/util/tracing'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats.ts index a775f9501e34f..eb69f17fc8d43 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats.ts @@ -12,7 +12,7 @@ import { GetDashboardMigrationStatsRequestParams } from '../../../../../common/s import { SIEM_DASHBOARD_MIGRATION_STATS_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { withLicense } from '../../common/api/util/with_license'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; export const registerSiemDashboardMigrationsStatsRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats_all.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats_all.ts index 87698d5f91ae1..da57aeadd8ef7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats_all.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stats_all.ts @@ -9,7 +9,7 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import type { GetAllDashboardMigrationsStatsResponse } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATIONS_ALL_STATS_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; export const registerSiemDashboardMigrationsStatsAllRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stop.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stop.ts index 8a9bde444c4a6..8cd6662f66c34 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stop.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/stop.ts @@ -14,7 +14,7 @@ import { } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/translation_stats.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/translation_stats.ts index c9990b288d362..ffd0163113a92 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/translation_stats.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/translation_stats.ts @@ -11,7 +11,7 @@ import type { GetAllTranslationStatsDashboardMigrationResponse } from '../../../ import { GetAllTranslationStatsDashboardMigrationRequestParams } from '../../../../../common/siem_migrations/model/api/dashboards/dashboard_migration.gen'; import { SIEM_DASHBOARD_MIGRATION_TRANSLATION_STATS_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/update.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/update.ts index e2278e4e0f1a2..c2bc8e3794ba2 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/update.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/update.ts @@ -10,7 +10,7 @@ import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; import { SIEM_DASHBOARD_MIGRATION_PATH } from '../../../../../common/siem_migrations/dashboards/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { UpdateDashboardMigrationRequestParams, diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/util/authz.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/util/authz.ts new file mode 100644 index 0000000000000..c2d5a18c935aa --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/dashboards/api/util/authz.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SIEM_MIGRATIONS_API_ACTION_ALL } from '@kbn/security-solution-features/actions'; + +export const authz = { + requiredPrivileges: [SIEM_MIGRATIONS_API_ACTION_ALL], +}; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/create.ts index 1088605f491f1..1bb917b85f82d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/create.ts @@ -14,7 +14,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; export const registerSiemRuleMigrationsCreateRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/delete.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/delete.ts index d0f668af01ef2..e684a10446ff5 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/delete.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/delete.ts @@ -11,7 +11,7 @@ import { SIEM_RULE_MIGRATION_PATH } from '../../../../../common/siem_migrations/ import { GetRuleMigrationRequestParams } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/evaluation/evaluate.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/evaluation/evaluate.ts index 30f59987ce653..7858441dc07d6 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/evaluation/evaluate.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/evaluation/evaluate.ts @@ -13,7 +13,7 @@ import { RuleMigrationTaskExecutionSettings } from '../../../../../../common/sie import { LangSmithEvaluationOptions } from '../../../../../../common/siem_migrations/model/common.gen'; import { SIEM_RULE_MIGRATION_EVALUATE_PATH } from '../../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; const REQUEST_TIMEOUT = 10 * 60 * 1000; // 10 minutes diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts index 0054358f3bc94..5771dc5f052ac 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get.ts @@ -12,7 +12,7 @@ import type { GetRuleMigrationResponse } from '../../../../../common/siem_migrat import { GetRuleMigrationRequestParams } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { MIGRATION_ID_NOT_FOUND } from '../../common/translations'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_integrations.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_integrations.ts index ad476eae401e5..4ba3b6603bba7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_integrations.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_integrations.ts @@ -10,7 +10,7 @@ import type { RelatedIntegration } from '../../../../../common/api/detection_eng import { type GetRuleMigrationIntegrationsResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATIONS_INTEGRATIONS_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; export const registerSiemRuleMigrationsIntegrationsRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_prebuilt_rules.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_prebuilt_rules.ts index 7b7ed9b175d49..09a5c5bd185a7 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_prebuilt_rules.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/get_prebuilt_rules.ts @@ -11,7 +11,7 @@ import type { GetRuleMigrationPrebuiltRulesResponse } from '../../../../../commo import { GetRuleMigrationPrebuiltRulesRequestParams } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATIONS_PREBUILT_RULES_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { getPrebuiltRulesForMigration } from './util/prebuilt_rules'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/install.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/install.ts index 9ddd43508d63e..960af90a7d0c0 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/install.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/install.ts @@ -16,7 +16,7 @@ import { import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; import { installTranslated } from './util/installation'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; export const registerSiemRuleMigrationsInstallRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/integrations_stats.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/integrations_stats.ts index 9a4ae0b394d6a..3f4af9eb4ba2e 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/integrations_stats.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/integrations_stats.ts @@ -9,7 +9,7 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import { type GetRuleMigrationIntegrationsStatsResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATIONS_INTEGRATIONS_STATS_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/privileges/get_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/privileges/get_missing_privileges.ts index dedf72953ffe6..2f81ced4ba1d1 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/privileges/get_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/privileges/get_missing_privileges.ts @@ -13,7 +13,7 @@ import { LOOKUPS_INDEX_PREFIX, } from '../../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; export const registerSiemRuleMigrationsGetMissingPrivilegesRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/get.ts index c4c033cde65c2..006529193446d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/get.ts @@ -15,7 +15,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; export const registerSiemRuleMigrationsResourceGetRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/missing.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/missing.ts index a3090e4ca2c6e..6aae284ec4642 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/missing.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/missing.ts @@ -14,7 +14,7 @@ import { } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_RESOURCES_MISSING_PATH } from '../../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; export const registerSiemRuleMigrationsResourceGetMissingRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts index 3e84d6b82221b..04e8e81ea221b 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/resources/upsert.ts @@ -18,7 +18,7 @@ import { import { RuleResourceIdentifier } from '../../../../../../common/siem_migrations/rules/resources'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { processLookups } from '../util/lookups'; import { withLicense } from '../../../common/api/util/with_license'; import type { CreateSiemMigrationResourceInput } from '../../../common/data/siem_migrations_data_resources_client'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/create.ts index 56d96fe9d10d3..a5998e5012a20 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/create.ts @@ -18,7 +18,7 @@ import { RuleResourceIdentifier } from '../../../../../../common/siem_migrations import type { SecuritySolutionPluginRouter } from '../../../../../types'; import type { CreateRuleMigrationRulesInput } from '../../data/rule_migrations_data_rules_client'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; import { withLicense } from '../../../common/api/util/with_license'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/get.ts index df5676154ffc3..412eb656d6f1b 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/get.ts @@ -16,7 +16,7 @@ import { import type { SecuritySolutionPluginRouter } from '../../../../../types'; import type { RuleMigrationGetRulesOptions } from '../../data/rule_migrations_data_rules_client'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { withLicense } from '../../../common/api/util/with_license'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/qradar/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/qradar/create.ts index 16f929d6a6f21..273656207b423 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/qradar/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/qradar/create.ts @@ -16,7 +16,7 @@ import { QradarRulesXmlParser } from '../../../../../../../common/siem_migration import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import type { CreateRuleMigrationRulesInput } from '../../../data/rule_migrations_data_rules_client'; import { SiemMigrationAuditLogger } from '../../../../common/api/util/audit'; -import { authz } from '../../../../common/api/util/authz'; +import { authz } from '../../util/authz'; import { withExistingMigration } from '../../../../common/api/util/with_existing_migration_id'; import { withLicense } from '../../../../common/api/util/with_license'; import { transformQRadarRuleToOriginalRule } from '../../util/qradar_transform'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/update.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/update.ts index c6e4559c9a51d..3a85859103a99 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/update.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/update.ts @@ -14,7 +14,7 @@ import { UpdateRuleMigrationRulesRequestParams, } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; import { transformToInternalUpdateRuleMigrationData } from '../util/update_rules'; import { withLicense } from '../../../common/api/util/with_license'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts index be4a90fad04a4..2feb322aff3f2 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/start.ts @@ -15,7 +15,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { getRetryFilter } from '../../common/api/util/retry'; import { withLicense } from '../../common/api/util/with_license'; import { createTracersCallbacks } from '../../common/api/util/tracing'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats.ts index ebf49e1cf030e..21b4efe34673e 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats.ts @@ -13,7 +13,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_STATS_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats_all.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats_all.ts index d169caa82b57a..1bf206a828d09 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats_all.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stats_all.ts @@ -9,7 +9,7 @@ import type { IKibanaResponse, Logger } from '@kbn/core/server'; import type { GetAllStatsRuleMigrationResponse } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATIONS_ALL_STATS_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; export const registerSiemRuleMigrationsStatsAllRoute = ( diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stop.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stop.ts index d0ebf3d2dfef9..3905b60d744f5 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stop.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/stop.ts @@ -14,7 +14,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/translation_stats.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/translation_stats.ts index f45a8a35a6a88..2f19237e670ee 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/translation_stats.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/translation_stats.ts @@ -11,7 +11,7 @@ import type { GetRuleMigrationTranslationStatsResponse } from '../../../../../co import { GetRuleMigrationTranslationStatsRequestParams } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_TRANSLATION_STATS_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update.ts index 6a941c397fe07..3bbdc8915f2c1 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update.ts @@ -14,7 +14,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update_index_pattern.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update_index_pattern.ts index f83132bb1b95f..4b6034270d0a9 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update_index_pattern.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/update_index_pattern.ts @@ -14,7 +14,7 @@ import { } from '../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import { SIEM_RULE_MIGRATION_UPDATE_INDEX_PATTERN_PATH } from '../../../../../common/siem_migrations/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { authz } from '../../common/api/util/authz'; +import { authz } from './util/authz'; import { withLicense } from '../../common/api/util/with_license'; import { withExistingMigration } from '../../common/api/util/with_existing_migration_id'; import { SiemMigrationAuditLogger } from '../../common/api/util/audit'; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/util/authz.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/util/authz.ts new file mode 100644 index 0000000000000..8513addb5b064 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/util/authz.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SIEM_MIGRATIONS_API_ACTION_ALL } from '@kbn/security-solution-features/actions'; +import { RULES_API_READ } from '@kbn/security-solution-features/constants'; + +export const authz = { + requiredPrivileges: [RULES_API_READ, SIEM_MIGRATIONS_API_ACTION_ALL], +}; From 0efc4943538cfe987df6c8995002ba9626b9cb35 Mon Sep 17 00:00:00 2001 From: Jatin Kathuria Date: Mon, 1 Dec 2025 17:53:06 +0100 Subject: [PATCH 65/85] remove unnecessary file --- .../lib/siem_migrations/common/api/util/authz.ts | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts deleted file mode 100644 index 83e958d439b59..0000000000000 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/common/api/util/authz.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { SIEM_MIGRATIONS_API_ACTION_ALL } from '@kbn/security-solution-features/actions'; -import { RULES_API_READ } from '@kbn/security-solution-features/constants'; - -export const commonAuthz = { - requiredPrivileges: [RULES_API_READ, SIEM_MIGRATIONS_API_ACTION_ALL], -}; From 49b139c550288a7c53d0a5058718718fa4a48a5e Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Mon, 1 Dec 2025 14:17:08 -0600 Subject: [PATCH 66/85] Grant 'alerting.alert.all' privileges to rules:read users In order to maintain backwards compatibility with alert privileges for existing SIEM users, we need more than `alert.read` for `siem:read` users`. Since our only other option is `alert.all`, we instead grant them this privilege (although arguably this is more access than they previously had). However, once the `securityAlerts` privilege work is complete, `securityAlerts.all` will be pared down to precisely what is needed for security users. Discussion around this change can be found [here](https://github.com/elastic/kibana/pull/239634/files/632bbc0e8c2597ae9f676123d6ecd09b644bbf73#r2510764307). --- .../security/packages/features/src/rules/kibana_features.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts index 04f3f35553316..a9b25c38aa40d 100644 --- a/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/kibana_features.ts @@ -115,7 +115,7 @@ export const getRulesBaseKibanaFeature = ( }, alerting: { rule: { read: alertingFeatures }, - alert: { read: alertingFeatures }, + alert: { all: alertingFeatures }, }, management: { insightsAndAlerting: ['triggersActions'], // Access to the stack rules management UI From 110938b0afe1879ebf815381910b3262a3ba5514 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Mon, 1 Dec 2025 15:34:26 -0600 Subject: [PATCH 67/85] Add missing Defend privileges to siemV5 These were deleted before siemv5 was defined, then added back since. Luckily we have tests verifying the fact that these privileges are "replaced." --- .../features/src/security/v5_features/kibana_features.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts index 2c0e3577839d9..1d6a11166e6c7 100644 --- a/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/security/v5_features/kibana_features.ts @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common'; import { APP_ID, + CLOUD_DEFEND_APP_ID, CLOUD_POSTURE_APP_ID, INITIALIZE_SECURITY_SOLUTION, LISTS_API_ALL, @@ -35,7 +36,7 @@ export const getSecurityV5BaseKibanaFeature = ({ ), order: 1100, category: DEFAULT_APP_CATEGORIES.security, - app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + app: [APP_ID, CLOUD_POSTURE_APP_ID, CLOUD_DEFEND_APP_ID, 'kibana'], catalogue: [APP_ID], description: i18n.translate( 'securitySolutionPackages.features.featureRegistry.securityGroupDescription', @@ -46,7 +47,7 @@ export const getSecurityV5BaseKibanaFeature = ({ ), privileges: { all: { - app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + app: [APP_ID, CLOUD_POSTURE_APP_ID, CLOUD_DEFEND_APP_ID, 'kibana'], catalogue: [APP_ID], api: [ APP_ID, @@ -64,7 +65,7 @@ export const getSecurityV5BaseKibanaFeature = ({ ui: [SECURITY_UI_SHOW, SECURITY_UI_CRUD], }, read: { - app: [APP_ID, CLOUD_POSTURE_APP_ID, 'kibana'], + app: [APP_ID, CLOUD_POSTURE_APP_ID, CLOUD_DEFEND_APP_ID, 'kibana'], catalogue: [APP_ID], api: [APP_ID, 'rac', LISTS_API_READ, USERS_API_READ, INITIALIZE_SECURITY_SOLUTION], savedObject: { From 8bcc70d2fb0682e69a1ce625105b02362602c651 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Mon, 1 Dec 2025 18:36:06 -0500 Subject: [PATCH 68/85] hides exceptions tab in rule details based on permissions --- .../use_rule_details_tabs.test.tsx | 27 ++++++++++++++++++- .../rule_details/use_rule_details_tabs.tsx | 14 +++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.test.tsx index 6f616f23d1cec..470f0918ce519 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.test.tsx @@ -11,12 +11,17 @@ import { RuleDetailTabs, useRuleDetailsTabs } from './use_rule_details_tabs'; import type { Rule } from '../../../rule_management/logic'; import { useRuleExecutionSettings } from '../../../rule_monitoring'; import { useEndpointExceptionsCapability } from '../../../../exceptions/hooks/use_endpoint_exceptions_capability'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; +import { getUserPrivilegesMockDefaultValue } from '../../../../common/components/user_privileges/__mocks__'; +import { initialUserPrivilegesState } from '../../../../common/components/user_privileges/user_privileges_context'; jest.mock('../../../rule_monitoring'); jest.mock('../../../../exceptions/hooks/use_endpoint_exceptions_capability'); +jest.mock('../../../../common/components/user_privileges'); const mockUseRuleExecutionSettings = useRuleExecutionSettings as jest.Mock; const mockUseEndpointExceptionsCapability = useEndpointExceptionsCapability as jest.Mock; +const mockUseUserPrivileges = useUserPrivileges as jest.Mock; const mockRule: Rule = { id: 'myfakeruleid', @@ -65,6 +70,7 @@ describe('useRuleDetailsTabs', () => { }, }); mockUseEndpointExceptionsCapability.mockReturnValue(true); + mockUseUserPrivileges.mockReturnValue(getUserPrivilegesMockDefaultValue()); }); beforeEach(() => { @@ -90,7 +96,26 @@ describe('useRuleDetailsTabs', () => { expect(tabsNames).not.toContain(RuleDetailTabs.alerts); }); - it('always returns ths rule exception tab ', async () => { + it('does not render the rule exception tab if the user does not have read permissions', async () => { + const tabs = render({ + rule: mockRule, + ruleId: mockRule.rule_id, + isExistingRule: true, + hasIndexRead: true, + }); + const tabsNames = Object.keys(tabs.result.current); + + expect(tabsNames).not.toContain(RuleDetailTabs.exceptions); + }); + + it('renders the rule exception tab if the user has read permissions', async () => { + mockUseUserPrivileges.mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { + ...initialUserPrivilegesState().rulesPrivileges, + exceptions: { read: true, crud: false }, + }, + }); const tabs = render({ rule: mockRule, ruleId: mockRule.rule_id, diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.tsx index 17c9b643cbc53..2da3a2863843b 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/use_rule_details_tabs.tsx @@ -8,6 +8,7 @@ import { useEffect, useMemo, useState } from 'react'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { omit } from 'lodash/fp'; +import { useUserPrivileges } from '../../../../common/components/user_privileges'; import { useEndpointExceptionsCapability } from '../../../../exceptions/hooks/use_endpoint_exceptions_capability'; import * as i18n from './translations'; import type { Rule } from '../../../rule_management/logic'; @@ -83,6 +84,7 @@ export const useRuleDetailsTabs = ({ const ruleExecutionSettings = useRuleExecutionSettings(); const canReadEndpointExceptions = useEndpointExceptionsCapability('showEndpointExceptions'); + const canReadExceptions = useUserPrivileges().rulesPrivileges.exceptions.read; useEffect(() => { const hiddenTabs = []; @@ -96,6 +98,9 @@ export const useRuleDetailsTabs = ({ if (!canReadEndpointExceptions) { hiddenTabs.push(RuleDetailTabs.endpointExceptions); } + if (!canReadExceptions) { + hiddenTabs.push(RuleDetailTabs.exceptions); + } if (rule != null) { const hasEndpointList = (rule.exceptions_list ?? []).some( (list) => list.type === ExceptionListTypeEnum.ENDPOINT @@ -108,7 +113,14 @@ export const useRuleDetailsTabs = ({ const tabs = omit>(hiddenTabs, ruleDetailTabs); setTabs(tabs); - }, [canReadEndpointExceptions, hasIndexRead, rule, ruleDetailTabs, ruleExecutionSettings]); + }, [ + canReadEndpointExceptions, + canReadExceptions, + hasIndexRead, + rule, + ruleDetailTabs, + ruleExecutionSettings, + ]); return pageTabs; }; From 83e004addb2406a1d45dff566bc92bca785816cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20=C3=81brah=C3=A1m?= Date: Tue, 2 Dec 2025 10:20:42 +0100 Subject: [PATCH 69/85] handle siem version dynamically in artifact details tab cypress test --- .../artifacts/artifact_tabs_in_policy_details.cy.ts | 11 ++++++++--- .../fixtures/role_with_artifact_read_privilege.ts | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts index 4405a01d37922..6fae846737bf4 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts @@ -39,6 +39,11 @@ const loginWithPrivilegeNone = (privilegePrefix: string) => { const getRoleWithoutArtifactPrivilege = (privilegePrefix: string) => { const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager(); + const siemVersion = + Object.keys(endpointSecurityPolicyManagerRole.kibana[0].feature).find((feature) => + feature.startsWith('siem') + ) ?? SECURITY_FEATURE_ID; + return { ...endpointSecurityPolicyManagerRole, kibana: [ @@ -46,9 +51,9 @@ const getRoleWithoutArtifactPrivilege = (privilegePrefix: string) => { ...endpointSecurityPolicyManagerRole.kibana[0], feature: { ...endpointSecurityPolicyManagerRole.kibana[0].feature, - [SECURITY_FEATURE_ID]: endpointSecurityPolicyManagerRole.kibana[0].feature[ - SECURITY_FEATURE_ID - ].filter((privilege) => privilege !== `${privilegePrefix}all`), + [siemVersion]: endpointSecurityPolicyManagerRole.kibana[0].feature[siemVersion].filter( + (privilege) => privilege !== `${privilegePrefix}all` + ), }, }, ], diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts index 043967d8c3a29..ea1dad676b471 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts @@ -11,6 +11,11 @@ import { getEndpointSecurityPolicyManager } from '../../../../scripts/endpoint/c export const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => { const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager(); + const siemVersion = + Object.keys(endpointSecurityPolicyManagerRole.kibana[0].feature).find((feature) => + feature.startsWith('siem') + ) ?? SECURITY_FEATURE_ID; + return { ...endpointSecurityPolicyManagerRole, kibana: [ @@ -18,8 +23,8 @@ export const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => { ...endpointSecurityPolicyManagerRole.kibana[0], feature: { ...endpointSecurityPolicyManagerRole.kibana[0].feature, - [SECURITY_FEATURE_ID]: [ - ...endpointSecurityPolicyManagerRole.kibana[0].feature[SECURITY_FEATURE_ID].filter( + [siemVersion]: [ + ...endpointSecurityPolicyManagerRole.kibana[0].feature[siemVersion].filter( (privilege) => privilege !== `${privilegePrefix}all` ), `${privilegePrefix}read`, From ac0a95ebfb3f3d39af8a078ccce980bda30c475c Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 11:11:36 -0500 Subject: [PATCH 70/85] fixes search bar jest tests --- .../src/search_bar/search_bar.test.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/search_bar.test.tsx b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/search_bar.test.tsx index a7eaa7ba47ad0..e7ce046a72963 100644 --- a/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/search_bar.test.tsx +++ b/x-pack/solutions/security/packages/kbn-securitysolution-exception-list-components/src/search_bar/search_bar.test.tsx @@ -20,7 +20,7 @@ describe('SearchBar', () => { onSearch={jest.fn()} onAddExceptionClick={jest.fn()} isSearching={false} - canAddException + canAddException={false} dataTestSubj="searchBar" /> ); @@ -32,7 +32,7 @@ describe('SearchBar', () => { const mockOnAddExceptionClick = jest.fn(); const wrapper = render( { const mockOnAddExceptionClick = jest.fn(); const wrapper = render( { const mockHandleOnSearch = jest.fn(); const wrapper = render( Date: Tue, 2 Dec 2025 11:39:34 -0500 Subject: [PATCH 71/85] updates api integration configs --- .../api_integration/apis/features/features/features.ts | 2 +- .../test/api_integration/apis/security/privileges.ts | 8 ++++++++ .../spaces_api_integration/common/suites/get.agnostic.ts | 2 +- .../common/suites/get_all.agnostic.ts | 2 +- .../spaces_only/telemetry/telemetry.ts | 1 + .../plugins/security_solution/public/helpers_access.ts | 4 ++-- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/x-pack/platform/test/api_integration/apis/features/features/features.ts b/x-pack/platform/test/api_integration/apis/features/features/features.ts index 3cb3c9569c6dd..a487b5f824093 100644 --- a/x-pack/platform/test/api_integration/apis/features/features/features.ts +++ b/x-pack/platform/test/api_integration/apis/features/features/features.ts @@ -141,7 +141,7 @@ export default function ({ getService }: FtrProviderContext) { 'securitySolutionCasesV3', 'securitySolutionTimeline', 'securitySolutionNotes', - 'securitySolutionRulesV1', + 'securitySolutionRulesV2', 'securitySolutionSiemMigrations', 'workflowsManagement', 'fleet', diff --git a/x-pack/platform/test/api_integration/apis/security/privileges.ts b/x-pack/platform/test/api_integration/apis/security/privileges.ts index 82736f8e0d427..5cd384dc20360 100644 --- a/x-pack/platform/test/api_integration/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration/apis/security/privileges.ts @@ -332,6 +332,14 @@ export default function ({ getService }: FtrProviderContext) { securitySolutionNotes: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionSiemMigrations: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], + securitySolutionRulesV2: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'securitySolutionExceptionsAll', + 'securitySolutionExceptionsRead', + ], infrastructure: ['all', 'read', 'minimal_all', 'minimal_read'], logs: ['all', 'read', 'minimal_all', 'minimal_read'], dataQuality: ['all', 'read', 'minimal_all', 'minimal_read', 'manage_rules', 'manage_alerts'], diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts index 46e2c26b41f94..c5c657b632fc4 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/get.agnostic.ts @@ -94,7 +94,7 @@ export function getTestSuiteFactory(context: DeploymentAgnosticFtrProviderContex 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', - 'securitySolutionRulesV1', + 'securitySolutionRulesV2', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', 'siemV5', diff --git a/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts b/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts index 8e5fb26511f7c..4d981158b8304 100644 --- a/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts +++ b/x-pack/platform/test/spaces_api_integration/common/suites/get_all.agnostic.ts @@ -84,7 +84,7 @@ const ALL_SPACE_RESULTS: Space[] = [ 'securitySolutionAttackDiscovery', 'securitySolutionCasesV3', 'securitySolutionNotes', - 'securitySolutionRulesV1', + 'securitySolutionRulesV2', 'securitySolutionSiemMigrations', 'securitySolutionTimeline', 'siemV5', diff --git a/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts b/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts index 177da91c4fc2c..fc2107d073838 100644 --- a/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts +++ b/x-pack/platform/test/spaces_api_integration/spaces_only/telemetry/telemetry.ts @@ -99,6 +99,7 @@ export default function ({ getService }: FtrProviderContext) { siemV4: 0, siemV5: 0, securitySolutionRulesV1: 0, + securitySolutionRulesV2: 0, securitySolutionCases: 0, securitySolutionCasesV2: 0, securitySolutionCasesV3: 0, diff --git a/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts b/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts index c46a531d9e63e..da8bc7fbb17f5 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/helpers_access.ts @@ -6,7 +6,7 @@ */ import type { Capabilities } from '@kbn/core/public'; import { RULES_UI_READ } from '@kbn/security-solution-features/constants'; -import { SECURITY_FEATURE_ID, CASES_FEATURE_ID } from '../common/constants'; +import { SECURITY_FEATURE_ID, CASES_FEATURE_ID, RULES_FEATURE_ID } from '../common/constants'; export function hasAccessToSecuritySolution(capabilities: Capabilities): boolean { return Boolean( @@ -17,7 +17,7 @@ export function hasAccessToSecuritySolution(capabilities: Capabilities): boolean } export function hasAccessToRules(capabilities: Capabilities): boolean { - return Boolean(capabilities.securitySolutionRulesV1?.[RULES_UI_READ]); + return Boolean(capabilities[RULES_FEATURE_ID]?.[RULES_UI_READ]); } export function hasAccessToCases(capabilities: Capabilities): boolean { From 8759e3a84e5d54c6ffea06a29c3f7846829dc572 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 12:08:47 -0500 Subject: [PATCH 72/85] updates serverless test authorization snapshot --- .../platform_security/authorization.ts | 132 ++++++++++-------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts index 25e2514b0ecd5..7938ac98ddc41 100644 --- a/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts +++ b/x-pack/solutions/security/test/serverless/api_integration/test_suites/platform_security/authorization.ts @@ -1120,10 +1120,12 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/writeGlobalArtifacts", "ui:siemV5/showEndpointExceptions", "ui:siemV5/crudEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", + "ui:securitySolutionRulesV2/crudExceptions", ], "blocklist_all": Array [ "login:", @@ -2169,10 +2171,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", ], "minimal_read": Array [ "login:", @@ -2585,9 +2587,9 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", ], "policy_management_all": Array [ "login:", @@ -3042,9 +3044,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", "ui:siemV5/showEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", ], "scan_operations_all": Array [ "login:", @@ -3917,10 +3920,12 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/writeGlobalArtifacts", "ui:siemV5/showEndpointExceptions", "ui:siemV5/crudEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", + "ui:securitySolutionRulesV2/crudExceptions", ], "blocklist_all": Array [ "login:", @@ -4910,10 +4915,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", ], "minimal_read": Array [ "login:", @@ -5298,9 +5303,9 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", ], "policy_management_all": Array [ "login:", @@ -5727,9 +5732,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", "ui:siemV5/showEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", ], "scan_operations_all": Array [ "login:", @@ -6613,10 +6619,12 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/threat-intelligence", "ui:siemV5/showEndpointExceptions", "ui:siemV5/crudEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", + "ui:securitySolutionRulesV2/crudExceptions", ], "blocklist_all": Array [ "login:", @@ -7595,10 +7603,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", ], "minimal_read": Array [ "login:", @@ -7981,9 +7989,9 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", ], "policy_management_all": Array [ "login:", @@ -8408,9 +8416,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", "ui:siemV5/showEndpointExceptions", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", ], "scan_operations_all": Array [ "login:", @@ -8542,11 +8551,13 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-threat-intelligence", "app:securitySolution", "app:csp", + "app:cloudDefend", "app:kibana", "ui:catalogue/securitySolution", "ui:management/insightsAndAlerting/triggersActions", "ui:navLinks/securitySolution", "ui:navLinks/csp", + "ui:navLinks/cloudDefend", "ui:navLinks/kibana", "saved_object:alert/bulk_get", "saved_object:alert/get", @@ -9318,10 +9329,12 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", + "ui:securitySolutionRulesV2/crudExceptions", ], "blocklist_all": Array [ "login:", @@ -9524,11 +9537,13 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-threat-intelligence", "app:securitySolution", "app:csp", + "app:cloudDefend", "app:kibana", "ui:catalogue/securitySolution", "ui:management/insightsAndAlerting/triggersActions", "ui:navLinks/securitySolution", "ui:navLinks/csp", + "ui:navLinks/cloudDefend", "ui:navLinks/kibana", "saved_object:alert/bulk_get", "saved_object:alert/get", @@ -10300,10 +10315,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/edit_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/edit_rules", + "ui:securitySolutionRulesV2/detections", ], "minimal_read": Array [ "login:", @@ -10321,11 +10336,13 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-threat-intelligence", "app:securitySolution", "app:csp", + "app:cloudDefend", "app:kibana", "ui:catalogue/securitySolution", "ui:management/insightsAndAlerting/triggersActions", "ui:navLinks/securitySolution", "ui:navLinks/csp", + "ui:navLinks/cloudDefend", "ui:navLinks/kibana", "saved_object:exception-list/bulk_get", "saved_object:exception-list/get", @@ -10686,9 +10703,9 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", ], "policy_management_all": Array [ "login:", @@ -10744,11 +10761,13 @@ export default function ({ getService }: FtrProviderContext) { "api:securitySolution-threat-intelligence", "app:securitySolution", "app:csp", + "app:cloudDefend", "app:kibana", "ui:catalogue/securitySolution", "ui:management/insightsAndAlerting/triggersActions", "ui:navLinks/securitySolution", "ui:navLinks/csp", + "ui:navLinks/cloudDefend", "ui:navLinks/kibana", "saved_object:exception-list/bulk_get", "saved_object:exception-list/get", @@ -11109,9 +11128,10 @@ export default function ({ getService }: FtrProviderContext) { "ui:siemV5/investigation-guide", "ui:siemV5/investigation-guide-interactions", "ui:siemV5/threat-intelligence", - "ui:navLinks/securitySolutionRulesV1", - "ui:securitySolutionRulesV1/read_rules", - "ui:securitySolutionRulesV1/detections", + "ui:navLinks/securitySolutionRulesV2", + "ui:securitySolutionRulesV2/read_rules", + "ui:securitySolutionRulesV2/detections", + "ui:securitySolutionRulesV2/readExceptions", ], "scan_operations_all": Array [ "login:", From 2849d9089ca185167c588c92b18103acf266b157 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 16:28:05 -0500 Subject: [PATCH 73/85] fix types --- .../server/lib/siem_migrations/rules/api/rules/enhance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/enhance.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/enhance.ts index 78d2c5915ca3a..d559de7d0504d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/enhance.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/siem_migrations/rules/api/rules/enhance.ts @@ -14,7 +14,7 @@ import { RuleMigrationEnhanceRuleRequestBody, } from '../../../../../../common/siem_migrations/model/api/rules/rule_migration.gen'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { authz } from '../../../common/api/util/authz'; +import { authz } from '../util/authz'; import { SiemMigrationAuditLogger } from '../../../common/api/util/audit'; import { withLicense } from '../../../common/api/util/with_license'; import { withExistingMigration } from '../../../common/api/util/with_existing_migration_id'; From bf24ee0ac3f1153e231cd37d9a481bafd4102db2 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 16:51:34 -0500 Subject: [PATCH 74/85] fix security role object types --- .../shared/kbn-es/src/serverless_resources/security_roles.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index 0a25f359e2ee4..a8f6cf9b49a4f 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -426,6 +426,7 @@ ] }, "readrules": { + "name": "readrules", "elasticsearch": { "cluster": [], "indices": [ @@ -472,6 +473,7 @@ ] }, "editrules": { + "name": "editrules", "elasticsearch": { "cluster": [], "indices": [ From 7a74953bf1cf2f9ad34b41dcfbb0cc4cf3318544 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 17:40:22 -0500 Subject: [PATCH 75/85] REMOVES exceptions serverless security_roles for now --- .../serverless_resources/security_roles.json | 95 ------------------- 1 file changed, 95 deletions(-) diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index a8f6cf9b49a4f..a2c804deed626 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -424,100 +424,5 @@ "base": [] } ] - }, - "readrules": { - "name": "readrules", - "elasticsearch": { - "cluster": [], - "indices": [ - { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] - }, - { - "names": [ - "apm-*-transaction*", - "traces-apm*", - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "metrics-endpoint.metadata_current_*", - ".fleet-agents*", - ".fleet-actions*", - ".asset-criticality.asset-criticality-*", - ".entity_analytics.monitoring*" - ], - "privileges": ["read"] - } - ], - "run_as": [] - }, - "kibana": [ - { - "feature": { - "siemV4": ["read", "read_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["read"], - "builtInAlerts": ["read"] - }, - "spaces": ["*"], - "base": [] - } - ] - }, - "editrules": { - "name": "editrules", - "elasticsearch": { - "cluster": [], - "indices": [ - { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] - }, - { - "names": [ - "apm-*-transaction*", - "traces-apm*", - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - "metrics-endpoint.metadata_current_*", - ".fleet-agents*", - ".fleet-actions*", - ".asset-criticality.asset-criticality-*", - ".entity_analytics.monitoring*" - ], - "privileges": ["read"] - } - ], - "run_as": [] - }, - "kibana": [ - { - "feature": { - "ml": ["read"], - "siemV4": ["all", "all_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["all"], - "builtInAlerts": ["all"] - }, - "spaces": ["*"], - "base": [] - } - ] } } From 915fa66b4cf0da361c5f99ac80b9a80e580d8418 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 23:47:50 -0500 Subject: [PATCH 76/85] reverts security roles changes --- .../serverless_resources/security_roles.json | 454 ++++++++++++++---- 1 file changed, 349 insertions(+), 105 deletions(-) diff --git a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json index a2c804deed626..aecec6532056e 100644 --- a/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json +++ b/src/platform/packages/shared/kbn-es/src/serverless_resources/security_roles.json @@ -5,8 +5,15 @@ "cluster": [], "indices": [ { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { "names": [ @@ -24,7 +31,9 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -32,17 +41,38 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV4": ["read", "read_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["read"], - "builtInAlerts": ["read"] + "ml": [ + "read" + ], + "siemV4": [ + "read", + "read_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "read" + ], + "securitySolutionTimeline": [ + "read" + ], + "securitySolutionNotes": [ + "read" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "read" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -53,8 +83,15 @@ "cluster": [], "indices": [ { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { "names": [ @@ -74,7 +111,9 @@ ".asset-criticality.asset-criticality-*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -82,17 +121,38 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV4": ["read", "read_alerts"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["read"], - "securitySolutionTimeline": ["read"], - "securitySolutionNotes": ["read"], - "actions": ["read"], - "builtInAlerts": ["read"] + "ml": [ + "read" + ], + "siemV4": [ + "read", + "read_alerts" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "read" + ], + "securitySolutionTimeline": [ + "read" + ], + "securitySolutionNotes": [ + "read" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "read" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -115,15 +175,31 @@ "logstash-*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { - "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write", "maintenance"] + "names": [ + ".alerts-security*", + ".siem-signals-*" + ], + "privileges": [ + "read", + "write", + "maintenance" + ] }, { - "names": [".lists*", ".items*"], - "privileges": ["read", "write"] + "names": [ + ".lists*", + ".items*" + ], + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -137,7 +213,9 @@ ".entities.v1.updates.security_*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -145,7 +223,9 @@ "kibana": [ { "feature": { - "ml": ["read"], + "ml": [ + "read" + ], "siemV4": [ "all", "read_alerts", @@ -162,21 +242,49 @@ "actions_log_management_all", "file_operations_all" ], - "securitySolutionCasesV2": ["all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"], - "osquery": ["all"], - "discover_v2": ["all"], - "dashboard_v2": ["all"], - "maps_v2": ["all"], - "visualize_v2": ["all"], - "savedQueryManagement": ["all"] + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ], + "osquery": [ + "all" + ], + "discover_v2": [ + "all" + ], + "dashboard_v2": [ + "all" + ], + "maps_v2": [ + "all" + ], + "visualize_v2": [ + "all" + ], + "savedQueryManagement": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -200,7 +308,10 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -211,7 +322,12 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["read", "write", "maintenance", "view_index_metadata"] + "privileges": [ + "read", + "write", + "maintenance", + "view_index_metadata" + ] }, { "names": [ @@ -220,7 +336,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -228,17 +346,40 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"] + "ml": [ + "read" + ], + "siemV4": [ + "all", + "read_alerts", + "crud_alerts", + "endpoint_exceptions_all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -262,7 +403,10 @@ ".items*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["read", "write"] + "privileges": [ + "read", + "write" + ] }, { "names": [ @@ -273,7 +417,11 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["read", "write", "manage"] + "privileges": [ + "read", + "write", + "manage" + ] }, { "names": [ @@ -282,7 +430,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -290,17 +440,40 @@ "kibana": [ { "feature": { - "ml": ["read"], - "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["all"], - "builtInAlerts": ["all"] + "ml": [ + "read" + ], + "siemV4": [ + "all", + "read_alerts", + "crud_alerts", + "endpoint_exceptions_all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "all" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -308,7 +481,9 @@ "detections_admin": { "name": "detections_admin", "elasticsearch": { - "cluster": ["manage"], + "cluster": [ + "manage" + ], "indices": [ { "names": [ @@ -330,7 +505,11 @@ "winlogbeat-*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["manage", "write", "read"] + "privileges": [ + "manage", + "write", + "read" + ] }, { "names": [ @@ -339,7 +518,9 @@ ".fleet-actions*", ".entity_analytics.monitoring*" ], - "privileges": ["read"] + "privileges": [ + "read" + ] } ], "run_as": [] @@ -347,18 +528,43 @@ "kibana": [ { "feature": { - "ml": ["all"], - "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["read"], - "builtInAlerts": ["all"], - "dev_tools": ["all"] + "ml": [ + "all" + ], + "siemV4": [ + "all", + "read_alerts", + "crud_alerts", + "endpoint_exceptions_all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "read" + ], + "builtInAlerts": [ + "all" + ], + "dev_tools": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] @@ -366,11 +572,18 @@ "platform_engineer": { "name": "platform_engineer", "elasticsearch": { - "cluster": ["manage"], + "cluster": [ + "manage" + ], "indices": [ { - "names": [".lists*", ".items*"], - "privileges": ["all"] + "names": [ + ".lists*", + ".items*" + ], + "privileges": [ + "all" + ] }, { "names": [ @@ -387,7 +600,9 @@ ".fleet-actions*", ".asset-criticality.asset-criticality-*" ], - "privileges": ["all"] + "privileges": [ + "all" + ] }, { "names": [ @@ -398,11 +613,17 @@ ".internal.adhoc.alerts-security*", ".siem-signals-*" ], - "privileges": ["all"] + "privileges": [ + "all" + ] }, { - "names": [".entity_analytics.monitoring*"], - "privileges": ["read"] + "names": [ + ".entity_analytics.monitoring*" + ], + "privileges": [ + "read" + ] } ], "run_as": [] @@ -410,19 +631,42 @@ "kibana": [ { "feature": { - "ml": ["all"], - "siemV4": ["all", "read_alerts", "crud_alerts", "endpoint_exceptions_all"], - "securitySolutionAssistant": ["all"], - "securitySolutionAttackDiscovery": ["all"], - "securitySolutionCasesV2": ["all"], - "securitySolutionTimeline": ["all"], - "securitySolutionNotes": ["all"], - "actions": ["all"], - "builtInAlerts": ["all"] + "ml": [ + "all" + ], + "siemV4": [ + "all", + "read_alerts", + "crud_alerts", + "endpoint_exceptions_all" + ], + "securitySolutionAssistant": [ + "all" + ], + "securitySolutionAttackDiscovery": [ + "all" + ], + "securitySolutionCasesV2": [ + "all" + ], + "securitySolutionTimeline": [ + "all" + ], + "securitySolutionNotes": [ + "all" + ], + "actions": [ + "all" + ], + "builtInAlerts": [ + "all" + ] }, - "spaces": ["*"], + "spaces": [ + "*" + ], "base": [] } ] } -} +} \ No newline at end of file From a304a999a32d05c57ca43d87fce4fb0d3dcfce7a Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Tue, 2 Dec 2025 23:51:08 -0500 Subject: [PATCH 77/85] fix types --- .../shared/components/take_action_dropdown.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx index 43b92545996f7..bfc107bdd39d0 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/flyout/document_details/shared/components/take_action_dropdown.test.tsx @@ -162,6 +162,7 @@ describe('take action dropdown', () => { exceptions: { read: true, crud: true }, }, }); + wrapper = mount( From dd1691529a0deb1921fb1d5b8af39a243c021c35 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 09:58:15 -0500 Subject: [PATCH 78/85] update deprecated feature ID FTR tests --- .../api_integration_basic/apis/security/privileges.ts | 9 +++++++++ .../tests/features/deprecated_features.ts | 1 + 2 files changed, 10 insertions(+) diff --git a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts index 309f729267368..d1f525f8f5e75 100644 --- a/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts +++ b/x-pack/platform/test/api_integration_basic/apis/security/privileges.ts @@ -61,6 +61,7 @@ export default function ({ getService }: FtrProviderContext) { siemV4: ['all', 'read', 'minimal_all', 'minimal_read'], siemV5: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], + securitySolutionRulesV2: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionAssistant: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionAttackDiscovery: ['all', 'read', 'minimal_all', 'minimal_read'], securitySolutionCases: ['all', 'read', 'minimal_all', 'minimal_read'], @@ -399,6 +400,14 @@ export default function ({ getService }: FtrProviderContext) { 'minimal_read', ], securitySolutionRulesV1: ['all', 'read', 'minimal_all', 'minimal_read'], + securitySolutionRulesV2: [ + 'all', + 'read', + 'minimal_all', + 'minimal_read', + 'securitySolutionExceptionsAll', + 'securitySolutionExceptionsRead', + ], securitySolutionAssistant: [ 'all', 'read', diff --git a/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts b/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts index 815fb9a2ee050..382403068369a 100644 --- a/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts +++ b/x-pack/platform/test/security_api_integration/tests/features/deprecated_features.ts @@ -189,6 +189,7 @@ export default function ({ getService }: FtrProviderContext) { "observabilityCasesV2", "securitySolutionCases", "securitySolutionCasesV2", + "securitySolutionRulesV1", "siem", "siemV2", "siemV3", From 33f8eae674578a3ab6a86d580e33a8ee4a9b281e Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 10:16:46 -0500 Subject: [PATCH 79/85] updates roles for rule cypress tests --- .../shared_exception_list_page/read_only.cy.ts | 4 ++-- .../security_solution_cypress/cypress/tasks/privileges.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts index 31405abf18de5..67f1346e1ce9b 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/detection_engine/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts @@ -58,7 +58,7 @@ describe('Shared exception lists - read only', { tags: ['@ess', '@skipInServerle }); }); - it('Exception list actions should be disabled', () => { - cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().should('be.disabled'); + it('Exception list actions should be enabled', () => { + cy.get(EXCEPTIONS_OVERFLOW_ACTIONS_BTN).first().should('be.enabled'); }); }); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts index e12a49eab2f03..3757832d62c99 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/tasks/privileges.ts @@ -211,7 +211,7 @@ export const rulesAll: Role = { kibana: [ { feature: { - securitySolutionRulesV1: ['all'], + securitySolutionRulesV2: ['all'], actions: ['all'], indexPatterns: ['all'], savedObjectManagement: ['all'], @@ -236,7 +236,7 @@ export const rulesAllWithCases: Role = { kibana: [ { feature: { - securitySolutionRulesV1: ['all'], + securitySolutionRulesV2: ['all'], actions: ['all'], indexPatterns: ['all'], savedObjectManagement: ['all'], @@ -262,7 +262,7 @@ export const rulesRead: Role = { kibana: [ { feature: { - securitySolutionRulesV1: ['read'], + securitySolutionRulesV2: ['read'], savedObjectManagement: ['all'], indexPatterns: ['all'], }, From d04dd7f4aa3e3c7b63e8b9068d6e31d87d25324f Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 13:32:44 -0500 Subject: [PATCH 80/85] allows users with read privileges to view uninstalled prebuilt rules and updateable rules --- .../hooks/use_prebuilt_rules_upgrade.tsx | 4 +++ .../pre_packaged_rules/load_empty_prompt.tsx | 4 +-- .../rules_table/rules_table_toolbar.tsx | 4 +-- .../pages/rule_management/index.tsx | 4 +-- .../security_solution/public/rules/routes.tsx | 14 +++++------ .../install_update_authorization.cy.ts | 25 +++++++++---------- .../rules_table/privileges.cy.ts | 5 ++++ 7 files changed, 34 insertions(+), 26 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx index 4277555cdd3f6..e3788cd85e7d8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { EuiButton, EuiToolTip } from '@elastic/eui'; +import { useUserPrivileges } from '../../../common/components/user_privileges'; import { RuleUpgradeEventTypes } from '../../../common/lib/telemetry/events/rule_upgrade/types'; import type { ReviewPrebuiltRuleUpgradeFilter } from '../../../../common/api/detection_engine/prebuilt_rules/common/review_prebuilt_rules_upgrade_filter'; import { FieldUpgradeStateEnum, type RuleUpgradeState } from '../model/prebuilt_rule_upgrade'; @@ -73,6 +74,7 @@ export function usePrebuiltRulesUpgrade({ const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages(); const [loadingRules, setLoadingRules] = useState([]); const { telemetry } = useKibana().services; + const canEditRules = useUserPrivileges().rulesPrivileges.edit; const { data: upgradeReviewResponse, @@ -254,6 +256,7 @@ export function usePrebuiltRulesUpgrade({ return ( { - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canReadRules = useUserPrivileges().rulesPrivileges.read; return ( { { const { data: ruleManagementFilters } = useRuleManagementFilters(); const { data: prebuiltRulesStatus } = usePrebuiltRulesStatus(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canReadRules = useUserPrivileges().rulesPrivileges.read; const installedTotal = (ruleManagementFilters?.rules_summary.custom_count ?? 0) + (ruleManagementFilters?.rules_summary.prebuilt_installed_count ?? 0); const updateTotal = prebuiltRulesStatus?.stats.num_prebuilt_rules_to_upgrade ?? 0; - const shouldDisplayRuleUpdatesTab = canEditRules && updateTotal > 0; + const shouldDisplayRuleUpdatesTab = canReadRules && updateTotal > 0; const ruleTabs = useMemo( () => ({ diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index 19f796f584d59..a62aaf7d1dabe 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -47,7 +47,7 @@ const RulesPageComponent: React.FC = () => { const [{ loading: userInfoLoading, isSignalIndexExists, isAuthenticated, hasEncryptionKey }] = useUserData(); - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const { edit: canEditRules, read: canReadRules } = useUserPrivileges().rulesPrivileges; const { loading: listsConfigLoading, canWriteIndex: canWriteListsIndex, @@ -100,7 +100,7 @@ const RulesPageComponent: React.FC = () => { - + [ main: RulesPage, exact: true, }, + { + path: '/rules/add_rules', + main: withSecurityRoutePageWrapper(AddRulesPage, SecurityPageName.rulesAdd, { + omitSpyRoute: true, + }), + exact: true, + }, ] : []), ...(hasCapabilities(capabilities, RULES_UI_EDIT_PRIVILEGE) @@ -67,13 +74,6 @@ const getRulesSubRoutes = (capabilities: Capabilities) => [ }), exact: true, }, - { - path: '/rules/add_rules', - main: withSecurityRoutePageWrapper(AddRulesPage, SecurityPageName.rulesAdd, { - omitSpyRoute: true, - }), - exact: true, - }, ] : []), ]; diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts index f36c4128d8615..cd877800f37c7 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts @@ -95,14 +95,13 @@ describe( // Now login with read-only user in preparation for test loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL); - // Check that Add Elastic Rules button is disabled - cy.get(ADD_ELASTIC_RULES_BTN).should('be.disabled'); + // Check that Add Elastic Rules button is enabled + cy.get(ADD_ELASTIC_RULES_BTN).should('be.enabled'); - // Navigate to Add Elastic Rules page anyways via URL - // and assert that rules cannot be selected and all - // installation buttons are disabled + // Navigate to Add Elastic Rules page via URL + // and assert that page can be accessed cy.visit(`${APP_PATH}${RULES_ADD_PATH}`); - cy.get(NOT_FOUND).should('exist'); + cy.get(NOT_FOUND).should('not.exist'); }); it('should not be able to upgrade prebuilt rules', () => { @@ -114,20 +113,20 @@ describe( // Now login with read-only user in preparation for test loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL); - // Check that Rule Update tab is not shown - cy.get(RULES_UPDATES_TAB).should('not.exist'); + // Check that Rule Update tab is shown + cy.get(RULES_UPDATES_TAB).should('exist'); // Navigate to Rule Update tab anyways via URL cy.visit(`${APP_PATH}${RULES_UPDATES}`); - // Check that upgrade buttons are not visible - cy.get(UPGRADE_ALL_RULES_BUTTON).should('not.exist'); + // Check that upgrade buttons are disabled + cy.get(UPGRADE_ALL_RULES_BUTTON).should('be.disabled'); cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should( - 'not.exist' + 'be.disabled' ); - // Check that rule selection checkbox is not visible - cy.get(RULE_CHECKBOX).should('not.exist'); + // Check that rule selection checkbox is visible + cy.get(RULE_CHECKBOX).should('exist'); }); }); diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts index ba1ef9ace803f..5ec260e898b08 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/privileges.cy.ts @@ -6,6 +6,7 @@ */ import { + ADD_ELASTIC_RULES_BTN, CREATE_NEW_RULE_BTN, ENABLE_RULE_TOGGLE, } from '../../../../screens/alerts_detection_rules'; @@ -138,6 +139,10 @@ describe('Rules table - privileges', { tags: ['@ess'] }, () => { it(`should not be able to "Enable/Disable" a rule`, () => { cy.get(ENABLE_RULE_TOGGLE).should('not.be.enabled'); }); + + it(`should be able to "Add" a prebuilt rule`, () => { + cy.get(ADD_ELASTIC_RULES_BTN).should('be.enabled'); + }); }); describe('securitySolutionRulesV1 none', () => { From b66434e7423bc86dbc6094ce7e3db6520dac806f Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 15:56:18 -0500 Subject: [PATCH 81/85] adds mocks to rule upgrade tests --- .../rules_upgrade/test_utils/rule_upgrade_flyout.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx index 67f580a11ae2d..e72d5489aab35 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx @@ -14,6 +14,8 @@ import type { FieldSpec, } from '@kbn/data-views-plugin/common'; import userEvent from '@testing-library/user-event'; +import { initialUserPrivilegesState } from '../../../../../../../common/components/user_privileges/user_privileges_context'; +import { useUserPrivileges } from '../../../../../../../common/components/user_privileges'; import { invariant } from '../../../../../../../../common/utils/invariant'; import { TIMELINES_URL } from '../../../../../../../../common/constants'; import { RulesPage } from '../../..'; @@ -34,6 +36,7 @@ import { RuleUpgradeTestProviders } from './rule_upgrade_test_providers'; jest.mock('../../../../../../../detections/components/user_info'); jest.mock('../../../../../../../detections/containers/detection_engine/lists/use_lists_config'); jest.mock('../../../../../components/rules_table/feature_tour/rules_feature_tour'); +jest.mock('../../../../../../../common/components/user_privileges'); /** **********************************************/ /** @@ -48,6 +51,10 @@ export async function renderRuleUpgradeFlyout(): Promise mockedResponses.get(requestedPath) ); + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + rulesPrivileges: { read: true, edit: true }, + }); mockKibanaFetchResponse(GET_PREBUILT_RULES_STATUS_URL, { stats: { From 56d7caed6dbbeef778f712150b0a415f2e7f0de1 Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 16:03:39 -0500 Subject: [PATCH 82/85] updates rule upgrade cypress tests --- .../installation/install_update_authorization.cy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts index cd877800f37c7..b62ac79104f7e 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/prebuilt_rules/installation/install_update_authorization.cy.ts @@ -119,10 +119,10 @@ describe( // Navigate to Rule Update tab anyways via URL cy.visit(`${APP_PATH}${RULES_UPDATES}`); - // Check that upgrade buttons are disabled + // Check that upgrade buttons are disabled/hidden cy.get(UPGRADE_ALL_RULES_BUTTON).should('be.disabled'); cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should( - 'be.disabled' + 'not.exist' ); // Check that rule selection checkbox is visible From 5f6fbd5dc0d96f7705ad8ddeb8520e06bc59dca0 Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Wed, 3 Dec 2025 16:48:35 -0600 Subject: [PATCH 83/85] Add SIEM V4 user to AI4DSOC capabilities tests This will ensure behaviors are correct for all intermediate SIEM features. --- .../e2e/ai4dsoc/capabilities/access.cy.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts index ce529668fefd6..a181ffce8c947 100644 --- a/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts +++ b/x-pack/solutions/security/test/security_solution_cypress/cypress/e2e/ai4dsoc/capabilities/access.cy.ts @@ -96,6 +96,29 @@ describe('Capabilities', { tags: '@serverless' }, () => { cy.task('deleteServerlessCustomRole', 'siemV3'); }, }, + { + name: 'User with siem v4 role', + loginAs: 'siemV4', + setup: () => { + cy.task('createServerlessCustomRole', { + roleDescriptor: { + elasticsearch: { + indices: [{ names: ['*'], privileges: ['all'] }], + }, + kibana: [ + { + feature: { siemV4: ['all'], fleet: ['all'] }, + spaces: ['*'], + }, + ], + }, + roleName: 'siemV4', + }); + }, + teardown: () => { + cy.task('deleteServerlessCustomRole', 'siemV4'); + }, + }, { name: 'User with siem v5 role', loginAs: 'siemV5', From d86686c9ec50ffd236f738ac08f84492c0a5437d Mon Sep 17 00:00:00 2001 From: Davis Plumlee Date: Wed, 3 Dec 2025 20:42:50 -0500 Subject: [PATCH 84/85] fix rules management cypress tests --- .../security/packages/features/src/constants.ts | 2 +- .../src/rules/v1_features/kibana_features.ts | 12 ++++++------ .../plugins/security_solution/common/constants.ts | 7 +++++-- .../plugins/security_solution/common/index.ts | 1 + .../public/common/hooks/use_missing_privileges.ts | 4 ++-- .../rules_upgrade/test_utils/rule_upgrade_flyout.tsx | 5 ++++- .../endpoint_exceptions.ts | 3 ++- .../cypress/tasks/privileges.ts | 6 ++++++ 8 files changed, 27 insertions(+), 13 deletions(-) diff --git a/x-pack/solutions/security/packages/features/src/constants.ts b/x-pack/solutions/security/packages/features/src/constants.ts index edcc4f7171752..486813d07e221 100644 --- a/x-pack/solutions/security/packages/features/src/constants.ts +++ b/x-pack/solutions/security/packages/features/src/constants.ts @@ -46,7 +46,7 @@ export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SIEM_MIGRATIONS_FEATURE_ID = 'securitySolutionSiemMigrations' as const; -export const RULES_FEATURE_ID = 'securitySolutionRulesV1' as const; +export const RULES_FEATURE_ID_V1 = 'securitySolutionRulesV1' as const; export const RULES_FEATURE_ID_V2 = 'securitySolutionRulesV2' as const; // Rules API privileges diff --git a/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts b/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts index c8860859c63a8..7bfc9343d7048 100644 --- a/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts +++ b/x-pack/solutions/security/packages/features/src/rules/v1_features/kibana_features.ts @@ -31,7 +31,7 @@ import { LISTS_API_SUMMARY, RULES_API_ALL, RULES_API_READ, - RULES_FEATURE_ID, + RULES_FEATURE_ID_V1, RULES_FEATURE_ID_V2, RULES_UI_EDIT, RULES_UI_READ, @@ -69,13 +69,13 @@ export const getRulesBaseKibanaFeature = ( { defaultMessage: 'The {currentId} permissions are deprecated, please see {latestId}.', values: { - currentId: RULES_FEATURE_ID, + currentId: RULES_FEATURE_ID_V1, latestId: RULES_FEATURE_ID_V2, }, } ), }, - id: RULES_FEATURE_ID, + id: RULES_FEATURE_ID_V1, name: i18n.translate( 'securitySolutionPackages.features.featureRegistry.linkSecuritySolutionRolesTitle', { @@ -84,7 +84,7 @@ export const getRulesBaseKibanaFeature = ( ), order: 1100, category: DEFAULT_APP_CATEGORIES.security, - app: [RULES_FEATURE_ID, 'kibana'], + app: [RULES_FEATURE_ID_V1, 'kibana'], catalogue: [APP_ID], alerting: alertingFeatures, management: { @@ -101,7 +101,7 @@ export const getRulesBaseKibanaFeature = ( }, ], }, - app: [RULES_FEATURE_ID, 'kibana'], + app: [RULES_FEATURE_ID_V1, 'kibana'], catalogue: [APP_ID], savedObject: { all: params.savedObjects, @@ -140,7 +140,7 @@ export const getRulesBaseKibanaFeature = ( }, ], }, - app: [RULES_FEATURE_ID, 'kibana'], + app: [RULES_FEATURE_ID_V1, 'kibana'], catalogue: [APP_ID], savedObject: { all: [], diff --git a/x-pack/solutions/security/plugins/security_solution/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/constants.ts index 751529f047ded..1c7fcf3a2f076 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/constants.ts @@ -7,7 +7,10 @@ import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import type { FilterControlConfig } from '@kbn/alerts-ui-shared'; -import { SECURITY_FEATURE_ID_V5 } from '@kbn/security-solution-features/constants'; +import { + RULES_FEATURE_ID_V2, + SECURITY_FEATURE_ID_V5, +} from '@kbn/security-solution-features/constants'; import * as i18n from './translations'; export { @@ -30,7 +33,7 @@ export const TIMELINE_FEATURE_ID = 'securitySolutionTimeline' as const; export const NOTES_FEATURE_ID = 'securitySolutionNotes' as const; export const SERVER_APP_ID = 'siem' as const; export const SECURITY_FEATURE_ID = SECURITY_FEATURE_ID_V5; -export { RULES_FEATURE_ID_V2 as RULES_FEATURE_ID } from '@kbn/security-solution-features/constants'; +export const RULES_FEATURE_ID = RULES_FEATURE_ID_V2; export const APP_NAME = 'Security' as const; export const APP_ICON_SOLUTION = 'logoSecurity' as const; export const APP_PATH = `/app/security` as const; diff --git a/x-pack/solutions/security/plugins/security_solution/common/index.ts b/x-pack/solutions/security/plugins/security_solution/common/index.ts index 7bd4c019a6d15..52ce3ff562868 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/index.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/index.ts @@ -16,6 +16,7 @@ export { ADD_DATA_PATH, SecurityPageName, DETECTION_ENGINE_RULES_URL_FIND, + RULES_FEATURE_ID, } from './constants'; export { ELASTIC_SECURITY_RULE_ID } from './detection_engine/constants'; export { ENABLED_FIELD } from './detection_engine/rule_management/rule_fields'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts index ddb6cf93e939f..a320aff1f814a 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/common/hooks/use_missing_privileges.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { RULES_FEATURE_ID_V2 } from '@kbn/security-solution-features/constants'; import { useMemo } from 'react'; +import { RULES_FEATURE_ID } from '../../../common/constants'; import type { Privilege } from '../../detections/containers/detection_engine/alerts/types'; import { useUserPrivileges } from '../components/user_privileges'; @@ -66,7 +66,7 @@ export const useMissingPrivileges = (): MissingPrivileges => { } if (rulesPrivileges.rules.edit === false) { - featurePrivileges.push([RULES_FEATURE_ID_V2, ['all']]); + featurePrivileges.push([RULES_FEATURE_ID, ['all']]); } const missingItemsPrivileges = getMissingIndexPrivileges(listPrivileges.result.listItems.index); diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx index e72d5489aab35..83b13c2ede207 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/__integration_tests__/rules_upgrade/test_utils/rule_upgrade_flyout.tsx @@ -53,7 +53,10 @@ export async function renderRuleUpgradeFlyout(): Promise Date: Wed, 3 Dec 2025 21:20:05 -0500 Subject: [PATCH 85/85] fix types --- .../rule_management/hooks/use_prebuilt_rules_upgrade.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx index e3788cd85e7d8..b63ac1ef5c9fd 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx +++ b/x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/hooks/use_prebuilt_rules_upgrade.tsx @@ -74,7 +74,7 @@ export function usePrebuiltRulesUpgrade({ const isUpgradingSecurityPackages = useIsUpgradingSecurityPackages(); const [loadingRules, setLoadingRules] = useState([]); const { telemetry } = useKibana().services; - const canEditRules = useUserPrivileges().rulesPrivileges.edit; + const canEditRules = useUserPrivileges().rulesPrivileges.rules.edit; const { data: upgradeReviewResponse,