Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
20 changes: 20 additions & 0 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70783,10 +70783,28 @@ components:
- endpoint_host_isolation_exceptions
- endpoint_blocklists
type: string
Security_Detections_API_ExternalRuleCustomizedFields:
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
items:
type: object
properties:
field_name:
description: Name of a user-modified field in the rule object.
type: string
required:
- field_name
type: array
Security_Detections_API_ExternalRuleHasBaseVersion:
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`).
type: boolean
Security_Detections_API_ExternalRuleSource:
description: Type of rule source for externally sourced rules, i.e. rules that have an external source, such as the Elastic Prebuilt rules repo.
type: object
properties:
customized_fields:
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleCustomizedFields'
has_base_version:
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleHasBaseVersion'
is_customized:
$ref: '#/components/schemas/Security_Detections_API_IsExternalRuleCustomized'
type:
Expand All @@ -70796,6 +70814,8 @@ components:
required:
- type
- is_customized
- has_base_version
- customized_fields
Security_Detections_API_FindRulesSortField:
enum:
- created_at
Expand Down
20 changes: 20 additions & 0 deletions oas_docs/output/kibana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83976,10 +83976,28 @@ components:
- endpoint_host_isolation_exceptions
- endpoint_blocklists
type: string
Security_Detections_API_ExternalRuleCustomizedFields:
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
items:
type: object
properties:
field_name:
description: Name of a user-modified field in the rule object.
type: string
required:
- field_name
type: array
Security_Detections_API_ExternalRuleHasBaseVersion:
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`).
type: boolean
Security_Detections_API_ExternalRuleSource:
description: Type of rule source for externally sourced rules, i.e. rules that have an external source, such as the Elastic Prebuilt rules repo.
type: object
properties:
customized_fields:
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleCustomizedFields'
has_base_version:
$ref: '#/components/schemas/Security_Detections_API_ExternalRuleHasBaseVersion'
is_customized:
$ref: '#/components/schemas/Security_Detections_API_IsExternalRuleCustomized'
type:
Expand All @@ -83989,6 +84007,8 @@ components:
required:
- type
- is_customized
- has_base_version
- customized_fields
Security_Detections_API_FindRulesSortField:
enum:
- created_at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ export const IsRuleImmutable = z.boolean();
export type IsExternalRuleCustomized = z.infer<typeof IsExternalRuleCustomized>;
export const IsExternalRuleCustomized = z.boolean();

/**
* 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`).
*/
export type ExternalRuleHasBaseVersion = z.infer<typeof ExternalRuleHasBaseVersion>;
export const ExternalRuleHasBaseVersion = z.boolean();

/**
* An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
*/
export type ExternalRuleCustomizedFields = z.infer<typeof ExternalRuleCustomizedFields>;
export const ExternalRuleCustomizedFields = z.array(
z.object({
/**
* Name of a user-modified field in the rule object.
*/
field_name: z.string(),
})
);

/**
* Type of rule source for internally sourced rules, i.e. created within the Kibana apps.
*/
Expand All @@ -104,6 +123,8 @@ export type ExternalRuleSource = z.infer<typeof ExternalRuleSource>;
export const ExternalRuleSource = z.object({
type: z.literal('external'),
is_customized: IsExternalRuleCustomized,
has_base_version: ExternalRuleHasBaseVersion,
customized_fields: ExternalRuleCustomizedFields,
});

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ components:
type: boolean
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).

ExternalRuleHasBaseVersion:
type: boolean
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`).

ExternalRuleCustomizedFields:
type: array
description: An array of customized field names — that is, fields that the user has modified from their base value. Defaults to an empty array.
items:
type: object
properties:
field_name:
type: string
description: Name of a user-modified field in the rule object.
required:
- field_name

InternalRuleSource:
description: Type of rule source for internally sourced rules, i.e. created within the Kibana apps.
type: object
Expand All @@ -91,9 +107,15 @@ components:
- external
is_customized:
$ref: '#/components/schemas/IsExternalRuleCustomized'
has_base_version:
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
customized_fields:
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
required:
- type
- is_customized
- has_base_version
- customized_fields

RuleSource:
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ describe('rule_source', () => {
payload.rule_source = {
type: 'external',
is_customized: true,
customized_fields: [{ field_name: 'name' }],
has_base_version: true,
};

const result = RuleResponse.safeParse(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,8 @@ describe('RuleToImport', () => {
rule_source: {
type: 'external',
is_customized: true,
customized_fields: [{ field_name: 'name' }],
has_base_version: true,
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6315,12 +6315,36 @@ components:
- endpoint_host_isolation_exceptions
- endpoint_blocklists
type: string
ExternalRuleCustomizedFields:
description: >-
An array of customized field names — that is, fields that the user has
modified from their base value. Defaults to an empty array.
items:
type: object
properties:
field_name:
description: Name of a user-modified field in the rule object.
type: string
required:
- field_name
type: array
ExternalRuleHasBaseVersion:
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`).
type: boolean
ExternalRuleSource:
description: >-
Type of rule source for externally sourced rules, i.e. rules that have
an external source, such as the Elastic Prebuilt rules repo.
type: object
properties:
customized_fields:
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
has_base_version:
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
is_customized:
$ref: '#/components/schemas/IsExternalRuleCustomized'
type:
Expand All @@ -6330,6 +6354,8 @@ components:
required:
- type
- is_customized
- has_base_version
- customized_fields
FindRulesSortField:
enum:
- created_at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5645,12 +5645,36 @@ components:
- endpoint_host_isolation_exceptions
- endpoint_blocklists
type: string
ExternalRuleCustomizedFields:
description: >-
An array of customized field names — that is, fields that the user has
modified from their base value. Defaults to an empty array.
items:
type: object
properties:
field_name:
description: Name of a user-modified field in the rule object.
type: string
required:
- field_name
type: array
ExternalRuleHasBaseVersion:
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`).
type: boolean
ExternalRuleSource:
description: >-
Type of rule source for externally sourced rules, i.e. rules that have
an external source, such as the Elastic Prebuilt rules repo.
type: object
properties:
customized_fields:
$ref: '#/components/schemas/ExternalRuleCustomizedFields'
has_base_version:
$ref: '#/components/schemas/ExternalRuleHasBaseVersion'
is_customized:
$ref: '#/components/schemas/IsExternalRuleCustomized'
type:
Expand All @@ -5660,6 +5684,8 @@ components:
required:
- type
- is_customized
- has_base_version
- customized_fields
FindRulesSortField:
enum:
- created_at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
- [**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)
- [**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)
- [**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)
- [**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)
- [Calculating the Modified badge in the UI](#calculating-the-modified-badge-in-the-ui)
- [**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)
- [**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)
Expand Down Expand Up @@ -83,6 +84,8 @@ https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
- [Common terminology](./prebuilt_rules_common_info.md#common-terminology).
- **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.
- **`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.
- **`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.
- **`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.
- **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.
- **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).
- **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.
Expand Down Expand Up @@ -245,6 +248,8 @@ Given a prebuilt rule installed
When user customizes the prebuilt rule by changing the <field_name> field so it differs from the base version
Then the rule's `is_customized` value should be `true`
And ruleSource should be "external"
And the rule's `customized_fields` value should contain <field_name>
And the rule's `has_base_version` value should be true
```

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

```Gherkin
Given a prebuilt rule installed
And the prebuilt rule doesn't have a matching base version
And the prebuilt rule has a matching base version
When user opens the corresponding rule editing page
And saves the form unchanged
Then the rule's `is_customized` value should stay unchanged (non-customized rule stays non-customized)
And the rule's `customized_fields` value should be an empty array
And the rule's `has_base_version` value should be true
```

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

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

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

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

**Examples:**

`<field_name>` = all customizable rule fields

#### **Scenario: prebuilt rule's `is_customized` value is not affected by specific fields when base version is missing**

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

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

#### **Scenario: prebuilt rule's `customized_fields` resets to an empty array if rule was previously edited with base version present**

**Automation**: one integration test.

```Gherkin
Given a prebuilt rule installed
And the prebuilt rule has a populated `customized_fields` value
And the prebuilt rule doesn't have a matching base version
When user opens the corresponding rule editing page
And saves the form unchanged
Then the rule's `is_customized` value should remain true
And the rule's `customized_fields` value should be an empty array
And the rule's `has_base_version` value should be false
```

### Calculating the Modified badge in the UI

#### **Scenario: Modified badge should appear on the rule details page when prebuilt rule is customized**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ When the user imports these rules
Then the rules should be created
And the created rules should be correctly identified as prebuilt or custom
And the created rules' is_customized field should be correctly calculated
And the created rules' customized_fields field should be correctly calculated
And the created rules' parameters should match the import payload
```

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

Expand Down
Loading