Skip to content

Commit f351069

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Add anomaly detection options to security monitoring rules (#3136)
Co-authored-by: ci.datadog-api-spec <packages@datadoghq.com>
1 parent 8558ee2 commit f351069

File tree

13 files changed

+458
-0
lines changed

13 files changed

+458
-0
lines changed

.generator/schemas/v2/openapi.yaml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47320,6 +47320,86 @@ components:
4732047320
description: The name of the reference table.
4732147321
type: string
4732247322
type: object
47323+
SecurityMonitoringRuleAnomalyDetectionOptions:
47324+
additionalProperties: {}
47325+
description: Options on anomaly detection method.
47326+
properties:
47327+
bucketDuration:
47328+
$ref: '#/components/schemas/SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration'
47329+
detectionTolerance:
47330+
$ref: '#/components/schemas/SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance'
47331+
learningDuration:
47332+
$ref: '#/components/schemas/SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration'
47333+
learningPeriodBaseline:
47334+
description: An optional override baseline to apply while the rule is in
47335+
the learning period. Must be greater than or equal to 0.
47336+
format: int64
47337+
minimum: 0
47338+
type: integer
47339+
type: object
47340+
SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration:
47341+
description: 'Duration in seconds of the time buckets used to aggregate events
47342+
matched by the rule.
47343+
47344+
Must be greater than or equal to 300.'
47345+
enum:
47346+
- 300
47347+
- 600
47348+
- 900
47349+
- 1800
47350+
- 3600
47351+
- 10800
47352+
example: 300
47353+
format: int32
47354+
type: integer
47355+
x-enum-varnames:
47356+
- FIVE_MINUTES
47357+
- TEN_MINUTES
47358+
- FIFTEEN_MINUTES
47359+
- THIRTY_MINUTES
47360+
- ONE_HOUR
47361+
- THREE_HOURS
47362+
SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance:
47363+
description: 'An optional parameter that sets how permissive anomaly detection
47364+
is.
47365+
47366+
Higher values require higher deviations before triggering a signal.'
47367+
enum:
47368+
- 1
47369+
- 2
47370+
- 3
47371+
- 4
47372+
- 5
47373+
example: 5
47374+
format: int32
47375+
type: integer
47376+
x-enum-varnames:
47377+
- ONE
47378+
- TWO
47379+
- THREE
47380+
- FOUR
47381+
- FIVE
47382+
SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration:
47383+
description: Learning duration in hours. Anomaly detection waits for at least
47384+
this amount of historical data before it starts evaluating.
47385+
enum:
47386+
- 1
47387+
- 6
47388+
- 12
47389+
- 24
47390+
- 48
47391+
- 168
47392+
- 336
47393+
format: int32
47394+
type: integer
47395+
x-enum-varnames:
47396+
- ONE_HOUR
47397+
- SIX_HOURS
47398+
- TWELVE_HOURS
47399+
- ONE_DAY
47400+
- TWO_DAYS
47401+
- ONE_WEEK
47402+
- TWO_WEEKS
4732347403
SecurityMonitoringRuleCase:
4732447404
description: Case when signal is generated.
4732547405
properties:
@@ -47685,6 +47765,8 @@ components:
4768547765
SecurityMonitoringRuleOptions:
4768647766
description: Options.
4768747767
properties:
47768+
anomalyDetectionOptions:
47769+
$ref: '#/components/schemas/SecurityMonitoringRuleAnomalyDetectionOptions'
4768847770
complianceRuleOptions:
4768947771
$ref: '#/components/schemas/CloudConfigurationComplianceRuleOptions'
4769047772
decreaseCriticalityBasedOnEnv:
@@ -55124,6 +55206,8 @@ components:
5512455206
ThreatHuntingJobOptions:
5512555207
description: Job options.
5512655208
properties:
55209+
anomalyDetectionOptions:
55210+
$ref: '#/components/schemas/SecurityMonitoringRuleAnomalyDetectionOptions'
5512755211
detectionMethod:
5512855212
$ref: '#/components/schemas/SecurityMonitoringRuleDetectionMethod'
5512955213
evaluationWindow:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"2025-12-16T15:19:00.493Z"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
{
2+
"log": {
3+
"_recordingName": "Security Monitoring/Create a detection rule with detection method 'anomaly_detection' returns \"OK\" response",
4+
"creator": {
5+
"comment": "persister:fs",
6+
"name": "Polly.JS",
7+
"version": "6.0.5"
8+
},
9+
"entries": [
10+
{
11+
"_id": "ceeb4640e238fd2dfaea833262b811c7",
12+
"_order": 0,
13+
"cache": {},
14+
"request": {
15+
"bodySize": 736,
16+
"cookies": [],
17+
"headers": [
18+
{
19+
"_fromType": "array",
20+
"name": "accept",
21+
"value": "application/json"
22+
},
23+
{
24+
"_fromType": "array",
25+
"name": "content-type",
26+
"value": "application/json"
27+
}
28+
],
29+
"headersSize": 586,
30+
"httpVersion": "HTTP/1.1",
31+
"method": "POST",
32+
"postData": {
33+
"mimeType": "application/json",
34+
"params": [],
35+
"text": "{\"cases\":[{\"condition\":\"a > 0.995\",\"name\":\"\",\"notifications\":[],\"status\":\"info\"}],\"filters\":[],\"isEnabled\":true,\"message\":\"An anomaly detection rule\",\"name\":\"Test-Create_a_detection_rule_with_detection_method_anomaly_detection_returns_OK_response-1765898340\",\"options\":{\"anomalyDetectionOptions\":{\"bucketDuration\":300,\"detectionTolerance\":3,\"learningDuration\":24,\"learningPeriodBaseline\":10},\"detectionMethod\":\"anomaly_detection\",\"evaluationWindow\":900,\"keepAlive\":3600,\"maxSignalDuration\":86400},\"queries\":[{\"aggregation\":\"count\",\"dataSource\":\"logs\",\"distinctFields\":[],\"groupByFields\":[\"@usr.email\",\"@network.client.ip\"],\"hasOptionalGroupByFields\":false,\"name\":\"\",\"query\":\"service:app status:error\"}],\"tags\":[],\"type\":\"log_detection\"}"
36+
},
37+
"queryString": [],
38+
"url": "https://api.datadoghq.com/api/v2/security_monitoring/rules"
39+
},
40+
"response": {
41+
"bodySize": 1163,
42+
"content": {
43+
"mimeType": "application/json",
44+
"size": 1163,
45+
"text": "{\"name\":\"Test-Create_a_detection_rule_with_detection_method_anomaly_detection_returns_OK_response-1765898340\",\"createdAt\":1765898340611,\"isDefault\":false,\"isPartner\":false,\"isEnabled\":true,\"isBeta\":false,\"isDeleted\":false,\"isDeprecated\":false,\"queries\":[{\"query\":\"service:app status:error\",\"groupByFields\":[\"@usr.email\",\"@network.client.ip\"],\"hasOptionalGroupByFields\":false,\"distinctFields\":[],\"aggregation\":\"count\",\"name\":\"\",\"dataSource\":\"logs\"}],\"options\":{\"evaluationWindow\":1800,\"detectionMethod\":\"anomaly_detection\",\"maxSignalDuration\":86400,\"keepAlive\":3600,\"anomalyDetectionOptions\":{\"bucketDuration\":300,\"learningDuration\":24,\"detectionTolerance\":3,\"instantaneousBaseline\":false,\"instantaneousBaselineTimeoutMinutes\":30,\"learningPeriodBaseline\":10}},\"cases\":[{\"name\":\"\",\"status\":\"info\",\"notifications\":[],\"condition\":\"a \\u003e 0.995\"}],\"message\":\"An anomaly detection rule\",\"tags\":[],\"hasExtendedTitle\":false,\"type\":\"log_detection\",\"filters\":[],\"version\":1,\"id\":\"0vk-kph-3ri\",\"blocking\":false,\"metadata\":{\"entities\":null,\"sources\":null},\"creationAuthorId\":1445416,\"creator\":{\"handle\":\"frog@datadoghq.com\",\"name\":\"frog\"},\"updater\":{\"handle\":\"\",\"name\":\"\"}}"
46+
},
47+
"cookies": [],
48+
"headers": [
49+
{
50+
"name": "content-type",
51+
"value": "application/json"
52+
}
53+
],
54+
"headersSize": 656,
55+
"httpVersion": "HTTP/1.1",
56+
"redirectURL": "",
57+
"status": 200,
58+
"statusText": "OK"
59+
},
60+
"startedDateTime": "2025-12-16T15:19:00.497Z",
61+
"time": 129
62+
},
63+
{
64+
"_id": "903a73a28dbeebf5cd6c473010faf924",
65+
"_order": 0,
66+
"cache": {},
67+
"request": {
68+
"bodySize": 0,
69+
"cookies": [],
70+
"headers": [
71+
{
72+
"_fromType": "array",
73+
"name": "accept",
74+
"value": "*/*"
75+
}
76+
],
77+
"headersSize": 534,
78+
"httpVersion": "HTTP/1.1",
79+
"method": "DELETE",
80+
"queryString": [],
81+
"url": "https://api.datadoghq.com/api/v2/security_monitoring/rules/0vk-kph-3ri"
82+
},
83+
"response": {
84+
"bodySize": 0,
85+
"content": {
86+
"mimeType": "text/plain",
87+
"size": 0
88+
},
89+
"cookies": [],
90+
"headers": [],
91+
"headersSize": 602,
92+
"httpVersion": "HTTP/1.1",
93+
"redirectURL": "",
94+
"status": 204,
95+
"statusText": "No Content"
96+
},
97+
"startedDateTime": "2025-12-16T15:19:00.633Z",
98+
"time": 119
99+
}
100+
],
101+
"pages": [],
102+
"version": "1.2"
103+
}
104+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Create a detection rule with detection method 'anomaly_detection' returns "OK" response
3+
*/
4+
5+
import { client, v2 } from "@datadog/datadog-api-client";
6+
7+
const configuration = client.createConfiguration();
8+
const apiInstance = new v2.SecurityMonitoringApi(configuration);
9+
10+
const params: v2.SecurityMonitoringApiCreateSecurityMonitoringRuleRequest = {
11+
body: {
12+
name: "Example-Security-Monitoring",
13+
type: "log_detection",
14+
isEnabled: true,
15+
queries: [
16+
{
17+
aggregation: "count",
18+
dataSource: "logs",
19+
distinctFields: [],
20+
groupByFields: ["@usr.email", "@network.client.ip"],
21+
hasOptionalGroupByFields: false,
22+
name: "",
23+
query: "service:app status:error",
24+
},
25+
],
26+
cases: [
27+
{
28+
name: "",
29+
status: "info",
30+
notifications: [],
31+
condition: "a > 0.995",
32+
},
33+
],
34+
message: "An anomaly detection rule",
35+
options: {
36+
detectionMethod: "anomaly_detection",
37+
evaluationWindow: 900,
38+
keepAlive: 3600,
39+
maxSignalDuration: 86400,
40+
anomalyDetectionOptions: {
41+
bucketDuration: 300,
42+
learningDuration: 24,
43+
detectionTolerance: 3,
44+
learningPeriodBaseline: 10,
45+
},
46+
},
47+
tags: [],
48+
filters: [],
49+
},
50+
};
51+
52+
apiInstance
53+
.createSecurityMonitoringRule(params)
54+
.then((data: v2.SecurityMonitoringRuleResponse) => {
55+
console.log(
56+
"API called successfully. Returned data: " + JSON.stringify(data)
57+
);
58+
})
59+
.catch((error: any) => console.error(error));

features/v2/security_monitoring.feature

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,20 @@ Feature: Security Monitoring
333333
And the response "message" is equal to "Test rule"
334334
And the response "referenceTables" is equal to [{"tableName": "synthetics_test_reference_table_dont_delete", "columnName": "value", "logFieldPath":"testtag", "checkPresence":true, "ruleQueryName":"a"}]
335335

336+
@team:DataDog/k9-cloud-security-platform
337+
Scenario: Create a detection rule with detection method 'anomaly_detection' returns "OK" response
338+
Given new "CreateSecurityMonitoringRule" request
339+
And body with value {"name":"{{ unique }}","type":"log_detection","isEnabled":true,"queries":[{"aggregation":"count","dataSource":"logs","distinctFields":[],"groupByFields":["@usr.email","@network.client.ip"],"hasOptionalGroupByFields":false,"name":"","query":"service:app status:error"}],"cases":[{"name":"","status":"info","notifications":[],"condition":"a > 0.995"}],"message":"An anomaly detection rule","options":{"detectionMethod":"anomaly_detection","evaluationWindow":900,"keepAlive":3600,"maxSignalDuration":86400,"anomalyDetectionOptions":{"bucketDuration":300,"learningDuration":24,"detectionTolerance":3,"learningPeriodBaseline":10}},"tags":[],"filters":[]}
340+
When the request is sent
341+
Then the response status is 200 OK
342+
And the response "name" is equal to "{{ unique }}"
343+
And the response "type" is equal to "log_detection"
344+
And the response "options.detectionMethod" is equal to "anomaly_detection"
345+
And the response "options.anomalyDetectionOptions.bucketDuration" is equal to 300
346+
And the response "options.anomalyDetectionOptions.learningDuration" is equal to 24
347+
And the response "options.anomalyDetectionOptions.learningPeriodBaseline" is equal to 10
348+
And the response "options.anomalyDetectionOptions.detectionTolerance" is equal to 3
349+
336350
@team:DataDog/k9-cloud-security-platform
337351
Scenario: Create a detection rule with detection method 'sequence_detection' returns "OK" response
338352
Given new "CreateSecurityMonitoringRule" request

packages/datadog-api-client-v2/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3956,6 +3956,10 @@ export { SecurityMonitoringFilter } from "./models/SecurityMonitoringFilter";
39563956
export { SecurityMonitoringFilterAction } from "./models/SecurityMonitoringFilterAction";
39573957
export { SecurityMonitoringListRulesResponse } from "./models/SecurityMonitoringListRulesResponse";
39583958
export { SecurityMonitoringReferenceTable } from "./models/SecurityMonitoringReferenceTable";
3959+
export { SecurityMonitoringRuleAnomalyDetectionOptions } from "./models/SecurityMonitoringRuleAnomalyDetectionOptions";
3960+
export { SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration";
3961+
export { SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance";
3962+
export { SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration";
39593963
export { SecurityMonitoringRuleCase } from "./models/SecurityMonitoringRuleCase";
39603964
export { SecurityMonitoringRuleCaseAction } from "./models/SecurityMonitoringRuleCaseAction";
39613965
export { SecurityMonitoringRuleCaseActionOptions } from "./models/SecurityMonitoringRuleCaseActionOptions";

packages/datadog-api-client-v2/models/ObjectSerializer.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,6 +2247,7 @@ import { SecurityFiltersResponse } from "./SecurityFiltersResponse";
22472247
import { SecurityMonitoringFilter } from "./SecurityMonitoringFilter";
22482248
import { SecurityMonitoringListRulesResponse } from "./SecurityMonitoringListRulesResponse";
22492249
import { SecurityMonitoringReferenceTable } from "./SecurityMonitoringReferenceTable";
2250+
import { SecurityMonitoringRuleAnomalyDetectionOptions } from "./SecurityMonitoringRuleAnomalyDetectionOptions";
22502251
import { SecurityMonitoringRuleCase } from "./SecurityMonitoringRuleCase";
22512252
import { SecurityMonitoringRuleCaseAction } from "./SecurityMonitoringRuleCaseAction";
22522253
import { SecurityMonitoringRuleCaseActionOptions } from "./SecurityMonitoringRuleCaseActionOptions";
@@ -4048,6 +4049,15 @@ const enumsMap: { [key: string]: any[] } = {
40484049
SecurityFilterFilteredDataType: ["logs"],
40494050
SecurityFilterType: ["security_filters"],
40504051
SecurityMonitoringFilterAction: ["require", "suppress"],
4052+
SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration: [
4053+
300, 600, 900, 1800, 3600, 10800,
4054+
],
4055+
SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance: [
4056+
1, 2, 3, 4, 5,
4057+
],
4058+
SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration: [
4059+
1, 6, 12, 24, 48, 168, 336,
4060+
],
40514061
SecurityMonitoringRuleCaseActionOptionsFlaggedIPType: [
40524062
"SUSPICIOUS",
40534063
"FLAGGED",
@@ -7083,6 +7093,8 @@ const typeMap: { [index: string]: any } = {
70837093
SecurityMonitoringFilter: SecurityMonitoringFilter,
70847094
SecurityMonitoringListRulesResponse: SecurityMonitoringListRulesResponse,
70857095
SecurityMonitoringReferenceTable: SecurityMonitoringReferenceTable,
7096+
SecurityMonitoringRuleAnomalyDetectionOptions:
7097+
SecurityMonitoringRuleAnomalyDetectionOptions,
70867098
SecurityMonitoringRuleCase: SecurityMonitoringRuleCase,
70877099
SecurityMonitoringRuleCaseAction: SecurityMonitoringRuleCaseAction,
70887100
SecurityMonitoringRuleCaseActionOptions:

0 commit comments

Comments
 (0)