Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
21dde1a
[SecuritySolution] Alerts/Attacks promotion
e40pud Feb 11, 2026
5a50530
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 13, 2026
c6ae75e
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 16, 2026
5a9bd61
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 18, 2026
c465a94
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 20, 2026
614f898
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 23, 2026
c03f6a5
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 23, 2026
1403fd2
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 24, 2026
0662084
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 24, 2026
5b8c68b
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 24, 2026
c2c6b33
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 25, 2026
e60c507
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 26, 2026
e2428b6
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 27, 2026
ed0d696
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Feb 27, 2026
7df256a
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 2, 2026
36ee891
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 3, 2026
539b0ad
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 3, 2026
574b0c9
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 3, 2026
62b825a
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 4, 2026
4114c25
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 4, 2026
922b000
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 5, 2026
5e30fc5
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 5, 2026
e3b049c
POC 2
e40pud Mar 5, 2026
b053bb5
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 6, 2026
a62942d
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 6, 2026
a9167ed
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 9, 2026
f06a595
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 9, 2026
8341c57
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 10, 2026
ca75431
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 10, 2026
4fde6fb
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 10, 2026
c9e9c31
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 10, 2026
b526b02
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 11, 2026
f2369cb
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 11, 2026
06d782f
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 11, 2026
b7596b5
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 11, 2026
60665ed
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 12, 2026
1117f09
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 12, 2026
c9d5132
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 13, 2026
2cc4250
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 16, 2026
2628b58
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 17, 2026
22b3523
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 18, 2026
82b0bc5
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 19, 2026
908257d
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 19, 2026
f5d5cf6
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 20, 2026
b6bac52
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 23, 2026
8dae144
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 24, 2026
0ee6665
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 25, 2026
097cfbd
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 25, 2026
36fa2cd
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 26, 2026
f88d0b7
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 27, 2026
0565dc2
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 30, 2026
5c341b4
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 30, 2026
d4dfeb3
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 30, 2026
980ff1e
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 31, 2026
0f14755
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Mar 31, 2026
184f013
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 2, 2026
97cdc8f
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 7, 2026
1cef865
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 7, 2026
e4d3c85
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 8, 2026
96ca61f
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 9, 2026
e60ffd4
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 10, 2026
81ac012
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 20, 2026
dddc2e0
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 21, 2026
1aa6027
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 22, 2026
bd78722
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 24, 2026
b91679b
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 27, 2026
a27e488
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 28, 2026
563801b
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud Apr 30, 2026
148da7d
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 4, 2026
1d7fc8e
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 5, 2026
bb90c3d
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 6, 2026
08f306f
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 7, 2026
3e74902
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 7, 2026
0cf1c5d
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 8, 2026
8ecb30f
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 11, 2026
4d084eb
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 12, 2026
08e2e45
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 13, 2026
8fe585b
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 15, 2026
fb57e87
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 18, 2026
4c516d2
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 18, 2026
9458a5e
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 19, 2026
5e454b2
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 20, 2026
4a42e33
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 21, 2026
731b208
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 22, 2026
1cd2544
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 22, 2026
4792581
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 25, 2026
217fde4
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 26, 2026
fc83431
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 29, 2026
df8f886
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 29, 2026
109ec28
Merge branch 'main' into security/attack-alerts-alignment/POC-attack-…
e40pud May 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const DEFEND_INSIGHTS_BY_ID = `${DEFEND_INSIGHTS}/{id}`;

// Attack Discovery
export const ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID = 'attack-discovery' as const;
export const ATTACK_DISCOVERY_PROMOTE_ATTACK_RULE_TYPE_ID = 'security.attack.promotion' as const;
export const ATTACK_DISCOVERY_SCHEDULES_CONSUMER_ID = 'siem' as const;

// Attack discovery public API
Expand Down Expand Up @@ -116,6 +117,7 @@ export const ATTACK_DISCOVERY_INTERNAL =
`${ELASTIC_AI_ASSISTANT_INTERNAL_URL}/attack_discovery` as const;
export const ATTACK_DISCOVERY_INTERNAL_MISSING_PRIVILEGES =
`${ATTACK_DISCOVERY_INTERNAL}/_missing_privileges` as const;
export const ATTACK_DISCOVERY_INTERNAL_PROMOTE = `${ATTACK_DISCOVERY_INTERNAL}/_promote` as const;

/** A fake `kibana.alert.rule.uuid` for ad hock rules */
export const ATTACK_DISCOVERY_AD_HOC_RULE_ID = 'attack_discovery_ad_hoc_rule_id' as const;
Expand Down
Original file line number Diff line number Diff line change
@@ -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 { z } from '@kbn/zod/v4';

export const PostAttackDiscoveryPromoteRequestBody = z.object({
attack_ids: z.array(z.string()).min(1),
});

export type PostAttackDiscoveryPromoteRequestBody = z.infer<
typeof PostAttackDiscoveryPromoteRequestBody
>;

export const PostAttackDiscoveryPromoteResponse = z.object({
success: z.boolean(),
execution_uuid: z.string().optional(),
error: z.string().optional(),
});

export type PostAttackDiscoveryPromoteResponse = z.infer<typeof PostAttackDiscoveryPromoteResponse>;
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ export {
PostAttackDiscoveryGenerationsDismissResponse,
} from './attack_discovery/routes/public/post/post_attack_discovery_generations_dismiss.route.gen';

export {
PostAttackDiscoveryPromoteRequestBody,
PostAttackDiscoveryPromoteResponse,
} from './attack_discovery/routes/internal/promote/post_attack_discovery_promote';

export {
GetAttackDiscoveryGenerationRequestParams,
GetAttackDiscoveryGenerationRequestQuery,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/*
* 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 {
ISavedObjectsRepository,
Logger,
SavedObjectReference,
SavedObjectsBulkCreateObject,
SavedObjectsClientContract,
} from '@kbn/core/server';
import type { AuditLogger } from '@kbn/security-plugin/server';
import type {
TaskInstance,
TaskManagerStartContract,
TaskManagerSetupContract,
RunContext,
} from '@kbn/task-manager-plugin/server';
import { TaskPriority } from '@kbn/task-manager-plugin/server';
import type { IEventLogger, IEventLogClient } from '@kbn/event-log-plugin/server';
import type {
ExecutionError,
ScheduleExecutionParams,
ScheduleExecutionResults,
AdHocRunResult,
} from '../application/ad_hoc/types';
import {
transformAdHocRunToBackfillResult,
transformBackfillParamToAdHocRun,
} from '../application/backfill/transforms';
import type { RuleDomain } from '../application/rule/types';
import type { AdHocRunSO } from '../data/ad_hoc_run/types';
import { AdHocRunAuditAction, adHocRunAuditEvent } from '../rules_client/common/audit_events';
import { AD_HOC_RUN_SAVED_OBJECT_TYPE } from '../saved_objects';
import { createExecutionError } from '../application/ad_hoc/lib/create_execution_error';
import type { TaskRunnerFactory } from '../task_runner';

import { AD_HOC_TASK_TYPE } from '../application/ad_hoc/constants';

interface ConstructorOpts {
logger: Logger;
taskManagerSetup: TaskManagerSetupContract;
taskManagerStartPromise: Promise<TaskManagerStartContract>;
taskRunnerFactory: TaskRunnerFactory;
}

interface QueueAdHocExecutionOpts {
auditLogger?: AuditLogger;
params: ScheduleExecutionParams;
rules: RuleDomain[];
spaceId: string;
unsecuredSavedObjectsClient: SavedObjectsClientContract;
eventLogClient: IEventLogClient;
internalSavedObjectsRepository: ISavedObjectsRepository;
eventLogger: IEventLogger | undefined;
}

export class AdHocExecutionClient {
private logger: Logger;
private readonly taskManagerStartPromise: Promise<TaskManagerStartContract>;

constructor(opts: ConstructorOpts) {
this.logger = opts.logger;
this.taskManagerStartPromise = opts.taskManagerStartPromise;

opts.taskManagerSetup.registerTaskDefinitions({
[AD_HOC_TASK_TYPE]: {
title: 'Alerting Ad-hoc Rule Run',
priority: TaskPriority.Low,
createTaskRunner: (context: RunContext) => opts.taskRunnerFactory.createAdHoc(context),
},
});
}

public async queueAdHocExecution({
auditLogger,
params,
rules,
spaceId,
unsecuredSavedObjectsClient,
}: QueueAdHocExecutionOpts): Promise<ScheduleExecutionResults> {
const adHocSOsToCreate: Array<SavedObjectsBulkCreateObject<AdHocRunSO>> = [];
const soToCreateIndexOrErrorMap: Map<number, number | ExecutionError> = new Map();

for (let ndx = 0; ndx < params.length; ndx++) {
const param = params[ndx];
// simplified rule lookup - we expect the rule to be passed in rules array
const rule = rules.find((r) => r.id === param.ruleId);

if (rule) {
soToCreateIndexOrErrorMap.set(ndx, adHocSOsToCreate.length);

const references: SavedObjectReference[] = [
{
name: 'rule',
type: 'rule',
id: rule.id,
},
];

const start = param.start ?? new Date().toISOString();
const end = param.end ?? new Date().toISOString();

const attributes = transformBackfillParamToAdHocRun(
{
ruleId: rule.id,
ranges: [{ start, end }],
runActions: false,
initiator: param.initiator,
initiatorId: param.initiatorId,
},
rule,
[],
spaceId
);
Comment thread
e40pud marked this conversation as resolved.

adHocSOsToCreate.push({
type: AD_HOC_RUN_SAVED_OBJECT_TYPE,
attributes,
references,
});
} else {
const error = createExecutionError(`Rule not found for ID ${param.ruleId}`, param.ruleId);
soToCreateIndexOrErrorMap.set(ndx, error);
this.logger.warn(
`Error for ruleId ${param.ruleId} - not scheduling ad-hoc execution for ${JSON.stringify(
param
)}`
);
}
}

if (!adHocSOsToCreate.length) {
return params.map((_, ndx: number) => soToCreateIndexOrErrorMap.get(ndx) as ExecutionError);
}

// Create Saved Objects
const response = await unsecuredSavedObjectsClient.bulkCreate<AdHocRunSO>(adHocSOsToCreate);

// Process results
const createdSOs = response.saved_objects;

const transformedResponse: ScheduleExecutionResults = [];

// Map back to original order and transform
for (let ndx = 0; ndx < params.length; ndx++) {
const indexOrError = soToCreateIndexOrErrorMap.get(ndx);
if (typeof indexOrError === 'number') {
const so = createdSOs[indexOrError];
if (so.error) {
auditLogger?.log(
adHocRunAuditEvent({
action: AdHocRunAuditAction.CREATE,
error: new Error(so.error.message),
})
);
transformedResponse.push(createExecutionError(so.error.message, params[ndx].ruleId));
} else {
auditLogger?.log(
adHocRunAuditEvent({
action: AdHocRunAuditAction.CREATE,
savedObject: { type: AD_HOC_RUN_SAVED_OBJECT_TYPE, id: so.id },
})
);

const result = transformAdHocRunToBackfillResult({
adHocRunSO: so,
isSystemAction: (id: string) => true, // System action check not relevant here? Or pass dummy
originalSO: adHocSOsToCreate[indexOrError],
});

transformedResponse.push(result);
}
} else {
transformedResponse.push(indexOrError as ExecutionError);
}
}

// Schedule Tasks
const adHocTasksToSchedule: TaskInstance[] = [];
transformedResponse.forEach((result) => {
if (!('error' in result)) {
const createdSO = result as AdHocRunResult;
// We don't have ruleTypeRegistry here easily to check timeout,
// but we can pass it or just default.
adHocTasksToSchedule.push({
id: createdSO.id,
taskType: AD_HOC_TASK_TYPE,
state: {},
params: {
adHocRunParamsId: createdSO.id,
spaceId,
},
});
}
});

if (adHocTasksToSchedule.length > 0) {
const taskManager = await this.taskManagerStartPromise;
await taskManager.bulkSchedule(adHocTasksToSchedule);
}

return transformedResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,33 @@ export interface PublicAlertsClient<
getRecoveredAlerts: () => Array<RecoveredAlertData<AlertData, State, Context, ActionGroupIds>>;
}

export interface IAdHocAlertsClient<
AlertData extends RuleAlertData,
LegacyState extends AlertInstanceState,
LegacyContext extends AlertInstanceContext,
ActionGroupIds extends string,
RecoveryActionGroupId extends string
> {
report(
alert: ReportedAlert<
AlertData,
LegacyState,
LegacyContext,
WithoutReservedActionGroups<ActionGroupIds, RecoveryActionGroupId>
>
): ReportedAlertData<AlertData>;
setAlertData(
alert: UpdateableAlert<
AlertData,
LegacyState,
LegacyContext,
WithoutReservedActionGroups<ActionGroupIds, RecoveryActionGroupId>
>
): void;
processAlerts(): void;
persistAlerts(): Promise<void>;
}

export interface ReportedAlert<
AlertData extends RuleAlertData,
State extends AlertInstanceState,
Expand Down
Loading
Loading