Skip to content

Commit

Permalink
[Security Solution] Make rule schema forward-compatible (#170861)
Browse files Browse the repository at this point in the history
**Resolves: elastic/security-team#6888

## Summary

The transition from io-ts to Zod has led to a new approach in request
validation where extra fields are allowed. Now, any unknown fields in
data structures sent to our API are stripped away silently, without
triggering validation errors. This change ensures the rule schema is
forward-compatible, facilitating scenarios such as:

- Users exporting a rule with a new field from the latest Kibana version
and importing it into the previous Kibana without issues.
- The TRADE team can avoid backporting rules with new fields for
out-of-band updates, as these fields will be ignored during the rule
installation process.

Forward-compatible rule schemas are supported by:
- All Rule CRUD operations
- All Bulk Rule CRUD operations
- Rule Import/Export functionality

### How to test this PR

1. In Kibana UI. Export a rule, append extra fields at any level, and
re-import it. All additional fields should be omitted in the final rule.
2. On the API level. Include extra fields in any CRUD rule request. Then
retrieve the rule, all extra fields should be missing.

### Note

Not all rule fields are validated; some fields are defined as
`Record<string, unknown>` like `RuleActionParams` or
`RuleActionAlertsFilter`. Any extra fields added to these structures
will be preserved.
  • Loading branch information
xcrzx authored Nov 13, 2023
1 parent b71a52c commit 69c9aee
Show file tree
Hide file tree
Showing 14 changed files with 478 additions and 713 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/* eslint-disable @typescript-eslint/naming-convention */

import * as t from 'io-ts';
import { IsoDateString, PositiveInteger } from '@kbn/securitysolution-io-ts-types';
import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';

export const file_name = t.string;
export type FileName = t.TypeOf<typeof file_name>;
Expand Down Expand Up @@ -42,13 +42,6 @@ export const signal_status_query = t.object;
export const alert_tag_ids = t.array(t.string);
export type AlertTagIds = t.TypeOf<typeof alert_tag_ids>;

export const created_at = IsoDateString;
export const updated_at = IsoDateString;
export const created_by = t.string;
export const updated_by = t.string;

export const revision = PositiveInteger;

export const indexRecord = t.record(
t.string,
t.type({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const getImportRulesSchemaMock = (ruleId = 'rule-1'): RuleToImport => ({
risk_score: 55,
language: 'kuery',
rule_id: ruleId,
immutable: false,
});

export const getImportRulesWithIdSchemaMock = (ruleId = 'rule-1'): RuleToImport => ({
Expand All @@ -28,6 +29,7 @@ export const getImportRulesWithIdSchemaMock = (ruleId = 'rule-1'): RuleToImport
risk_score: 55,
language: 'kuery',
rule_id: ruleId,
immutable: false,
});

/**
Expand Down Expand Up @@ -79,6 +81,7 @@ export const getImportThreatMatchRulesSchemaMock = (ruleId = 'rule-1'): RuleToIm
},
},
],
immutable: false,
});

export const webHookConnector = {
Expand Down
Loading

0 comments on commit 69c9aee

Please sign in to comment.