Skip to content

Commit 4dc50fe

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

File tree

12 files changed

+374
-0
lines changed

12 files changed

+374
-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+
}

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

services/security_monitoring/src/v2/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ export { SecurityMonitoringFilter } from "./models/SecurityMonitoringFilter";
283283
export { SecurityMonitoringFilterAction } from "./models/SecurityMonitoringFilterAction";
284284
export { SecurityMonitoringListRulesResponse } from "./models/SecurityMonitoringListRulesResponse";
285285
export { SecurityMonitoringReferenceTable } from "./models/SecurityMonitoringReferenceTable";
286+
export { SecurityMonitoringRuleAnomalyDetectionOptions } from "./models/SecurityMonitoringRuleAnomalyDetectionOptions";
287+
export { SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration";
288+
export { SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance";
289+
export { SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration } from "./models/SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration";
286290
export { SecurityMonitoringRuleCase } from "./models/SecurityMonitoringRuleCase";
287291
export { SecurityMonitoringRuleCaseAction } from "./models/SecurityMonitoringRuleCaseAction";
288292
export { SecurityMonitoringRuleCaseActionOptions } from "./models/SecurityMonitoringRuleCaseActionOptions";
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { AttributeTypeMap } from "@datadog/datadog-api-client";
2+
3+
import { SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration } from "./SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration";
4+
import { SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance } from "./SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance";
5+
import { SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration } from "./SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration";
6+
7+
/**
8+
* Options on anomaly detection method.
9+
*/
10+
export class SecurityMonitoringRuleAnomalyDetectionOptions {
11+
/**
12+
* Duration in seconds of the time buckets used to aggregate events matched by the rule.
13+
* Must be greater than or equal to 300.
14+
*/
15+
"bucketDuration"?: SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration;
16+
/**
17+
* An optional parameter that sets how permissive anomaly detection is.
18+
* Higher values require higher deviations before triggering a signal.
19+
*/
20+
"detectionTolerance"?: SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance;
21+
/**
22+
* Learning duration in hours. Anomaly detection waits for at least this amount of historical data before it starts evaluating.
23+
*/
24+
"learningDuration"?: SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration;
25+
/**
26+
* An optional override baseline to apply while the rule is in the learning period. Must be greater than or equal to 0.
27+
*/
28+
"learningPeriodBaseline"?: number;
29+
/**
30+
* A container for additional, undeclared properties.
31+
* This is a holder for any undeclared properties as specified with
32+
* the 'additionalProperties' keyword in the OAS document.
33+
*/
34+
"additionalProperties"?: { [key: string]: any };
35+
/**
36+
* @ignore
37+
*/
38+
"_unparsed"?: boolean;
39+
40+
/**
41+
* @ignore
42+
*/
43+
static readonly attributeTypeMap: AttributeTypeMap = {
44+
bucketDuration: {
45+
baseName: "bucketDuration",
46+
type: "SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration",
47+
format: "int32",
48+
},
49+
detectionTolerance: {
50+
baseName: "detectionTolerance",
51+
type: "SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance",
52+
format: "int32",
53+
},
54+
learningDuration: {
55+
baseName: "learningDuration",
56+
type: "SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration",
57+
format: "int32",
58+
},
59+
learningPeriodBaseline: {
60+
baseName: "learningPeriodBaseline",
61+
type: "number",
62+
format: "int64",
63+
},
64+
additionalProperties: {
65+
baseName: "additionalProperties",
66+
type: "{ [key: string]: any; }",
67+
},
68+
};
69+
70+
/**
71+
* @ignore
72+
*/
73+
static getAttributeTypeMap(): AttributeTypeMap {
74+
return SecurityMonitoringRuleAnomalyDetectionOptions.attributeTypeMap;
75+
}
76+
77+
public constructor() {}
78+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { UnparsedObject } from "@datadog/datadog-api-client";
2+
3+
/**
4+
* Duration in seconds of the time buckets used to aggregate events matched by the rule.
5+
* Must be greater than or equal to 300.
6+
*/
7+
export type SecurityMonitoringRuleAnomalyDetectionOptionsBucketDuration =
8+
| typeof FIVE_MINUTES
9+
| typeof TEN_MINUTES
10+
| typeof FIFTEEN_MINUTES
11+
| typeof THIRTY_MINUTES
12+
| typeof ONE_HOUR
13+
| typeof THREE_HOURS
14+
| UnparsedObject;
15+
export const FIVE_MINUTES = 300;
16+
export const TEN_MINUTES = 600;
17+
export const FIFTEEN_MINUTES = 900;
18+
export const THIRTY_MINUTES = 1800;
19+
export const ONE_HOUR = 3600;
20+
export const THREE_HOURS = 10800;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { UnparsedObject } from "@datadog/datadog-api-client";
2+
3+
/**
4+
* An optional parameter that sets how permissive anomaly detection is.
5+
* Higher values require higher deviations before triggering a signal.
6+
*/
7+
export type SecurityMonitoringRuleAnomalyDetectionOptionsDetectionTolerance =
8+
| typeof ONE
9+
| typeof TWO
10+
| typeof THREE
11+
| typeof FOUR
12+
| typeof FIVE
13+
| UnparsedObject;
14+
export const ONE = 1;
15+
export const TWO = 2;
16+
export const THREE = 3;
17+
export const FOUR = 4;
18+
export const FIVE = 5;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { UnparsedObject } from "@datadog/datadog-api-client";
2+
3+
/**
4+
* Learning duration in hours. Anomaly detection waits for at least this amount of historical data before it starts evaluating.
5+
*/
6+
export type SecurityMonitoringRuleAnomalyDetectionOptionsLearningDuration =
7+
| typeof ONE_HOUR
8+
| typeof SIX_HOURS
9+
| typeof TWELVE_HOURS
10+
| typeof ONE_DAY
11+
| typeof TWO_DAYS
12+
| typeof ONE_WEEK
13+
| typeof TWO_WEEKS
14+
| UnparsedObject;
15+
export const ONE_HOUR = 1;
16+
export const SIX_HOURS = 6;
17+
export const TWELVE_HOURS = 12;
18+
export const ONE_DAY = 24;
19+
export const TWO_DAYS = 48;
20+
export const ONE_WEEK = 168;
21+
export const TWO_WEEKS = 336;

0 commit comments

Comments
 (0)