-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Osquery] Add Detection action #133279
[Osquery] Add Detection action #133279
Conversation
# Conflicts: # x-pack/plugins/osquery/public/live_queries/form/index.tsx
@elasticmachine merge upstream |
@elasticmachine merge upstream |
…squery-detection-action
This reverts commit 12370cf.
} | ||
|
||
interface ScheduleNotificationActions { | ||
signals: unknown[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: any reason why not call this alerts
instead of the deprecated signals
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, good question. For the purpose of this component, I think we could call it alerts
, but there are some other places where these are signals, so I didn't want to stand out ;p
eg. x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts
import styled from 'styled-components'; | ||
import { EuiAccordion } from '@elastic/eui'; | ||
|
||
export const StyledEuiAccordion = styled(EuiAccordion)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look like this StyledEuiAccordion
was extracted out but wasn't used for replacing any of its current uses?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, there was quite a big refactor in the meanwhile, I'll remove this file 👍
@tomsonpl Yes! Now when you did that, and response actions are decoupled from regular actions and their frequency (
Tested all of that locally. Works great 👍 |
By foreign key, I mean a reference to any other Kibana entity (for example, a saved object) by id.
Ok, so I guess these are needed. Do you actually need the The problem is that you mixed references with copies of data here, and ideally it should be either full copy or only a reference. If that makes sense. You can chat with @marshallmain on that because we had a similar issue with Saved Query rules and it was fixed in #140064 by storing either a reference to a saved query, or its copy at the time of rule creation/editing. |
Oh, then yes, these are foreign keys, but we do not make use of them yet, there is nothing pushed to For now, as you mentioned, we keep both a 'copy' and a reference Id. However, it's not a real copy, because we just store a small piece of data, just query + ecs_mapping, mostly. I think we could get rid of reference id (packId, savedQueryId) - but that would trigger some UI changes in the form that I would like to avoid at this late stage. Do you think it would be problematic to keep both for 8.5, and then move to references at 8.6 ? |
It's hard for me to tell for sure if it would be acceptable to skip having 'references' in 8.5 and update this in 8.6. I don't think that writing SO references will help to fix that by itself. The two ref integrity issues I mentioned above require support for exporting and importing the referenced objects, in this case osquery packs and single queries, in the Security rule export and import endpoints. This is not something I'm familiar with - @yctercero could you please comment on that? UPD: FWIW we don't export and import connectors with rules, and this is what happens when you import a rule that references non-existent connectors: So to me the current implementation doesn't seem too risky, but maybe I'm missing something. |
🙏 Checked the changes -- looks great! Thank you.
Yes, please do it similar to how it was done for
That LGTM, thank you 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think most of my comments have been addressed by now, and it LGTM.
I don't feel that the current implementation imposes any significant risk for the future and I'm ok with merging it as is and then improving in the next cycle. I'd still consult with @marshallmain and @yctercero - maybe they have any other thoughts on the data model, referential integrity, or export/import.
Would be still good to know answers to some of the general questions I posted above.
Thank you @tomsonpl for all your efforts, quick responses and fixes!
@@ -101,6 +101,8 @@ export const data_view_id = t.string; | |||
|
|||
export const dataViewIdOrUndefined = t.union([data_view_id, t.undefined]); | |||
|
|||
export const action_action_type_id = NonEmptyString; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this one is an unused leftover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detection engine changes LGTM. Now that the response actions are decoupled from the throttle
, I don't see this feature interfering with existing detection engine features. The implementation in the rule executors also looks low risk to existing detection engine users - if a user has no response actions on the rule, there is no change to rule behavior at all, and if response actions are defined the only additional tasks are a couple of bulk
requests that don't block the rule from completing. 👍
There are some more updates I'd like to see in the OsqueryParams
schema to keep a consistent convention of using snake case in the HTTP API and camelCase internally. Essentially we should follow the same convention we have so far with the rule schemas and have separate versions of OsqueryParams
for the HTTP API and the internal rule representation with a conversion function between them.
@elasticmachine merge upstream |
const GhostFormField = () => <></>; | ||
|
||
// eslint-disable-next-line react/display-name | ||
export const ResponseActionsList = React.memo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to get rid of this eslint disable, you can just declare the const here, set ResponseActionsList.displayName = 'ResponseActionsList'
below the component definition, and then export ResponseActionsList
i know it might seem tedious but display name can help debugging sometimes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
): ActionsStepRule => { | ||
const { enabled, throttle, meta, actions = [] } = rule; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
const { enabled, throttle, meta, actions = [], response_actions = [] } = rule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const { enabled, throttle, meta, actions = [], response_actions = [] } = rule; | |
const { enabled, throttle, meta, actions = [], response_actions: responseActions = [] } = rule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
} | ||
|
||
const { OsqueryResults } = osquery; | ||
const parameters = rawEventData.fields['kibana.alert.rule.parameters']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be easier to work with everything in rawEventData if you used the helper expandDottedObject https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/public/common/utils/alerts.ts#L82
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll be creating a small PR later today with a small fix, do you mind If I attach this change there too? :) Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And yessss, this is much easier, thank you :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
few small nitpicks but overall this feature is awesome and threat hunting changes lgtm!
setValue('packId', [packId]); | ||
} | ||
} | ||
/* eslint-disable-next-line react-hooks/exhaustive-deps */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get why you disable this to only run once, but this line is terrifying and often causes bugs, there are a few other ways to accomplish the run once by refactoring the hook to be something like
const mungeData = useCallback(() => {
if (defaultParams && defaultParams.id) {
const { packId, ecs_mapping: ecsMapping, ...restParams } = defaultParams;
map(restParams, (value, key: keyof OsqueryResponseActionsParamsFormFields) => {
if (!isEmpty(value)) {
setValue(key, value);
}
});
if (ecsMapping) {
const converted = convertECSMappingToFormValue(ecsMapping);
setValue('ecs_mapping', converted);
}
if (!isEmpty(packId)) {
setValue('packId', [packId]);
}
}
}, [defaultParams, setValue]);
useEffect(() => {
mungeData();
}, [mungeData]);
the callback only runs when the reference in the useEffect changes, which won't happen just from render cycles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed it into useEffectOnce from react-use/lib/useEffectOnce , hope this is better :)
# Conflicts: # x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts # x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/saved_query/create_saved_query_alert_type.ts # x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts
…squery-detection-action
💚 Build SucceededMetrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
Unknown metric groupsAPI count
async chunk count
ESLint disabled line counts
References to deprecated APIs
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: cc @tomsonpl |
Thank you everyone that helped me get this PR ready, your review and feedback was enormous :elasticheart: |
Hi, this PR aims to resolve this issue https://github.com/elastic/security-team/issues/1103.
After a meeting happening sometime in between June/July where it was suggested that we shouldn't make Osquery a connector, but instead keep our data in the rule itself. Therefore
responseActions
in the rule, specifically in the rule params, more specifically inQueryRuleParams
.This PR will contain two major pieces:
TODO:
https://watch.screencastify.com/v/gWN8anJcbYamvT1hkipl