Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Split rule executor by rule type and validate type specific rule params #94857

Merged
merged 16 commits into from
Mar 27, 2021

Conversation

marshallmain
Copy link
Contributor

@marshallmain marshallmain commented Mar 17, 2021

Summary

This PR is copy paste with some refactoring thrown in to support the copy/paste.

Refactor changes include:

  • added warning boolean flag to the "search after return type" that each executor returns. This was a single variable that was shared across all rule types before, so to split the rule executors it has to be returned as part of the result object.
  • Each executor gets a SavedObject that has already been validated to ensure it matches the schema for the rule type. The validation is non-exact, meaning if a rule has fields we don't expect then the validation still passes. However, validation fails if required fields are missing - e.g. if query is missing from a rule that requires a query, or if required threat_match fields are missing. This allows us to rely entirely on the type specific schemas for validation and remove if statements checking if certain required fields exist. For optional fields, e.g. timestamp override, of course we still have to check if the field exists when using it.
  • reduced the number of places we cast filters as Filter[] from unknown. Instead, filters and threatFilters are typed as unknown until we have to cast them as params to buildEsQuery since we don't have validation for filters yet.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

);
logger.warn(errorMessage);
result.warning = true;
// TODO: change this to partialFailure since we don't immediately exit rule function and still do actions at the end?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new TODO: noticed this behavior when adding the warning logic to result. I think this error was added before we created partial errors, would it fit better as a partial error?

tags: rule.attributes.tags,
buildRuleMessage,
});
// The legacy ES client does not define failures when it can be present on the structure, hence why I have the & { failures: [] }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we use the new ES client, we can revisit this

@marshallmain
Copy link
Contributor Author

@elasticmachine merge upstream

@marshallmain marshallmain marked this pull request as ready for review March 23, 2021 22:00
@marshallmain marshallmain requested a review from a team as a code owner March 23, 2021 22:00
@marshallmain marshallmain added release_note:skip Skip the PR/issue when compiling release notes Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detections and Resp Security Detection Response Team v7.13.0 v8.0.0 labels Mar 23, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

Comment on lines 58 to 63
let results: SearchAfterAndBulkCreateReturnType = {
success: true,
warning: false,
bulkCreateTimes: [],
searchAfterTimes: [],
lastLookBackDate: null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we initialize this with the same createSearchAfterReturnType() function used in the other executors?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, I just didn't do it in this PR to limit scope creep

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@yctercero yctercero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I'm not sure I saw why we needed to change the typed partial filters to unknown but that was about it. I pulled down and created different rules to test out that it's all still as expected. That executor file is looking so much better! Thanks for all the work!

@@ -22,7 +22,7 @@ import { Query, Language, Index, TimestampOverrideOrUndefined } from './schemas/
export const getQueryFilter = (
query: Query,
language: Language,
filters: Array<Partial<Filter>>,
filters: unknown,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we turn this into an unknown? It seems that everywhere we're using it we're passing in filters typed as Filter[].

Copy link
Contributor Author

@marshallmain marshallmain Mar 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source of the problem here is that we don't have validation for the Filter type on the server side yet, so in attempting to make the server types more accurate the type of filters in RuleTypeParams became unknown. Then since we had a cast in here on line 51 already I thought we could just do the unsafe cast once at the end instead of passing in a partial then casting to unknown and then to Filter[].

I think you're right though that we should pass in Filter[] and function callers should be responsible for casting the parameter if necessary. As part of the follow up updating server types I'll revisit this - want to get this merged before it conflicts with other work.

@@ -153,12 +161,19 @@ const thresholdSpecificRuleParams = t.type({
savedId: savedIdOrUndefined,
threshold,
});
export const thresholdRuleParams = t.intersection([baseRuleParams, thresholdSpecificRuleParams]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this! Reads easy

} catch (err) {
if (err.statusCode === 403) {
throw new Error(
`EQL based rules require the user that created it to have the view_index_metadata, read, and write permissions for index: ${ruleParams.outputIndex}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the place to do it. But would it be possible to guide our users more with our error messages. Like where to view these permissions for example.

ruleParams.eventCategoryOverride
);
const eqlSignalSearchStart = performance.now();
// TODO: fix this later
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this fix referring to the as?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah this is referring to the use of transport.request still, which was necessary with the legacy ES client because the EQL apis weren't in it - but the EQL api is in the new client, so we can switch over.

const eqlSignalSearchEnd = performance.now();
const eqlSearchDuration = makeFloatString(eqlSignalSearchEnd - eqlSignalSearchStart);
result.searchAfterTimes = [eqlSearchDuration];
let newSignals: WrappedSignalHit[] | undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be cleaner to break this out into a function we can test and also then remove the let just a const newSignals = determineNewSignals()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, that would be cleaner 👍 will do in follow up

@marshallmain marshallmain merged commit 533a7bb into elastic:master Mar 27, 2021
@marshallmain marshallmain added the auto-backport Deprecated - use backport:version if exact versions are needed label Mar 27, 2021
kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Mar 27, 2021
…e specific rule params (elastic#94857)

* Split rule executors into different files

* Pass type-specific rule SOs to rule executor functions

* Genericize function to narrow ruleSO type

* Remove undefined return type from getExceptions

* Remove unintentional change to SIGNALS_TEMPLATE_VERSION

* Remove extra validation now covered by schemas

* Remove extra validation from ML rule executor

* Fix types

* syncs schemas

* Revert "syncs schemas"

This reverts commit b1dd59e.

* Fix api test and move threshold executor test

* kinda adds eql test

* Refactor and fix unit tests

* fixes marshalls mistake

Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
@kibanamachine
Copy link
Contributor

💚 Backport successful

7.x / #95607

This backport PR will be merged automatically after passing CI.

@marshallmain marshallmain deleted the split-rule-executors-rebased branch March 27, 2021 03:04
kibanamachine added a commit that referenced this pull request Mar 27, 2021
…e specific rule params (#94857) (#95607)

* Split rule executors into different files

* Pass type-specific rule SOs to rule executor functions

* Genericize function to narrow ruleSO type

* Remove undefined return type from getExceptions

* Remove unintentional change to SIGNALS_TEMPLATE_VERSION

* Remove extra validation now covered by schemas

* Remove extra validation from ML rule executor

* Fix types

* syncs schemas

* Revert "syncs schemas"

This reverts commit b1dd59e.

* Fix api test and move threshold executor test

* kinda adds eql test

* Refactor and fix unit tests

* fixes marshalls mistake

Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Marshall Main <55718608+marshallmain@users.noreply.github.com>
Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed release_note:skip Skip the PR/issue when compiling release notes Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v7.13.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants