Skip to content

Commit 25770cc

Browse files
kibanamachinedplumleeelasticmachinebanderror
authored
[9.1] [Security Solution] Adds customized_fields and has_base_version fields to rule_source object schema (#234793) (#237536)
# Backport This will backport the following commits from `main` to `9.1`: - [[Security Solution] Adds `customized_fields` and `has_base_version` fields to `rule_source` object schema (#234793)](#234793) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Davis Plumlee","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-10-03T19:52:53Z","message":"[Security Solution] Adds `customized_fields` and `has_base_version` fields to `rule_source` object schema (#234793)\n\n**Resolves: https://github.com/elastic/security-team/issues/12507**\n(internal)\n\n## Summary\n\nAdds two new fields to the existing `rule_source` object in our rule\nschema as described in https://github.com/elastic/kibana/pull/230856.\nAlso updates and adds test coverage for the new field logic.\n\nThe new fields are:\n\n- `customized_fields`: an array of objects containing rule field names\nthat have been modified from the base version of the prebuilt rule.\n- Defaults to empty array if prebuilt rule is not customized or if base\nversion did not exist during diff calculation.\n- `has_base_version`: a boolean field that specifies if the base version\nof a prebuilt rule was able to be fetched and used during the\ncustomization calculation.\n\nThis PR also adds related telemetry fields as described in\nhttps://github.com//pull/230856. This includes a\n`customizations` object field which contains a slimmed down version of\n`customized_fields` and has a `num_functional_fields` number field that\nis created in the telemetry task pipeline by comparing the customized\nfields array to a constant list of field names that we are defining as\n\"functional\". This source of truth list can be found in the\n`x-pack/solutions/security/plugins/security_solution/common/detection_engine/constants.ts`\nfile\n\n### Examples\n\n```json\n{\n \"rule_source\": {\n \"type\": \"external\",\n \"is_customized\": true,\n /* New fields */\n \"customized_fields\": [\n {\n \"field_name\": \"tags\",\n },\n {\n \"field_name\": \"query\",\n }\n ],\n \"has_base_version\": true\n }\n}\n```\n\n```json\n\"customizations\": {\n \"customized_fields\": [\"tags\", \"query\"],\n \"num_functional_fields\": 2,\n}\n```\n\n## How to test telemetry\n\nLink to internal staging with example data: ([internal\nstaging](https://analytics-staging.sde.elastic.dev/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:60000),time:(from:'2025-09-26T15:59:24.512Z',to:'2025-09-26T16:08:58.435Z'))&_a=(columns:!(),dataSource:(dataViewId:'4ca97040-d095-11ec-95a5-011050c1180f',type:dataView),filters:!(),interval:auto,query:(language:kuery,query:'customizations.num_functional_fields%20%3E%200'),sort:!(!('@timestamp',desc)),viewMode:documents)))\n\n1. Set the prebuilt rule task type to something shorter than `1hr` in\nthis file:\n`x-pack/solutions/security/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts`\n2. Add the following to `kibana.dev.yml`:\n```\ntelemetry.enabled: true\ntelemetry.optIn: true\n\n// (Optional for checking to see if its working)\nlogging:\n root:\n appenders: [default]\n level: warn\n loggers:\n - name: plugins.securitySolution\n level: debug\n - name: plugins.ruleRegistry\n - name: plugins.taskManager\n```\n3. Start up both Elasticsearch and kibana (Has to be done _after_\nupdating task interval as task objects are stored in ES)\n4. Install prebuilt rules\n5. Modify prebuilt rules with different field customizations and enable\nthose rules\n6. Generate alerts that match these rules (resolver script generator,\ndev tools, query modification, etc.)\n7. View the alerts getting sent to the internal staging telemetry\ncluster (https://analytics-staging.sde.elastic.dev) in the\n`detections_alert_telemetry_elastic*` index\n8. Use the new `customizations` field to filter out/in customized rule\nalerts\n\n## Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] [Rule customization\ntests](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/9317)\n\n---------\n\nCo-authored-by: Elastic Machine <[email protected]>\nCo-authored-by: Georgii Gorbachev <[email protected]>","sha":"aeb873a93ad8f8f29b4a616abe17c030621a3823","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","Feature:Prebuilt Detection Rules","backport:version","v9.2.0","v9.3.0","v9.1.6"],"title":"[Security Solution] Adds `customized_fields` and `has_base_version` fields to `rule_source` object schema","number":234793,"url":"https://github.com/elastic/kibana/pull/234793","mergeCommit":{"message":"[Security Solution] Adds `customized_fields` and `has_base_version` fields to `rule_source` object schema (#234793)\n\n**Resolves: https://github.com/elastic/security-team/issues/12507**\n(internal)\n\n## Summary\n\nAdds two new fields to the existing `rule_source` object in our rule\nschema as described in https://github.com/elastic/kibana/pull/230856.\nAlso updates and adds test coverage for the new field logic.\n\nThe new fields are:\n\n- `customized_fields`: an array of objects containing rule field names\nthat have been modified from the base version of the prebuilt rule.\n- Defaults to empty array if prebuilt rule is not customized or if base\nversion did not exist during diff calculation.\n- `has_base_version`: a boolean field that specifies if the base version\nof a prebuilt rule was able to be fetched and used during the\ncustomization calculation.\n\nThis PR also adds related telemetry fields as described in\nhttps://github.com//pull/230856. This includes a\n`customizations` object field which contains a slimmed down version of\n`customized_fields` and has a `num_functional_fields` number field that\nis created in the telemetry task pipeline by comparing the customized\nfields array to a constant list of field names that we are defining as\n\"functional\". This source of truth list can be found in the\n`x-pack/solutions/security/plugins/security_solution/common/detection_engine/constants.ts`\nfile\n\n### Examples\n\n```json\n{\n \"rule_source\": {\n \"type\": \"external\",\n \"is_customized\": true,\n /* New fields */\n \"customized_fields\": [\n {\n \"field_name\": \"tags\",\n },\n {\n \"field_name\": \"query\",\n }\n ],\n \"has_base_version\": true\n }\n}\n```\n\n```json\n\"customizations\": {\n \"customized_fields\": [\"tags\", \"query\"],\n \"num_functional_fields\": 2,\n}\n```\n\n## How to test telemetry\n\nLink to internal staging with example data: ([internal\nstaging](https://analytics-staging.sde.elastic.dev/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:60000),time:(from:'2025-09-26T15:59:24.512Z',to:'2025-09-26T16:08:58.435Z'))&_a=(columns:!(),dataSource:(dataViewId:'4ca97040-d095-11ec-95a5-011050c1180f',type:dataView),filters:!(),interval:auto,query:(language:kuery,query:'customizations.num_functional_fields%20%3E%200'),sort:!(!('@timestamp',desc)),viewMode:documents)))\n\n1. Set the prebuilt rule task type to something shorter than `1hr` in\nthis file:\n`x-pack/solutions/security/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts`\n2. Add the following to `kibana.dev.yml`:\n```\ntelemetry.enabled: true\ntelemetry.optIn: true\n\n// (Optional for checking to see if its working)\nlogging:\n root:\n appenders: [default]\n level: warn\n loggers:\n - name: plugins.securitySolution\n level: debug\n - name: plugins.ruleRegistry\n - name: plugins.taskManager\n```\n3. Start up both Elasticsearch and kibana (Has to be done _after_\nupdating task interval as task objects are stored in ES)\n4. Install prebuilt rules\n5. Modify prebuilt rules with different field customizations and enable\nthose rules\n6. Generate alerts that match these rules (resolver script generator,\ndev tools, query modification, etc.)\n7. View the alerts getting sent to the internal staging telemetry\ncluster (https://analytics-staging.sde.elastic.dev) in the\n`detections_alert_telemetry_elastic*` index\n8. Use the new `customizations` field to filter out/in customized rule\nalerts\n\n## Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] [Rule customization\ntests](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/9317)\n\n---------\n\nCo-authored-by: Elastic Machine <[email protected]>\nCo-authored-by: Georgii Gorbachev <[email protected]>","sha":"aeb873a93ad8f8f29b4a616abe17c030621a3823"}},"sourceBranch":"main","suggestedTargetBranches":["9.2","9.1"],"targetPullRequestStates":[{"branch":"9.2","label":"v9.2.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/234793","number":234793,"mergeCommit":{"message":"[Security Solution] Adds `customized_fields` and `has_base_version` fields to `rule_source` object schema (#234793)\n\n**Resolves: https://github.com/elastic/security-team/issues/12507**\n(internal)\n\n## Summary\n\nAdds two new fields to the existing `rule_source` object in our rule\nschema as described in https://github.com/elastic/kibana/pull/230856.\nAlso updates and adds test coverage for the new field logic.\n\nThe new fields are:\n\n- `customized_fields`: an array of objects containing rule field names\nthat have been modified from the base version of the prebuilt rule.\n- Defaults to empty array if prebuilt rule is not customized or if base\nversion did not exist during diff calculation.\n- `has_base_version`: a boolean field that specifies if the base version\nof a prebuilt rule was able to be fetched and used during the\ncustomization calculation.\n\nThis PR also adds related telemetry fields as described in\nhttps://github.com//pull/230856. This includes a\n`customizations` object field which contains a slimmed down version of\n`customized_fields` and has a `num_functional_fields` number field that\nis created in the telemetry task pipeline by comparing the customized\nfields array to a constant list of field names that we are defining as\n\"functional\". This source of truth list can be found in the\n`x-pack/solutions/security/plugins/security_solution/common/detection_engine/constants.ts`\nfile\n\n### Examples\n\n```json\n{\n \"rule_source\": {\n \"type\": \"external\",\n \"is_customized\": true,\n /* New fields */\n \"customized_fields\": [\n {\n \"field_name\": \"tags\",\n },\n {\n \"field_name\": \"query\",\n }\n ],\n \"has_base_version\": true\n }\n}\n```\n\n```json\n\"customizations\": {\n \"customized_fields\": [\"tags\", \"query\"],\n \"num_functional_fields\": 2,\n}\n```\n\n## How to test telemetry\n\nLink to internal staging with example data: ([internal\nstaging](https://analytics-staging.sde.elastic.dev/app/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:60000),time:(from:'2025-09-26T15:59:24.512Z',to:'2025-09-26T16:08:58.435Z'))&_a=(columns:!(),dataSource:(dataViewId:'4ca97040-d095-11ec-95a5-011050c1180f',type:dataView),filters:!(),interval:auto,query:(language:kuery,query:'customizations.num_functional_fields%20%3E%200'),sort:!(!('@timestamp',desc)),viewMode:documents)))\n\n1. Set the prebuilt rule task type to something shorter than `1hr` in\nthis file:\n`x-pack/solutions/security/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts`\n2. Add the following to `kibana.dev.yml`:\n```\ntelemetry.enabled: true\ntelemetry.optIn: true\n\n// (Optional for checking to see if its working)\nlogging:\n root:\n appenders: [default]\n level: warn\n loggers:\n - name: plugins.securitySolution\n level: debug\n - name: plugins.ruleRegistry\n - name: plugins.taskManager\n```\n3. Start up both Elasticsearch and kibana (Has to be done _after_\nupdating task interval as task objects are stored in ES)\n4. Install prebuilt rules\n5. Modify prebuilt rules with different field customizations and enable\nthose rules\n6. Generate alerts that match these rules (resolver script generator,\ndev tools, query modification, etc.)\n7. View the alerts getting sent to the internal staging telemetry\ncluster (https://analytics-staging.sde.elastic.dev) in the\n`detections_alert_telemetry_elastic*` index\n8. Use the new `customizations` field to filter out/in customized rule\nalerts\n\n## Checklist\n\nCheck the PR satisfies following conditions. \n\nReviewers should verify this PR satisfies this list as well.\n\n- [x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas added for features that require explanation or tutorials\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] [Flaky Test\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\nused on any tests changed\n- [x] [Rule customization\ntests](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/9317)\n\n---------\n\nCo-authored-by: Elastic Machine <[email protected]>\nCo-authored-by: Georgii Gorbachev <[email protected]>","sha":"aeb873a93ad8f8f29b4a616abe17c030621a3823"}},{"branch":"9.1","label":"v9.1.6","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Davis Plumlee <[email protected]> Co-authored-by: Elastic Machine <[email protected]> Co-authored-by: Georgii Gorbachev <[email protected]>
1 parent 2ddc181 commit 25770cc

File tree

55 files changed

+1386
-303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1386
-303
lines changed

oas_docs/output/kibana.serverless.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60930,10 +60930,28 @@ components:
6093060930
- endpoint_host_isolation_exceptions
6093160931
- endpoint_blocklists
6093260932
type: string
60933+
Security_Detections_API_ExternalRuleCustomizedFields:
60934+
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
60935+
items:
60936+
type: object
60937+
properties:
60938+
field_name:
60939+
description: Name of a user-modified field in the rule object.
60940+
type: string
60941+
required:
60942+
- field_name
60943+
type: array
60944+
Security_Detections_API_ExternalRuleHasBaseVersion:
60945+
description: Determines whether an external/prebuilt rule has its original, unmodified version present when the calculation of its customization status is performed (`rule_source.is_customized` and `rule_source.customized_fields`).
60946+
type: boolean
6093360947
Security_Detections_API_ExternalRuleSource:
6093460948
description: Type of rule source for externally sourced rules, i.e. rules that have an external source, such as the Elastic Prebuilt rules repo.
6093560949
type: object
6093660950
properties:
60951+
customized_fields:
60952+
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleCustomizedFields'
60953+
has_base_version:
60954+
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleHasBaseVersion'
6093760955
is_customized:
6093860956
$ref: '#/components/schemas/Security_Detections_API_IsExternalRuleCustomized'
6093960957
type:
@@ -60943,6 +60961,8 @@ components:
6094360961
required:
6094460962
- type
6094560963
- is_customized
60964+
- has_base_version
60965+
- customized_fields
6094660966
Security_Detections_API_FindRulesSortField:
6094760967
enum:
6094860968
- created_at

oas_docs/output/kibana.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70375,10 +70375,28 @@ components:
7037570375
- endpoint_host_isolation_exceptions
7037670376
- endpoint_blocklists
7037770377
type: string
70378+
Security_Detections_API_ExternalRuleCustomizedFields:
70379+
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
70380+
items:
70381+
type: object
70382+
properties:
70383+
field_name:
70384+
description: Name of a user-modified field in the rule object.
70385+
type: string
70386+
required:
70387+
- field_name
70388+
type: array
70389+
Security_Detections_API_ExternalRuleHasBaseVersion:
70390+
description: Determines whether an external/prebuilt rule has its original, unmodified version present when the calculation of its customization status is performed (`rule_source.is_customized` and `rule_source.customized_fields`).
70391+
type: boolean
7037870392
Security_Detections_API_ExternalRuleSource:
7037970393
description: Type of rule source for externally sourced rules, i.e. rules that have an external source, such as the Elastic Prebuilt rules repo.
7038070394
type: object
7038170395
properties:
70396+
customized_fields:
70397+
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleCustomizedFields'
70398+
has_base_version:
70399+
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleHasBaseVersion'
7038270400
is_customized:
7038370401
$ref: '#/components/schemas/Security_Detections_API_IsExternalRuleCustomized'
7038470402
type:
@@ -70388,6 +70406,8 @@ components:
7038870406
required:
7038970407
- type
7039070408
- is_customized
70409+
- has_base_version
70410+
- customized_fields
7039170411
Security_Detections_API_FindRulesSortField:
7039270412
enum:
7039370413
- created_at

x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,25 @@ export const IsRuleImmutable = z.boolean();
8989
export type IsExternalRuleCustomized = z.infer<typeof IsExternalRuleCustomized>;
9090
export const IsExternalRuleCustomized = z.boolean();
9191

92+
/**
93+
* Determines whether an external/prebuilt rule has its original, unmodified version present when the calculation of its customization status is performed (`rule_source.is_customized` and `rule_source.customized_fields`).
94+
*/
95+
export type ExternalRuleHasBaseVersion = z.infer<typeof ExternalRuleHasBaseVersion>;
96+
export const ExternalRuleHasBaseVersion = z.boolean();
97+
98+
/**
99+
* An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
100+
*/
101+
export type ExternalRuleCustomizedFields = z.infer<typeof ExternalRuleCustomizedFields>;
102+
export const ExternalRuleCustomizedFields = z.array(
103+
z.object({
104+
/**
105+
* Name of a user-modified field in the rule object.
106+
*/
107+
field_name: z.string(),
108+
})
109+
);
110+
92111
/**
93112
* Type of rule source for internally sourced rules, i.e. created within the Kibana apps.
94113
*/
@@ -104,6 +123,8 @@ export type ExternalRuleSource = z.infer<typeof ExternalRuleSource>;
104123
export const ExternalRuleSource = z.object({
105124
type: z.literal('external'),
106125
is_customized: IsExternalRuleCustomized,
126+
has_base_version: ExternalRuleHasBaseVersion,
127+
customized_fields: ExternalRuleCustomizedFields,
107128
});
108129

109130
/**

x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.schema.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ components:
7070
type: boolean
7171
description: Determines whether an external/prebuilt rule has been customized by the user (i.e. any of its fields have been modified and diverged from the base value).
7272

73+
ExternalRuleHasBaseVersion:
74+
type: boolean
75+
description: Determines whether an external/prebuilt rule has its original, unmodified version present when the calculation of its customization status is performed (`rule_source.is_customized` and `rule_source.customized_fields`).
76+
77+
ExternalRuleCustomizedFields:
78+
type: array
79+
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
80+
items:
81+
type: object
82+
properties:
83+
field_name:
84+
type: string
85+
description: Name of a user-modified field in the rule object.
86+
required:
87+
- field_name
88+
7389
InternalRuleSource:
7490
description: Type of rule source for internally sourced rules, i.e. created within the Kibana apps.
7591
type: object
@@ -91,9 +107,15 @@ components:
91107
- external
92108
is_customized:
93109
$ref: '#/components/schemas/IsExternalRuleCustomized'
110+
has_base_version:
111+
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
112+
customized_fields:
113+
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
94114
required:
95115
- type
96116
- is_customized
117+
- has_base_version
118+
- customized_fields
97119

98120
RuleSource:
99121
description: Discriminated union that determines whether the rule is internally sourced (created within the Kibana app) or has an external source, such as the Elastic Prebuilt rules repo.

x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_schema/rule_response_schema.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ describe('rule_source', () => {
259259
payload.rule_source = {
260260
type: 'external',
261261
is_customized: true,
262+
customized_fields: [{ field_name: 'name' }],
263+
has_base_version: true,
262264
};
263265

264266
const result = RuleResponse.safeParse(payload);

x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/rule_management/import_rules/rule_to_import.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,8 @@ describe('RuleToImport', () => {
10561056
rule_source: {
10571057
type: 'external',
10581058
is_customized: true,
1059+
customized_fields: [{ field_name: 'name' }],
1060+
has_base_version: true,
10591061
},
10601062
});
10611063

x-pack/solutions/security/plugins/security_solution/docs/openapi/ess/security_solution_detections_api_2023_10_31.bundled.schema.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6272,12 +6272,36 @@ components:
62726272
- endpoint_host_isolation_exceptions
62736273
- endpoint_blocklists
62746274
type: string
6275+
ExternalRuleCustomizedFields:
6276+
description: >-
6277+
An array of customized field names — that is, fields that the user has
6278+
modified from their base value. Defaults to an empty array.
6279+
items:
6280+
type: object
6281+
properties:
6282+
field_name:
6283+
description: Name of a user-modified field in the rule object.
6284+
type: string
6285+
required:
6286+
- field_name
6287+
type: array
6288+
ExternalRuleHasBaseVersion:
6289+
description: >-
6290+
Determines whether an external/prebuilt rule has its original,
6291+
unmodified version present when the calculation of its customization
6292+
status is performed (`rule_source.is_customized` and
6293+
`rule_source.customized_fields`).
6294+
type: boolean
62756295
ExternalRuleSource:
62766296
description: >-
62776297
Type of rule source for externally sourced rules, i.e. rules that have
62786298
an external source, such as the Elastic Prebuilt rules repo.
62796299
type: object
62806300
properties:
6301+
customized_fields:
6302+
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
6303+
has_base_version:
6304+
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
62816305
is_customized:
62826306
$ref: '#/components/schemas/IsExternalRuleCustomized'
62836307
type:
@@ -6287,6 +6311,8 @@ components:
62876311
required:
62886312
- type
62896313
- is_customized
6314+
- has_base_version
6315+
- customized_fields
62906316
FindRulesSortField:
62916317
enum:
62926318
- created_at

x-pack/solutions/security/plugins/security_solution/docs/openapi/serverless/security_solution_detections_api_2023_10_31.bundled.schema.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5602,12 +5602,36 @@ components:
56025602
- endpoint_host_isolation_exceptions
56035603
- endpoint_blocklists
56045604
type: string
5605+
ExternalRuleCustomizedFields:
5606+
description: >-
5607+
An array of customized field names — that is, fields that the user has
5608+
modified from their base value. Defaults to an empty array.
5609+
items:
5610+
type: object
5611+
properties:
5612+
field_name:
5613+
description: Name of a user-modified field in the rule object.
5614+
type: string
5615+
required:
5616+
- field_name
5617+
type: array
5618+
ExternalRuleHasBaseVersion:
5619+
description: >-
5620+
Determines whether an external/prebuilt rule has its original,
5621+
unmodified version present when the calculation of its customization
5622+
status is performed (`rule_source.is_customized` and
5623+
`rule_source.customized_fields`).
5624+
type: boolean
56055625
ExternalRuleSource:
56065626
description: >-
56075627
Type of rule source for externally sourced rules, i.e. rules that have
56085628
an external source, such as the Elastic Prebuilt rules repo.
56095629
type: object
56105630
properties:
5631+
customized_fields:
5632+
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
5633+
has_base_version:
5634+
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
56115635
is_customized:
56125636
$ref: '#/components/schemas/IsExternalRuleCustomized'
56135637
type:
@@ -5617,6 +5641,8 @@ components:
56175641
required:
56185642
- type
56195643
- is_customized
5644+
- has_base_version
5645+
- customized_fields
56205646
FindRulesSortField:
56215647
enum:
56225648
- created_at

x-pack/solutions/security/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/prebuilt_rule_customization.md

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
4848
- [**Scenario: prebuilt rule's `is_customized` is set to true after it is customized when base version is missing**](#scenario-prebuilt-rules-is_customized-is-set-to-true-after-it-is-customized-when-base-version-is-missing)
4949
- [**Scenario: prebuilt rule's `is_customized` stays unchanged after it is saved unchanged when base version is missing**](#scenario-prebuilt-rules-is_customized-stays-unchanged-after-it-is-saved-unchanged-when-base-version-is-missing)
5050
- [**Scenario: prebuilt rule's `is_customized` value is not affected by specific fields when base version is missing**](#scenario-prebuilt-rules-is_customized-value-is-not-affected-by-specific-fields-when-base-version-is-missing)
51+
- [**Scenario: prebuilt rule's `customized_fields` resets to an empty array if rule was previously edited with base version present**](#scenario-prebuilt-rules-customized_fields-resets-to-an-empty-array-if-rule-was-previously-edited-with-base-version-present)
5152
- [Calculating the Modified badge in the UI](#calculating-the-modified-badge-in-the-ui)
5253
- [**Scenario: Modified badge should appear on the rule details page when prebuilt rule is customized**](#scenario-modified-badge-should-appear-on-the-rule-details-page-when-prebuilt-rule-is-customized)
5354
- [**Scenario: Modified badge should not appear on the rule details page when prebuilt rule isn't customized**](#scenario-modified-badge-should-not-appear-on-the-rule-details-page-when-prebuilt-rule-isnt-customized)
@@ -83,6 +84,8 @@ https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
8384
- [Common terminology](./prebuilt_rules_common_info.md#common-terminology).
8485
- **Rule source**, or **`ruleSource`**: a rule field that defines the rule's origin. Can be `internal` or `external`. Currently, custom rules have `internal` rule source and prebuilt rules have `external` rule source.
8586
- **`is_customized`**: a field within `ruleSource` that exists when rule source is set to `external`. It is a boolean value based on if the rule has been changed from its base version.
87+
- **`customized_fields`**: a field within `ruleSource` that exists when rule source is set to `external`. It is an array of objects containing field names that have been changed from their base version counterparts.
88+
- **`has_base_version`**: a field within `ruleSource` that exists when rule source is set to `external`. It is a boolean value based on if the rule had a matching base version during rule source calculation.
8689
- **non-semantic change**: a change to a rule field that is functionally different. We normalize certain fields so for a time-related field such as `from`, `1m` vs `60s` are treated as the same value. We also trim leading and trailing whitespace for query fields.
8790
- **rule customization**: a change to a customizable field of a prebuilt rule. Full list of customizable rule fields can be found in [Common information about prebuilt rules](./prebuilt_rules_common_info.md#customizable-rule-fields).
8891
- **insufficient license**: a license or a product tier that doesn't allow rule customization. In Serverless environments customization is only allowed on Security Essentials product tier. In non-Serverless environments customization is only allowed on Trial and Enterprise licenses.
@@ -245,6 +248,8 @@ Given a prebuilt rule installed
245248
When user customizes the prebuilt rule by changing the <field_name> field so it differs from the base version
246249
Then the rule's `is_customized` value should be `true`
247250
And ruleSource should be "external"
251+
And the rule's `customized_fields` value should contain <field_name>
252+
And the rule's `has_base_version` value should be true
248253
```
249254

250255
#### **Scenario: prebuilt rule's `is_customized` stays unchanged after it is saved unchanged**
@@ -253,10 +258,12 @@ And ruleSource should be "external"
253258

254259
```Gherkin
255260
Given a prebuilt rule installed
256-
And the prebuilt rule doesn't have a matching base version
261+
And the prebuilt rule has a matching base version
257262
When user opens the corresponding rule editing page
258263
And saves the form unchanged
259264
Then the rule's `is_customized` value should stay unchanged (non-customized rule stays non-customized)
265+
And the rule's `customized_fields` value should be an empty array
266+
And the rule's `has_base_version` value should be true
260267
```
261268

262269
**Examples:**
@@ -272,6 +279,8 @@ Given a prebuilt rule installed
272279
And it is non-customized
273280
When a user changes the <field_name> field so it differs from the base version
274281
Then the rule's `is_customized` value should remain `false`
282+
And the rule's `customized_fields` value should be an empty array
283+
And the rule's `has_base_version` value should be true
275284
```
276285

277286
**Examples:**
@@ -308,6 +317,8 @@ Given a prebuilt rule installed
308317
And it is customized
309318
When a user changes the rule fields to match the base version
310319
Then the rule's `is_customized` value should be false
320+
And the rule's `customized_fields` value should be an empty array
321+
And the rule's `has_base_version` value should be true
311322
```
312323

313324
### Detecting rule customizations when base version is missing
@@ -324,6 +335,8 @@ And the prebuilt rule doesn't have a matching base version
324335
When user customizes the prebuilt rule by changing the <field_name> field so it differs from the base version
325336
Then the rule's `is_customized` value should be `true`
326337
And ruleSource should be "external"
338+
And the rule's `customized_fields` value should be an empty array
339+
And the rule's `has_base_version` value should be false
327340
```
328341

329342
**Examples:**
@@ -340,12 +353,10 @@ And the prebuilt rule doesn't have a matching base version
340353
When user opens the corresponding rule editing page
341354
And saves the form unchanged
342355
Then the rule's `is_customized` value should stay unchanged (non-customized rule stays non-customized)
356+
And the rule's `customized_fields` value should be an empty array
357+
And the rule's `has_base_version` value should be false
343358
```
344359

345-
**Examples:**
346-
347-
`<field_name>` = all customizable rule fields
348-
349360
#### **Scenario: prebuilt rule's `is_customized` value is not affected by specific fields when base version is missing**
350361

351362
**Automation**: one integration test per field.
@@ -356,6 +367,8 @@ And the prebuilt rule doesn't have a matching base version
356367
And it is non-customized
357368
When a user changes the <field_name> field so it differs from the base version
358369
Then the rule's `is_customized` value should remain `false`
370+
And the rule's `customized_fields` value should be an empty array
371+
And the rule's `has_base_version` value should be false
359372
```
360373

361374
**Examples:**
@@ -367,6 +380,21 @@ Then the rule's `is_customized` value should remain `false`
367380
| revision |
368381
| meta |
369382

383+
#### **Scenario: prebuilt rule's `customized_fields` resets to an empty array if rule was previously edited with base version present**
384+
385+
**Automation**: one integration test.
386+
387+
```Gherkin
388+
Given a prebuilt rule installed
389+
And the prebuilt rule has a populated `customized_fields` value
390+
And the prebuilt rule doesn't have a matching base version
391+
When user opens the corresponding rule editing page
392+
And saves the form unchanged
393+
Then the rule's `is_customized` value should remain true
394+
And the rule's `customized_fields` value should be an empty array
395+
And the rule's `has_base_version` value should be false
396+
```
397+
370398
### Calculating the Modified badge in the UI
371399

372400
#### **Scenario: Modified badge should appear on the rule details page when prebuilt rule is customized**

x-pack/solutions/security/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/prebuilt_rule_import.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ When the user imports these rules
274274
Then the rules should be created
275275
And the created rules should be correctly identified as prebuilt or custom
276276
And the created rules' is_customized field should be correctly calculated
277+
And the created rules' customized_fields field should be correctly calculated
277278
And the created rules' parameters should match the import payload
278279
```
279280

@@ -292,6 +293,7 @@ When the user imports these rules
292293
Then the rules should be updated
293294
And the updated rules should be correctly identified as prebuilt or custom
294295
And the updated rules' is_customized field should be correctly calculated
296+
And the created rules' customized_fields field should be correctly calculated
295297
And the updated rules' parameters should match the import payload
296298
```
297299

0 commit comments

Comments
 (0)