Skip to content

Commit

Permalink
[Security Solution][Endpoint] refactor server-side response actions s…
Browse files Browse the repository at this point in the history
…ervice utilities (elastic#183859)

## Summary

Refactor of several service utilities related to response actions,
including:

- Deleted `action_list_helpers` from `server/endpoint/utils` and move
those function still in use to the `action_audit_log` (old deprecated
API)
- Renamed `actions.ts` to `action_audit_log.ts` to better reflect the
(deprecated) API that these services are associated with
- Simplified several utilities to no longer use
`ActivityLogActionResponse` or `EndpointActivityLogActionResponse` and
refactored existing utilities that depended on these types to just work
with the underlying `LogsEndpointActionResponse` and
`LogsEndpointActionResponse` instead
- moved logic that queries for list of Action Requests to its own module
- Changed signature of `fetchAllPendingActions()` (from
`BaseReponseActionsClient` class) to now return: `Array<{ action:
LogsEndpointAction; pendingAgentIds: string[]}>`
- Change will enable consumers of the `protected` method to now receive
a list of agent IDs for which a response is still pending
- Work in preparation for when we start to support sending response
actions to multiple agents
- Delete some unused code throughout
  • Loading branch information
paul-tavares authored May 31, 2024
1 parent 310f4ff commit 3dbf997
Show file tree
Hide file tree
Showing 24 changed files with 1,336 additions and 1,653 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class FleetActionGenerator extends BaseDataGenerator {
return merge(this.generate({ data: { command: 'unisolate' } }), overrides);
}

/** Generates an endpoint action response */
/** Generates an endpoint Fleet action response */
generateResponse(overrides: DeepPartial<EndpointActionResponse> = {}): EndpointActionResponse {
const timeStamp = overrides['@timestamp'] ? new Date(overrides['@timestamp']) : new Date();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ export interface EndpointActionData<
comment?: string;
parameters?: TParameters;
output?: ActionResponseOutput<TOutputContent>;
/**
* If `alert_id` is defined, then action request is of type `automated`
*
* **IMPORTANT**: should be used only when response actions are created from a Rule (automated response actions)
* as this property is used to determine if an action is of type `automated`
*/
alert_id?: string[];
hosts?: Record<string, { name: string }>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import type {
EndpointActionLogRequestParams,
EndpointActionLogRequestQuery,
} from '../../../../common/api/endpoint';
import { getAuditLogResponse } from '../../services';
import type { SecuritySolutionRequestHandlerContext } from '../../../types';
import { getAuditLogResponse } from '../../services/actions/actions_audit_log';
import type { EndpointAppContext } from '../../types';

export const auditLogRequestHandler = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@

import type { ElasticsearchClient } from '@kbn/core/server';

import type { FetchActionResponsesResult } from './utils/fetch_action_responses';
import { fetchActionResponses } from './utils/fetch_action_responses';
import { ENDPOINT_ACTIONS_INDEX } from '../../../../common/endpoint/constants';
import {
formatEndpointActionResults,
categorizeResponseResults,
mapToNormalizedActionRequest,
getAgentHostNamesWithIds,
createActionDetailsRecord,
} from './utils';
import type {
ActionDetails,
ActivityLogActionResponse,
EndpointActivityLogAction,
EndpointActivityLogActionResponse,
LogsEndpointAction,
} from '../../../../common/endpoint/types';
import { catchAndWrapError } from '../../utils';
Expand All @@ -42,11 +40,11 @@ export const getActionDetailsById = async <T extends ActionDetails = ActionDetai
let actionRequestsLogEntries: EndpointActivityLogAction[];

let normalizedActionRequest: ReturnType<typeof mapToNormalizedActionRequest> | undefined;
let actionResponses: Array<ActivityLogActionResponse | EndpointActivityLogActionResponse>;
let actionResponses: FetchActionResponsesResult;

try {
// Get both the Action Request(s) and action Response(s)
const [actionRequestEsSearchResults, allResponseEsHits] = await Promise.all([
const [actionRequestEsSearchResults, actionResponseResult] = await Promise.all([
// Get the action request(s)
esClient
.search<LogsEndpointAction>(
Expand All @@ -66,9 +64,10 @@ export const getActionDetailsById = async <T extends ActionDetails = ActionDetai
)
.catch(catchAndWrapError),

fetchActionResponses({ esClient, actionIds: [actionId] }).then((response) => response.data),
fetchActionResponses({ esClient, actionIds: [actionId] }),
]);

actionResponses = actionResponseResult;
actionRequestsLogEntries = formatEndpointActionResults(
actionRequestEsSearchResults?.hits?.hits ?? []
);
Expand All @@ -80,10 +79,6 @@ export const getActionDetailsById = async <T extends ActionDetails = ActionDetai
if (actionDoc) {
normalizedActionRequest = mapToNormalizedActionRequest(actionDoc);
}

actionResponses = categorizeResponseResults({
results: allResponseEsHits,
});
} catch (error) {
throw new EndpointError(error.message, error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,74 +339,72 @@ describe('When using `getActionList()', () => {
expect(esClient.search).toHaveBeenNthCalledWith(
1,
{
body: {
query: {
bool: {
must: [
{
bool: {
filter: [
{
range: {
'@timestamp': {
gte: 'now-10d',
},
query: {
bool: {
must: [
{
bool: {
filter: [
{
range: {
'@timestamp': {
gte: 'now-10d',
},
},
{
range: {
'@timestamp': {
lte: 'now',
},
},
{
range: {
'@timestamp': {
lte: 'now',
},
},
{
terms: {
'data.command': ['isolate', 'unisolate', 'get-file'],
},
},
{
terms: {
'data.command': ['isolate', 'unisolate', 'get-file'],
},
{
terms: {
input_type: ['endpoint'],
},
},
{
terms: {
input_type: ['endpoint'],
},
{
terms: {
agents: ['123'],
},
},
{
terms: {
agents: ['123'],
},
],
},
},
],
},
{
bool: {
should: [
{
query_string: {
fields: ['user_id'],
query: '*elastic*',
},
},
{
bool: {
should: [
{
query_string: {
fields: ['user_id'],
query: '*elastic*',
},
],
minimum_should_match: 1,
},
},
],
minimum_should_match: 1,
},
],
},
},
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
],
},
},
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
from: 0,
index: '.logs-endpoint.actions-default',
size: 20,
},
{ ignore: [404], meta: true }
{ ignore: [404] }
);
});

Expand All @@ -430,77 +428,75 @@ describe('When using `getActionList()', () => {
expect(esClient.search).toHaveBeenNthCalledWith(
1,
{
body: {
query: {
bool: {
must: [
{
bool: {
filter: [
{
range: {
'@timestamp': {
gte: 'now-1d',
},
query: {
bool: {
must: [
{
bool: {
filter: [
{
range: {
'@timestamp': {
gte: 'now-1d',
},
},
{
range: {
'@timestamp': {
lte: 'now',
},
},
{
range: {
'@timestamp': {
lte: 'now',
},
},
],
},
},
],
},
{
bool: {
should: [
{
bool: {
should: [
{
match: {
user_id: 'elastic',
},
},
{
bool: {
should: [
{
bool: {
should: [
{
match: {
user_id: 'elastic',
},
],
minimum_should_match: 1,
},
},
],
minimum_should_match: 1,
},
{
bool: {
should: [
{
match: {
user_id: 'kibana',
},
},
{
bool: {
should: [
{
match: {
user_id: 'kibana',
},
],
minimum_should_match: 1,
},
},
],
minimum_should_match: 1,
},
],
minimum_should_match: 1,
},
},
],
minimum_should_match: 1,
},
],
},
},
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
],
},
},
sort: [
{
'@timestamp': {
order: 'desc',
},
},
],
from: 0,
index: '.logs-endpoint.actions-default',
size: 10,
},
{ ignore: [404], meta: true }
{ ignore: [404] }
);
});

Expand Down
Loading

0 comments on commit 3dbf997

Please sign in to comment.