Skip to content

Commit 35474fb

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Add sequence detection to security monitoring rules (#2666)
Co-authored-by: ci.datadog-api-spec <[email protected]>
1 parent ee9ad7c commit 35474fb

15 files changed

+673
-2
lines changed

.generator/schemas/v2/openapi.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20470,6 +20470,8 @@ components:
2047020470
$ref: '#/components/schemas/SecurityMonitoringRuleMaxSignalDuration'
2047120471
newValueOptions:
2047220472
$ref: '#/components/schemas/SecurityMonitoringRuleNewValueOptions'
20473+
sequenceDetectionOptions:
20474+
$ref: '#/components/schemas/SecurityMonitoringRuleSequenceDetectionOptions'
2047320475
thirdPartyRuleOptions:
2047420476
$ref: '#/components/schemas/SecurityMonitoringRuleThirdPartyOptions'
2047520477
type: object
@@ -40786,6 +40788,7 @@ components:
4078640788
- hardcoded
4078740789
- third_party
4078840790
- anomaly_threshold
40791+
- sequence_detection
4078940792
type: string
4079040793
x-enum-varnames:
4079140794
- THRESHOLD
@@ -40795,6 +40798,7 @@ components:
4079540798
- HARDCODED
4079640799
- THIRD_PARTY
4079740800
- ANOMALY_THRESHOLD
40801+
- SEQUENCE_DETECTION
4079840802
SecurityMonitoringRuleEvaluationWindow:
4079940803
description: 'A time window is specified to match when at least one of the cases
4080040804
matches true. This is a sliding window
@@ -41008,6 +41012,8 @@ components:
4100841012
$ref: '#/components/schemas/SecurityMonitoringRuleMaxSignalDuration'
4100941013
newValueOptions:
4101041014
$ref: '#/components/schemas/SecurityMonitoringRuleNewValueOptions'
41015+
sequenceDetectionOptions:
41016+
$ref: '#/components/schemas/SecurityMonitoringRuleSequenceDetectionOptions'
4101141017
thirdPartyRuleOptions:
4101241018
$ref: '#/components/schemas/SecurityMonitoringRuleThirdPartyOptions'
4101341019
type: object
@@ -41083,6 +41089,47 @@ components:
4108341089
oneOf:
4108441090
- $ref: '#/components/schemas/SecurityMonitoringStandardRuleResponse'
4108541091
- $ref: '#/components/schemas/SecurityMonitoringSignalRuleResponse'
41092+
SecurityMonitoringRuleSequenceDetectionOptions:
41093+
description: Options on sequence detection method.
41094+
properties:
41095+
stepTransitions:
41096+
description: Transitions defining the allowed order of steps and their evaluation
41097+
windows.
41098+
items:
41099+
$ref: '#/components/schemas/SecurityMonitoringRuleSequenceDetectionStepTransition'
41100+
type: array
41101+
steps:
41102+
description: Steps that define the conditions to be matched in sequence.
41103+
items:
41104+
$ref: '#/components/schemas/SecurityMonitoringRuleSequenceDetectionStep'
41105+
type: array
41106+
type: object
41107+
SecurityMonitoringRuleSequenceDetectionStep:
41108+
description: Step definition for sequence detection containing the step name,
41109+
condition, and evaluation window.
41110+
properties:
41111+
condition:
41112+
description: Condition referencing rule queries (e.g., `a > 0`).
41113+
type: string
41114+
evaluationWindow:
41115+
$ref: '#/components/schemas/SecurityMonitoringRuleEvaluationWindow'
41116+
name:
41117+
description: Unique name identifying the step.
41118+
type: string
41119+
type: object
41120+
SecurityMonitoringRuleSequenceDetectionStepTransition:
41121+
description: Transition from a parent step to a child step within a sequence
41122+
detection rule.
41123+
properties:
41124+
child:
41125+
description: Name of the child step.
41126+
type: string
41127+
evaluationWindow:
41128+
$ref: '#/components/schemas/SecurityMonitoringRuleEvaluationWindow'
41129+
parent:
41130+
description: Name of the parent step.
41131+
type: string
41132+
type: object
4108641133
SecurityMonitoringRuleSeverity:
4108741134
description: Severity of the Security Signal.
4108841135
enum:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2025-09-12T15:45:55.719Z

cassettes/features/v2/security_monitoring/Create-a-detection-rule-with-detection-method-sequence-detection-returns-OK-response.yml

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2025-09-12T15:43:48.016Z

cassettes/features/v2/security_monitoring/Validate-a-detection-rule-with-detection-method-sequence-detection-returns-OK-response.yml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Create a detection rule with detection method 'sequence_detection' returns "OK" response
2+
3+
require "datadog_api_client"
4+
api_instance = DatadogAPIClient::V2::SecurityMonitoringAPI.new
5+
6+
body = DatadogAPIClient::V2::SecurityMonitoringStandardRuleCreatePayload.new({
7+
name: "Example-Security-Monitoring",
8+
type: DatadogAPIClient::V2::SecurityMonitoringRuleTypeCreate::LOG_DETECTION,
9+
is_enabled: true,
10+
queries: [
11+
DatadogAPIClient::V2::SecurityMonitoringStandardRuleQuery.new({
12+
aggregation: DatadogAPIClient::V2::SecurityMonitoringRuleQueryAggregation::COUNT,
13+
data_source: DatadogAPIClient::V2::SecurityMonitoringStandardDataSource::LOGS,
14+
distinct_fields: [],
15+
group_by_fields: [],
16+
has_optional_group_by_fields: false,
17+
name: "",
18+
query: "service:logs-rule-reducer source:paul test2",
19+
}),
20+
DatadogAPIClient::V2::SecurityMonitoringStandardRuleQuery.new({
21+
aggregation: DatadogAPIClient::V2::SecurityMonitoringRuleQueryAggregation::COUNT,
22+
data_source: DatadogAPIClient::V2::SecurityMonitoringStandardDataSource::LOGS,
23+
distinct_fields: [],
24+
group_by_fields: [],
25+
has_optional_group_by_fields: false,
26+
name: "",
27+
query: "service:logs-rule-reducer source:paul test1",
28+
}),
29+
],
30+
cases: [
31+
DatadogAPIClient::V2::SecurityMonitoringRuleCaseCreate.new({
32+
name: "",
33+
status: DatadogAPIClient::V2::SecurityMonitoringRuleSeverity::INFO,
34+
notifications: [],
35+
condition: "step_b > 0",
36+
}),
37+
],
38+
message: "Logs and signals asdf",
39+
options: DatadogAPIClient::V2::SecurityMonitoringRuleOptions.new({
40+
detection_method: DatadogAPIClient::V2::SecurityMonitoringRuleDetectionMethod::SEQUENCE_DETECTION,
41+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ZERO_MINUTES,
42+
keep_alive: DatadogAPIClient::V2::SecurityMonitoringRuleKeepAlive::FIVE_MINUTES,
43+
max_signal_duration: DatadogAPIClient::V2::SecurityMonitoringRuleMaxSignalDuration::TEN_MINUTES,
44+
sequence_detection_options: DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionOptions.new({
45+
step_transitions: [
46+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStepTransition.new({
47+
child: "step_b",
48+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::FIFTEEN_MINUTES,
49+
parent: "step_a",
50+
}),
51+
],
52+
steps: [
53+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStep.new({
54+
condition: "a > 0",
55+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ONE_MINUTE,
56+
name: "step_a",
57+
}),
58+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStep.new({
59+
condition: "b > 0",
60+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ONE_MINUTE,
61+
name: "step_b",
62+
}),
63+
],
64+
}),
65+
}),
66+
tags: [],
67+
})
68+
p api_instance.create_security_monitoring_rule(body)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Validate a detection rule with detection method 'sequence_detection' returns "OK" response
2+
3+
require "datadog_api_client"
4+
api_instance = DatadogAPIClient::V2::SecurityMonitoringAPI.new
5+
6+
body = DatadogAPIClient::V2::SecurityMonitoringStandardRulePayload.new({
7+
cases: [
8+
DatadogAPIClient::V2::SecurityMonitoringRuleCaseCreate.new({
9+
name: "",
10+
status: DatadogAPIClient::V2::SecurityMonitoringRuleSeverity::INFO,
11+
notifications: [],
12+
condition: "step_b > 0",
13+
}),
14+
],
15+
has_extended_title: true,
16+
is_enabled: true,
17+
message: "My security monitoring rule",
18+
name: "My security monitoring rule",
19+
options: DatadogAPIClient::V2::SecurityMonitoringRuleOptions.new({
20+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ZERO_MINUTES,
21+
keep_alive: DatadogAPIClient::V2::SecurityMonitoringRuleKeepAlive::FIVE_MINUTES,
22+
max_signal_duration: DatadogAPIClient::V2::SecurityMonitoringRuleMaxSignalDuration::TEN_MINUTES,
23+
detection_method: DatadogAPIClient::V2::SecurityMonitoringRuleDetectionMethod::SEQUENCE_DETECTION,
24+
sequence_detection_options: DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionOptions.new({
25+
step_transitions: [
26+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStepTransition.new({
27+
child: "step_b",
28+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::FIFTEEN_MINUTES,
29+
parent: "step_a",
30+
}),
31+
],
32+
steps: [
33+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStep.new({
34+
condition: "a > 0",
35+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ONE_MINUTE,
36+
name: "step_a",
37+
}),
38+
DatadogAPIClient::V2::SecurityMonitoringRuleSequenceDetectionStep.new({
39+
condition: "b > 0",
40+
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ONE_MINUTE,
41+
name: "step_b",
42+
}),
43+
],
44+
}),
45+
}),
46+
queries: [
47+
DatadogAPIClient::V2::SecurityMonitoringStandardRuleQuery.new({
48+
query: "source:source_here",
49+
group_by_fields: [
50+
"@userIdentity.assumed_role",
51+
],
52+
distinct_fields: [],
53+
aggregation: DatadogAPIClient::V2::SecurityMonitoringRuleQueryAggregation::COUNT,
54+
name: "",
55+
}),
56+
DatadogAPIClient::V2::SecurityMonitoringStandardRuleQuery.new({
57+
query: "source:source_here2",
58+
group_by_fields: [],
59+
distinct_fields: [],
60+
aggregation: DatadogAPIClient::V2::SecurityMonitoringRuleQueryAggregation::COUNT,
61+
name: "",
62+
}),
63+
],
64+
tags: [
65+
"env:prod",
66+
"team:security",
67+
],
68+
type: DatadogAPIClient::V2::SecurityMonitoringRuleTypeCreate::LOG_DETECTION,
69+
})
70+
api_instance.validate_security_monitoring_rule(body)

features/v2/security_monitoring.feature

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ Feature: Security Monitoring
211211
And the response "message" is equal to "Test rule"
212212
And the response "referenceTables" is equal to [{"tableName": "synthetics_test_reference_table_dont_delete", "columnName": "value", "logFieldPath":"testtag", "checkPresence":true, "ruleQueryName":"a"}]
213213

214+
@team:DataDog/k9-cloud-security-platform
215+
Scenario: Create a detection rule with detection method 'sequence_detection' returns "OK" response
216+
Given new "CreateSecurityMonitoringRule" request
217+
And body with value {"name":"{{ unique }}","type":"log_detection","isEnabled":true,"queries":[{"aggregation":"count","dataSource":"logs","distinctFields":[],"groupByFields":[],"hasOptionalGroupByFields":false,"name":"","query":"service:logs-rule-reducer source:paul test2"},{"aggregation":"count","dataSource":"logs","distinctFields":[],"groupByFields":[],"hasOptionalGroupByFields":false,"name":"","query":"service:logs-rule-reducer source:paul test1"}],"cases":[{"name":"","status":"info","notifications":[],"condition":"step_b > 0"}],"message":"Logs and signals asdf","options":{"detectionMethod":"sequence_detection","evaluationWindow":0,"keepAlive":300,"maxSignalDuration":600,"sequenceDetectionOptions":{"stepTransitions":[{"child":"step_b","evaluationWindow":900,"parent":"step_a"}],"steps":[{"condition":"a > 0","evaluationWindow":60,"name":"step_a"},{"condition":"b > 0","evaluationWindow":60,"name":"step_b"}]}},"tags":[]}
218+
When the request is sent
219+
Then the response status is 200 OK
220+
And the response "name" is equal to "{{ unique }}"
221+
And the response "type" is equal to "log_detection"
222+
And the response "options.detectionMethod" is equal to "sequence_detection"
223+
214224
@team:DataDog/k9-cloud-security-platform
215225
Scenario: Create a detection rule with detection method 'third_party' returns "OK" response
216226
Given new "CreateSecurityMonitoringRule" request
@@ -1483,6 +1493,13 @@ Feature: Security Monitoring
14831493
When the request is sent
14841494
Then the response status is 204 OK
14851495

1496+
@team:DataDog/k9-cloud-security-platform
1497+
Scenario: Validate a detection rule with detection method 'sequence_detection' returns "OK" response
1498+
Given new "ValidateSecurityMonitoringRule" request
1499+
And body with value {"cases":[{"name":"","status":"info","notifications":[],"condition":"step_b > 0"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":0,"keepAlive":300,"maxSignalDuration":600,"detectionMethod":"sequence_detection","sequenceDetectionOptions":{"stepTransitions":[{"child":"step_b","evaluationWindow":900,"parent":"step_a"}],"steps":[{"condition":"a > 0","evaluationWindow":60,"name":"step_a"},{"condition":"b > 0","evaluationWindow":60,"name":"step_b"}]}},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"aggregation":"count","name":""},{"query":"source:source_here2","groupByFields":[],"distinctFields":[],"aggregation":"count","name":""}],"tags":["env:prod","team:security"],"type":"log_detection"}
1500+
When the request is sent
1501+
Then the response status is 204 OK
1502+
14861503
@team:DataDog/k9-cloud-security-platform
14871504
Scenario: Validate a suppression rule returns "Bad Request" response
14881505
Given new "ValidateSecurityMonitoringSuppression" request

lib/datadog_api_client/inflector.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3521,6 +3521,9 @@ def overrides
35213521
"v2.security_monitoring_rule_query_payload" => "SecurityMonitoringRuleQueryPayload",
35223522
"v2.security_monitoring_rule_query_payload_data" => "SecurityMonitoringRuleQueryPayloadData",
35233523
"v2.security_monitoring_rule_response" => "SecurityMonitoringRuleResponse",
3524+
"v2.security_monitoring_rule_sequence_detection_options" => "SecurityMonitoringRuleSequenceDetectionOptions",
3525+
"v2.security_monitoring_rule_sequence_detection_step" => "SecurityMonitoringRuleSequenceDetectionStep",
3526+
"v2.security_monitoring_rule_sequence_detection_step_transition" => "SecurityMonitoringRuleSequenceDetectionStepTransition",
35243527
"v2.security_monitoring_rule_severity" => "SecurityMonitoringRuleSeverity",
35253528
"v2.security_monitoring_rule_test_payload" => "SecurityMonitoringRuleTestPayload",
35263529
"v2.security_monitoring_rule_test_request" => "SecurityMonitoringRuleTestRequest",

0 commit comments

Comments
 (0)