[Alert Triage workflow] Adds security.buildAlertEntityGraph and security.renderAlertNarrative…#259159
Conversation
…a into feature/alert-triage-steps-2
|
/ci |
|
@elasticmachine merge upstream |
|
merge conflict between base and head |
…a into feature/alert-triage-steps-2
| const inputSchema = z.object({ | ||
| alertId: z.string().describe('The alert ID'), | ||
| alertIndex: z.string().describe('The index that contains the alert'), | ||
| }); | ||
|
|
||
| const outputSchema = z.object({ | ||
| alert_id: z.string(), | ||
| alert_index: z.string(), | ||
| timeline_string: z.string().describe('A Timeline-like English string for the alert'), | ||
| message: z.string(), | ||
| }); | ||
|
|
||
| export const renderAlertNarrativeStepDefinition: PublicStepDefinition = { | ||
| id: 'security.renderAlertNarrative', | ||
| inputSchema, | ||
| outputSchema, | ||
| category: StepCategory.Elasticsearch, |
There was a problem hiding this comment.
I'd recommend keeping the props that are shared between public and server registration in a common place. To avoid duplication and potentially drifting over time. The spec of the shared props is here
Also:
- It would be interesting to add
documentationon the server side as well, since it's going to be leveraged by the agent builder. - I see the feature flag. Consider adding
stability: 'tech_preview'.
There was a problem hiding this comment.
Updated props to be shared, included tech preview flag and documentation: https://github.com/elastic/kibana/pull/259159/changes#diff-4ce48f9c9a7ebb96b18a84c44963f8e99ee47eb81b5925944e406910b48bbae0R41
| label: 'Render Alert Narrative', | ||
| description: | ||
| 'Render a human-readable narrative string for an alert based on its event, process, network, and host fields', | ||
| category: StepCategory.Elasticsearch, |
There was a problem hiding this comment.
Fix the category to be Kibana
Catch flakiness early (recommended)Recommended before merge: run the flaky test runner against this PR to catch flakiness early. Trigger a run with the Flaky Test Runner UI or post this comment on the PR: This check is experimental. Share your feedback in the #appex-qa channel. Posted via Macroscope — Flaky Test Runner nudge |
Scout Test ReviewNo issues found ✅ The two new entries in Share feedback in the #appex-qa channel. Posted via Macroscope — Scout Test Review |
There was a problem hiding this comment.
</antml :parameter>
[{"path": "src/platform/plugins/shared/workflows_extensions/test/scout/api/fixtures/approved_step_definitions.ts", "body": "🔵 Minor — Fixture maintainability\n\nThe file header states entries must be "alphabetically sorted", but the new security.* entries are placed before the cases.* block, which itself was already out of alphabetical order. Since the approval test iterates over registered steps and does a find() lookup, ordering doesn't affect correctness, but it does make the fixture harder to scan and maintain as the list grows.\n\nConsider moving cases.* entries to their correct alphabetical position (before data.*) so the full list follows the documented convention — or at minimum ensure security.* is placed after search.* and before any block that starts with a letter > s (which it currently is, so the new entries are correct relative to each other).\n\nThis is a pre-existing issue, not introduced by this PR. No action strictly required.", "line": 87, "start_line": 87, "side": "RIGHT", "start_side": "RIGHT"}]
Posted via Macroscope — Scout Test Review
|
/flaky scoutConfig:src/platform/plugins/shared/workflows_extensions/test/scout/api/playwright.config.ts:30 |
Flaky Test Runner✅ Build triggered - kibana-flaky-test-suite-runner#11735
|
Flaky Test Runner Stats🎉 All tests passed! - kibana-flaky-test-suite-runner#11735[✅] src/platform/plugins/shared/workflows_extensions/test/scout/api/playwright.config.ts: 30/30 tests passed. |
Three constants were dropped during a merge with main: - SIEM_MIGRATIONS_MANAGE_PATH - EXCLUDED_GAP_REASONS_KEY - NEW_FEATURES_TOUR_STORAGE_KEYS.AI_RULE_CREATION_MENU These are still referenced by other files in the plugin and their removal caused 17 type check errors in CI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/ci |
| "serverless", | ||
| "agentBuilder", | ||
| "llmTasks", | ||
| "workflowsManagement", |
There was a problem hiding this comment.
Is this really needed? Everything should be configurable via workflowsExtensions alone.
There was a problem hiding this comment.
Yep not needed - accidentally carried over from #253245
| if (plugins.workflowsExtensions) { | ||
| const workflowsExtensions = plugins.workflowsExtensions; | ||
| core | ||
| .getStartServices() | ||
| .then(async ([coreStart]) => { | ||
| await registerWorkflowSteps(workflowsExtensions, coreStart); | ||
| }) | ||
| .catch((error) => { | ||
| this.logger.error( | ||
| `[RegisterAlertValidationSteps] Error registering alert validation steps: ${error.message}`, | ||
| { | ||
| error: error.stack, | ||
| } | ||
| ); | ||
| }); | ||
| } |
There was a problem hiding this comment.
It would be better to call workflowsExtensions.registerStepDefinition synchronously.
The registry already accepts an async loader for the step definition, and we manage the promise internally. This approach delays registration beyond the start() lifecycle, which can be problematic.
However, I see the feature flag is preventing the registration, which is something we do not have a solution for.
I'll create a small PR adding support for it (on the server side as well), and I'll update this logic.
Let's keep this approach for now. I'll keep you posted @KDKHD .
There was a problem hiding this comment.
I just realized this is the server side. The comment is referring to the public side registration.
nvm, I'll adapt both anyway.
semd
left a comment
There was a problem hiding this comment.
Approving.
Remember to remove the unnecessary dependency.
LGTM!
💛 Build succeeded, but was flaky
Failed CI Steps
Metrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsasync chunk count
References to deprecated APIs
Unreferenced deprecated APIs
History
|
…sationChanges23 * commit '9a7b717c662d1c904052bc59f0e5a81daab87c7f': (145 commits) Upgrade EUI to v114.2.0 (elastic#264550) [Entity Analytics] Add missing OpenAPI descriptions and examples to p… (elastic#264778) [Entity Resolution] Clarify CSV upload result for already-linked entities (elastic#264689) [AI Infra] Fix failing GenAI Settings Scout tests (elastic#260496) [Agent Builder] [Bug Bash] OAuth connector settings mention fields that are not there (elastic#264756) [performance] process-wide cache for advanced settings lookup (elastic#262618) [CI] Update limits.yml for securitySolution (elastic#264946) [SLO] Fix APM embeddable ids (elastic#264750) [EDR Workflows] Unify artifacts empty state buttons (elastic#264389) [Alert Triage workflow] Adds security.buildAlertEntityGraph and security.renderAlertNarrative… (elastic#259159) [SigEvents] Add KI feature identification endpoints and refactor task to use shared service (elastic#263528) [Scout] Migrate Data Views API tests from FTR - Part5 (elastic#264088) [Cases] Apply shared extended_fields path util server side (elastic#264706) [Lens as code] Fix metric trendline (elastic#264777) [api-docs] 2026-04-22 Daily api_docs build (elastic#264882) [Scout] Update test config manifests (elastic#264575) [workflows_management] Lazy-load Zod connector schemas to cut idle memory (elastic#264283) [ES|QL] Fix ES|QL columns reset race during active fetch (elastic#263947) [Content List] Column layout props, sticky actions, and title click handlers (elastic#264203) [Lens as code] Validate `id` in route for new vis types (elastic#264480) ...
## Summary From: #259159 Enables conditional async registration of workflow custom steps on both the public and server side of the `workflows_extensions` plugin. - `registerStepDefinition` now accepts a sync definition **or** an async loader (`() => Promise<Definition | undefined>`). A loader resolving to `undefined` is a no-op, so plugins can gate registration behind async checks (e.g. feature flags, license, capabilities) without an explicit branch around the call. - Adds `isReady()` to the shared `WorkflowsExtensionsStartContract` (already present on the public start; now also on the server start). It resolves once every pending async loader has settled. - Loader rejections — and any error thrown while inserting the resolved definition into the registry — are caught and **logged via the plugin logger** as `Failed to register step definition` with the original error attached as meta. They do **not** propagate, so a single broken loader cannot break other steps or workflow execution as a whole. Consequently, `isReady()` always resolves; consumers can `await` it without try/catch. - The execution engine `setupDependencies` awaits `workflowsExtensions.isReady()` before reading the workflow execution, so step handlers registered asynchronously are guaranteed to be available when the engine runs. - Both `PublicStepRegistry` and `ServerStepRegistry` now take a `Logger` in their constructor, wired from the corresponding plugin's `initializerContext.logger.get()`. ## Changes - `workflows_extensions/common/types.ts` — add `isReady(): Promise<void>` to `WorkflowsExtensionsStartContract`. - `workflows_extensions/public/step_registry/step_registry.ts` — accept loader, skip on `undefined`, log loader/registration errors via the injected `Logger`. - `workflows_extensions/server/step_registry/step_registry.ts` — same async/loader behavior + `whenReady()`, takes a `Logger` in the constructor. - `workflows_extensions/server/plugin.ts` — expose `isReady()` from start; accept `ServerStepDefinitionOrLoader` in `registerStepDefinition`; pass the plugin logger to `ServerStepRegistry`. - `workflows_extensions/public/plugin.ts` — pass the plugin logger to `PublicStepRegistry`. - `workflows_extensions/public/types.ts` & `server/types.ts` — types for the new loader signature; move `isReady()` into the shared start contract. - `workflows_extensions/server/mocks.ts` — add `isReady` to the start mock. - `workflows_extensions/dev_docs/STEPS.md` — document async + conditional registration on both sides, the log-don't-throw error model, and the server-side `isReady()`. - `workflows_execution_engine/server/execution_functions/setup_dependencies.ts` — `await workflowsExtensions.isReady()` before fetching the workflow execution. ## Test plan - Unit tests updated/added for both registries (sync, async loader, `undefined`-skip, mixed sync/async, duplicate handling via async loader, loader rejection — all assert that `whenReady()` resolves and that `logger.error` is called with the original error). - Unit tests added for `setupDependencies` covering: it awaits `isReady()` before reading the execution, and propagates errors thrown by `isReady()`. - All affected Jest suites pass locally. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…264788) ## Summary From: elastic#259159 Enables conditional async registration of workflow custom steps on both the public and server side of the `workflows_extensions` plugin. - `registerStepDefinition` now accepts a sync definition **or** an async loader (`() => Promise<Definition | undefined>`). A loader resolving to `undefined` is a no-op, so plugins can gate registration behind async checks (e.g. feature flags, license, capabilities) without an explicit branch around the call. - Adds `isReady()` to the shared `WorkflowsExtensionsStartContract` (already present on the public start; now also on the server start). It resolves once every pending async loader has settled. - Loader rejections — and any error thrown while inserting the resolved definition into the registry — are caught and **logged via the plugin logger** as `Failed to register step definition` with the original error attached as meta. They do **not** propagate, so a single broken loader cannot break other steps or workflow execution as a whole. Consequently, `isReady()` always resolves; consumers can `await` it without try/catch. - The execution engine `setupDependencies` awaits `workflowsExtensions.isReady()` before reading the workflow execution, so step handlers registered asynchronously are guaranteed to be available when the engine runs. - Both `PublicStepRegistry` and `ServerStepRegistry` now take a `Logger` in their constructor, wired from the corresponding plugin's `initializerContext.logger.get()`. ## Changes - `workflows_extensions/common/types.ts` — add `isReady(): Promise<void>` to `WorkflowsExtensionsStartContract`. - `workflows_extensions/public/step_registry/step_registry.ts` — accept loader, skip on `undefined`, log loader/registration errors via the injected `Logger`. - `workflows_extensions/server/step_registry/step_registry.ts` — same async/loader behavior + `whenReady()`, takes a `Logger` in the constructor. - `workflows_extensions/server/plugin.ts` — expose `isReady()` from start; accept `ServerStepDefinitionOrLoader` in `registerStepDefinition`; pass the plugin logger to `ServerStepRegistry`. - `workflows_extensions/public/plugin.ts` — pass the plugin logger to `PublicStepRegistry`. - `workflows_extensions/public/types.ts` & `server/types.ts` — types for the new loader signature; move `isReady()` into the shared start contract. - `workflows_extensions/server/mocks.ts` — add `isReady` to the start mock. - `workflows_extensions/dev_docs/STEPS.md` — document async + conditional registration on both sides, the log-don't-throw error model, and the server-side `isReady()`. - `workflows_execution_engine/server/execution_functions/setup_dependencies.ts` — `await workflowsExtensions.isReady()` before fetching the workflow execution. ## Test plan - Unit tests updated/added for both registries (sync, async loader, `undefined`-skip, mixed sync/async, duplicate handling via async loader, loader rejection — all assert that `whenReady()` resolves and that `logger.error` is called with the original error). - Unit tests added for `setupDependencies` covering: it awaits `isReady()` before reading the execution, and propagates errors thrown by `isReady()`. - All affected Jest suites pass locally. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…nc loaders (#265230) ## Summary Follows up on #264788 (merged by @semd) which added async-loader support to the `ServerStepRegistry` and `PublicStepRegistry`. Previously, `registerStepDefinition` was called inside a deferred `getStartServices().then()` callback — meaning registration happened *after* the `setup()` lifecycle completed. semd flagged this as problematic in review comments on #259159 ([comment 1](#259159 (comment)), [comment 2](#259159 (comment))). This PR applies the fix on the security_solution side: `registerStepDefinition` is now called **synchronously** during `setup()`. Each step is registered with an async loader that checks the feature flag at resolution time and returns `undefined` to skip registration when the flag is disabled. Changes on both server and public sides: - `registerWorkflowSteps` is now a synchronous function accepting `CoreSetup` instead of `CoreStart` - Each step is wrapped in an async loader that defers the feature-flag check to resolution time - `plugin.ts` / `plugin.tsx` call `registerWorkflowSteps` directly in `setup()` (no deferred `.then()`) - New unit tests for both server and public `registerWorkflowSteps` ## Test plan - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/server/workflows/step_types/register_workflow_steps.test.ts` - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/public/workflows/step_types/register_workflow_steps.test.ts` - [ ] Confirm no regression in existing workflow step tests
…nc loaders (elastic#265230) ## Summary Follows up on elastic#264788 (merged by @semd) which added async-loader support to the `ServerStepRegistry` and `PublicStepRegistry`. Previously, `registerStepDefinition` was called inside a deferred `getStartServices().then()` callback — meaning registration happened *after* the `setup()` lifecycle completed. semd flagged this as problematic in review comments on elastic#259159 ([comment 1](elastic#259159 (comment)), [comment 2](elastic#259159 (comment))). This PR applies the fix on the security_solution side: `registerStepDefinition` is now called **synchronously** during `setup()`. Each step is registered with an async loader that checks the feature flag at resolution time and returns `undefined` to skip registration when the flag is disabled. Changes on both server and public sides: - `registerWorkflowSteps` is now a synchronous function accepting `CoreSetup` instead of `CoreStart` - Each step is wrapped in an async loader that defers the feature-flag check to resolution time - `plugin.ts` / `plugin.tsx` call `registerWorkflowSteps` directly in `setup()` (no deferred `.then()`) - New unit tests for both server and public `registerWorkflowSteps` ## Test plan - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/server/workflows/step_types/register_workflow_steps.test.ts` - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/public/workflows/step_types/register_workflow_steps.test.ts` - [ ] Confirm no regression in existing workflow step tests
…nc loaders (elastic#265230) ## Summary Follows up on elastic#264788 (merged by @semd) which added async-loader support to the `ServerStepRegistry` and `PublicStepRegistry`. Previously, `registerStepDefinition` was called inside a deferred `getStartServices().then()` callback — meaning registration happened *after* the `setup()` lifecycle completed. semd flagged this as problematic in review comments on elastic#259159 ([comment 1](elastic#259159 (comment)), [comment 2](elastic#259159 (comment))). This PR applies the fix on the security_solution side: `registerStepDefinition` is now called **synchronously** during `setup()`. Each step is registered with an async loader that checks the feature flag at resolution time and returns `undefined` to skip registration when the flag is disabled. Changes on both server and public sides: - `registerWorkflowSteps` is now a synchronous function accepting `CoreSetup` instead of `CoreStart` - Each step is wrapped in an async loader that defers the feature-flag check to resolution time - `plugin.ts` / `plugin.tsx` call `registerWorkflowSteps` directly in `setup()` (no deferred `.then()`) - New unit tests for both server and public `registerWorkflowSteps` ## Test plan - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/server/workflows/step_types/register_workflow_steps.test.ts` - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/public/workflows/step_types/register_workflow_steps.test.ts` - [ ] Confirm no regression in existing workflow step tests
…ity.renderAlertNarrative… (elastic#259159) … steps ## Summary Migrates two new workflow step definitions from `feature/alert-false-positive-queue` into this branch so they can be developed and shipped independently. The two steps added are: - **`renderAlertNarrativeStepDefinition`** — renders a human-readable narrative for an alert based on its event category (process, network, file, DNS, authentication, cloud, registry, ML, threat match) - **`buildAlertEntityGraphStepDefinition`** — builds an entity relationship graph for an alert by querying related events and scoring entity connections Both steps are registered behind the feature flag `securitySolution.registerAlertValidationStepsEnabled` (defaults to `true`) to allow safe removal of the flag at a later date without a code change. These 2 steps will be used by the alert false positive workflow in [feature/alert-false-positive-queue](https://github.com/KDKHD/kibana/tree/feature/alert-false-positive-queue) ## Changes - `kibana.jsonc` — adds `workflowsManagement` and `workflowsExtensions` as optional plugin dependencies - `server/plugin_contract.ts` / `public/types.ts` — adds `WorkflowsExtensions` types to setup/start dependency interfaces - `common/constants.ts` — adds `REGISTER_ALERT_VALIDATION_STEPS_FEATURE_FLAG` and `PREINSTALLED_WORKFLOWS_FEATURE_FLAG` constants - `server/plugin.ts` / `public/plugin.tsx` — registers step definitions on plugin setup, gated by the feature flag - `server/workflows/step_types/render_alert_narrative_step/` — server-side step implementation with strategy pattern per event category - `server/workflows/step_types/build_alert_entity_graph_step/` — server-side step implementation with entity graph traversal and scoring - `public/workflows/step_types/render_alert_narrative_step/` — client-side step definition - `public/workflows/step_types/build_alert_entity_graph_step/` — client-side step definition ## Follow-up Remove the `REGISTER_ALERT_VALIDATION_STEPS_FEATURE_FLAG` guard in `server/workflows/step_types/register_workflow_steps.ts` and `public/workflows/step_types/register_workflow_steps.ts` once the steps are ready to ship unconditionally. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [X] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [X] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [X] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [X] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [X] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [X] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [X] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…264788) ## Summary From: elastic#259159 Enables conditional async registration of workflow custom steps on both the public and server side of the `workflows_extensions` plugin. - `registerStepDefinition` now accepts a sync definition **or** an async loader (`() => Promise<Definition | undefined>`). A loader resolving to `undefined` is a no-op, so plugins can gate registration behind async checks (e.g. feature flags, license, capabilities) without an explicit branch around the call. - Adds `isReady()` to the shared `WorkflowsExtensionsStartContract` (already present on the public start; now also on the server start). It resolves once every pending async loader has settled. - Loader rejections — and any error thrown while inserting the resolved definition into the registry — are caught and **logged via the plugin logger** as `Failed to register step definition` with the original error attached as meta. They do **not** propagate, so a single broken loader cannot break other steps or workflow execution as a whole. Consequently, `isReady()` always resolves; consumers can `await` it without try/catch. - The execution engine `setupDependencies` awaits `workflowsExtensions.isReady()` before reading the workflow execution, so step handlers registered asynchronously are guaranteed to be available when the engine runs. - Both `PublicStepRegistry` and `ServerStepRegistry` now take a `Logger` in their constructor, wired from the corresponding plugin's `initializerContext.logger.get()`. ## Changes - `workflows_extensions/common/types.ts` — add `isReady(): Promise<void>` to `WorkflowsExtensionsStartContract`. - `workflows_extensions/public/step_registry/step_registry.ts` — accept loader, skip on `undefined`, log loader/registration errors via the injected `Logger`. - `workflows_extensions/server/step_registry/step_registry.ts` — same async/loader behavior + `whenReady()`, takes a `Logger` in the constructor. - `workflows_extensions/server/plugin.ts` — expose `isReady()` from start; accept `ServerStepDefinitionOrLoader` in `registerStepDefinition`; pass the plugin logger to `ServerStepRegistry`. - `workflows_extensions/public/plugin.ts` — pass the plugin logger to `PublicStepRegistry`. - `workflows_extensions/public/types.ts` & `server/types.ts` — types for the new loader signature; move `isReady()` into the shared start contract. - `workflows_extensions/server/mocks.ts` — add `isReady` to the start mock. - `workflows_extensions/dev_docs/STEPS.md` — document async + conditional registration on both sides, the log-don't-throw error model, and the server-side `isReady()`. - `workflows_execution_engine/server/execution_functions/setup_dependencies.ts` — `await workflowsExtensions.isReady()` before fetching the workflow execution. ## Test plan - Unit tests updated/added for both registries (sync, async loader, `undefined`-skip, mixed sync/async, duplicate handling via async loader, loader rejection — all assert that `whenReady()` resolves and that `logger.error` is called with the original error). - Unit tests added for `setupDependencies` covering: it awaits `isReady()` before reading the execution, and propagates errors thrown by `isReady()`. - All affected Jest suites pass locally. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
…nc loaders (elastic#265230) ## Summary Follows up on elastic#264788 (merged by @semd) which added async-loader support to the `ServerStepRegistry` and `PublicStepRegistry`. Previously, `registerStepDefinition` was called inside a deferred `getStartServices().then()` callback — meaning registration happened *after* the `setup()` lifecycle completed. semd flagged this as problematic in review comments on elastic#259159 ([comment 1](elastic#259159 (comment)), [comment 2](elastic#259159 (comment))). This PR applies the fix on the security_solution side: `registerStepDefinition` is now called **synchronously** during `setup()`. Each step is registered with an async loader that checks the feature flag at resolution time and returns `undefined` to skip registration when the flag is disabled. Changes on both server and public sides: - `registerWorkflowSteps` is now a synchronous function accepting `CoreSetup` instead of `CoreStart` - Each step is wrapped in an async loader that defers the feature-flag check to resolution time - `plugin.ts` / `plugin.tsx` call `registerWorkflowSteps` directly in `setup()` (no deferred `.then()`) - New unit tests for both server and public `registerWorkflowSteps` ## Test plan - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/server/workflows/step_types/register_workflow_steps.test.ts` - [ ] `node scripts/jest x-pack/solutions/security/plugins/security_solution/public/workflows/step_types/register_workflow_steps.test.ts` - [ ] Confirm no regression in existing workflow step tests
… steps
Summary
Migrates two new workflow step definitions from
feature/alert-false-positive-queueinto this branch so they can be developed and shipped independently.The two steps added are:
renderAlertNarrativeStepDefinition— renders a human-readable narrative for an alert based on its event category (process, network, file, DNS, authentication, cloud, registry, ML, threat match)buildAlertEntityGraphStepDefinition— builds an entity relationship graph for an alert by querying related events and scoring entity connectionsBoth steps are registered behind the feature flag
securitySolution.registerAlertValidationStepsEnabled(defaults totrue) to allow safe removal of the flag at a later date without a code change. These 2 steps will be used by the alert false positive workflow in feature/alert-false-positive-queueChanges
kibana.jsonc— addsworkflowsManagementandworkflowsExtensionsas optional plugin dependenciesserver/plugin_contract.ts/public/types.ts— addsWorkflowsExtensionstypes to setup/start dependency interfacescommon/constants.ts— addsREGISTER_ALERT_VALIDATION_STEPS_FEATURE_FLAGandPREINSTALLED_WORKFLOWS_FEATURE_FLAGconstantsserver/plugin.ts/public/plugin.tsx— registers step definitions on plugin setup, gated by the feature flagserver/workflows/step_types/render_alert_narrative_step/— server-side step implementation with strategy pattern per event categoryserver/workflows/step_types/build_alert_entity_graph_step/— server-side step implementation with entity graph traversal and scoringpublic/workflows/step_types/render_alert_narrative_step/— client-side step definitionpublic/workflows/step_types/build_alert_entity_graph_step/— client-side step definitionFollow-up
Remove the
REGISTER_ALERT_VALIDATION_STEPS_FEATURE_FLAGguard inserver/workflows/step_types/register_workflow_steps.tsandpublic/workflows/step_types/register_workflow_steps.tsonce the steps are ready to ship unconditionally.Checklist
Check the PR satisfies following conditions.
Reviewers should verify this PR satisfies this list as well.
release_note:breakinglabel should be applied in these situations.release_note:*label is applied per the guidelinesbackport:*labels.Identify risks
Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss.
Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging.