Skip to content

Commit c4b4df2

Browse files
api-clients-generation-pipeline[bot]ci.datadog-api-spec
andauthored
Add validation endpoint for Security Monitoring Rules (#1930)
Co-authored-by: ci.datadog-api-spec <[email protected]> Co-authored-by: api-clients-generation-pipeline[bot] <54105614+api-clients-generation-pipeline[bot]@users.noreply.github.com>
1 parent 735192c commit c4b4df2

10 files changed

+209
-4
lines changed

.apigentools-info

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"spec_versions": {
55
"v1": {
66
"apigentools_version": "1.6.6",
7-
"regenerated": "2024-03-26 15:17:46.509398",
8-
"spec_repo_commit": "46383d02"
7+
"regenerated": "2024-03-27 22:12:41.732378",
8+
"spec_repo_commit": "85625198"
99
},
1010
"v2": {
1111
"apigentools_version": "1.6.6",
12-
"regenerated": "2024-03-26 15:17:46.526266",
13-
"spec_repo_commit": "46383d02"
12+
"regenerated": "2024-03-27 22:12:41.749222",
13+
"spec_repo_commit": "85625198"
1414
}
1515
}
1616
}

.generator/schemas/v2/openapi.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32287,6 +32287,34 @@ paths:
3228732287
tags:
3228832288
- Security Monitoring
3228932289
x-codegen-request-body-name: body
32290+
/api/v2/security_monitoring/rules/validation:
32291+
post:
32292+
description: Validate a detection rule.
32293+
operationId: ValidateSecurityMonitoringRule
32294+
requestBody:
32295+
content:
32296+
application/json:
32297+
schema:
32298+
$ref: '#/components/schemas/SecurityMonitoringRuleCreatePayload'
32299+
required: true
32300+
responses:
32301+
'204':
32302+
description: OK
32303+
'400':
32304+
$ref: '#/components/responses/BadRequestResponse'
32305+
'403':
32306+
$ref: '#/components/responses/NotAuthorizedResponse'
32307+
'429':
32308+
$ref: '#/components/responses/TooManyRequestsResponse'
32309+
security:
32310+
- apiKeyAuth: []
32311+
appKeyAuth: []
32312+
- AuthZ:
32313+
- security_monitoring_rules_write
32314+
summary: Validate a detection rule
32315+
tags:
32316+
- Security Monitoring
32317+
x-codegen-request-body-name: body
3229032318
/api/v2/security_monitoring/rules/{rule_id}:
3229132319
delete:
3229232320
description: Delete an existing rule. Default rules cannot be deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
Validate a detection rule returns "OK" response
3+
"""
4+
5+
from datadog_api_client import ApiClient, Configuration
6+
from datadog_api_client.v2.api.security_monitoring_api import SecurityMonitoringApi
7+
from datadog_api_client.v2.model.security_monitoring_rule_case_create import SecurityMonitoringRuleCaseCreate
8+
from datadog_api_client.v2.model.security_monitoring_rule_detection_method import SecurityMonitoringRuleDetectionMethod
9+
from datadog_api_client.v2.model.security_monitoring_rule_evaluation_window import (
10+
SecurityMonitoringRuleEvaluationWindow,
11+
)
12+
from datadog_api_client.v2.model.security_monitoring_rule_keep_alive import SecurityMonitoringRuleKeepAlive
13+
from datadog_api_client.v2.model.security_monitoring_rule_max_signal_duration import (
14+
SecurityMonitoringRuleMaxSignalDuration,
15+
)
16+
from datadog_api_client.v2.model.security_monitoring_rule_options import SecurityMonitoringRuleOptions
17+
from datadog_api_client.v2.model.security_monitoring_rule_query_aggregation import (
18+
SecurityMonitoringRuleQueryAggregation,
19+
)
20+
from datadog_api_client.v2.model.security_monitoring_rule_severity import SecurityMonitoringRuleSeverity
21+
from datadog_api_client.v2.model.security_monitoring_rule_type_create import SecurityMonitoringRuleTypeCreate
22+
from datadog_api_client.v2.model.security_monitoring_standard_rule_create_payload import (
23+
SecurityMonitoringStandardRuleCreatePayload,
24+
)
25+
from datadog_api_client.v2.model.security_monitoring_standard_rule_query import SecurityMonitoringStandardRuleQuery
26+
27+
body = SecurityMonitoringStandardRuleCreatePayload(
28+
cases=[
29+
SecurityMonitoringRuleCaseCreate(
30+
name="",
31+
status=SecurityMonitoringRuleSeverity.INFO,
32+
notifications=[],
33+
condition="a > 0",
34+
),
35+
],
36+
has_extended_title=True,
37+
is_enabled=True,
38+
message="My security monitoring rule",
39+
name="My security monitoring rule",
40+
options=SecurityMonitoringRuleOptions(
41+
evaluation_window=SecurityMonitoringRuleEvaluationWindow.THIRTY_MINUTES,
42+
keep_alive=SecurityMonitoringRuleKeepAlive.THIRTY_MINUTES,
43+
max_signal_duration=SecurityMonitoringRuleMaxSignalDuration.THIRTY_MINUTES,
44+
detection_method=SecurityMonitoringRuleDetectionMethod.THRESHOLD,
45+
),
46+
queries=[
47+
SecurityMonitoringStandardRuleQuery(
48+
query="source:source_here",
49+
group_by_fields=[
50+
"@userIdentity.assumed_role",
51+
],
52+
distinct_fields=[],
53+
aggregation=SecurityMonitoringRuleQueryAggregation.COUNT,
54+
name="",
55+
),
56+
],
57+
tags=[
58+
"env:prod",
59+
"team:security",
60+
],
61+
type=SecurityMonitoringRuleTypeCreate.LOG_DETECTION,
62+
)
63+
64+
configuration = Configuration()
65+
with ApiClient(configuration) as api_client:
66+
api_instance = SecurityMonitoringApi(api_client)
67+
api_instance.validate_security_monitoring_rule(body=body)

src/datadog_api_client/v2/api/security_monitoring_api.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,26 @@ def __init__(self, api_client=None):
714714
api_client=api_client,
715715
)
716716

717+
self._validate_security_monitoring_rule_endpoint = _Endpoint(
718+
settings={
719+
"response_type": None,
720+
"auth": ["apiKeyAuth", "appKeyAuth", "AuthZ"],
721+
"endpoint_path": "/api/v2/security_monitoring/rules/validation",
722+
"operation_id": "validate_security_monitoring_rule",
723+
"http_method": "POST",
724+
"version": "v2",
725+
},
726+
params_map={
727+
"body": {
728+
"required": True,
729+
"openapi_types": (SecurityMonitoringRuleCreatePayload,),
730+
"location": "body",
731+
},
732+
},
733+
headers_map={"accept": ["*/*"], "content_type": ["application/json"]},
734+
api_client=api_client,
735+
)
736+
717737
def create_security_filter(
718738
self,
719739
body: SecurityFilterCreateRequest,
@@ -1503,3 +1523,24 @@ def update_security_monitoring_suppression(
15031523
kwargs["body"] = body
15041524

15051525
return self._update_security_monitoring_suppression_endpoint.call_with_http_info(**kwargs)
1526+
1527+
def validate_security_monitoring_rule(
1528+
self,
1529+
body: Union[
1530+
SecurityMonitoringRuleCreatePayload,
1531+
SecurityMonitoringStandardRuleCreatePayload,
1532+
SecurityMonitoringSignalRuleCreatePayload,
1533+
CloudConfigurationRuleCreatePayload,
1534+
],
1535+
) -> None:
1536+
"""Validate a detection rule.
1537+
1538+
Validate a detection rule.
1539+
1540+
:type body: SecurityMonitoringRuleCreatePayload
1541+
:rtype: None
1542+
"""
1543+
kwargs: Dict[str, Any] = {}
1544+
kwargs["body"] = body
1545+
1546+
return self._validate_security_monitoring_rule_endpoint.call_with_http_info(**kwargs)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2024-03-27T16:23:09.814Z
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
interactions:
2+
- request:
3+
body: '{"cases":[{"condition":"a > 0","name":"","notifications":[],"status":"info"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My
4+
security monitoring rule","name":"My security monitoring rule","options":{"detectionMethod":"threshold","evaluationWindow":1800,"keepAlive":999999,"maxSignalDuration":1800},"queries":[{"aggregation":"count","distinctFields":[],"groupByFields":["@userIdentity.assumed_role"],"name":"","query":"source:source_here"}],"tags":["env:prod","team:security"],"type":"log_detection"}'
5+
headers:
6+
accept:
7+
- '*/*'
8+
content-type:
9+
- application/json
10+
method: POST
11+
uri: https://api.datadoghq.com/api/v2/security_monitoring/rules/validation
12+
response:
13+
body:
14+
string: '{"error":{"code":"InvalidArgument","message":"Invalid rule configuration","details":[{"code":"InvalidArgument","message":"Max
15+
signal duration must be greater than or equal to keep alive","target":"maxSignalDuration"},{"code":"InvalidArgument","message":"Keep
16+
alive is not in allowed durations: 0, 1, 5, 10, 15, 30, 60, 120, 180, 360
17+
(in minutes)","target":"keepAlive"}]}}
18+
19+
'
20+
headers:
21+
content-type:
22+
- application/json
23+
status:
24+
code: 400
25+
message: Bad Request
26+
version: 1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2024-03-27T16:23:10.157Z
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
interactions:
2+
- request:
3+
body: '{"cases":[{"condition":"a > 0","name":"","notifications":[],"status":"info"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My
4+
security monitoring rule","name":"My security monitoring rule","options":{"detectionMethod":"threshold","evaluationWindow":1800,"keepAlive":1800,"maxSignalDuration":1800},"queries":[{"aggregation":"count","distinctFields":[],"groupByFields":["@userIdentity.assumed_role"],"name":"","query":"source:source_here"}],"tags":["env:prod","team:security"],"type":"log_detection"}'
5+
headers:
6+
accept:
7+
- '*/*'
8+
content-type:
9+
- application/json
10+
method: POST
11+
uri: https://api.datadoghq.com/api/v2/security_monitoring/rules/validation
12+
response:
13+
body:
14+
string: ''
15+
headers:
16+
content-type:
17+
- text/html; charset=utf-8
18+
status:
19+
code: 204
20+
message: No Content
21+
version: 1

tests/v2/features/security_monitoring.feature

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,3 +606,17 @@ Feature: Security Monitoring
606606
Then the response status is 200 OK
607607
And the response "name" is equal to "{{ unique }}-Updated"
608608
And the response "id" has the same value as "security_rule.id"
609+
610+
@skip-go @skip-java @skip-python @skip-ruby @skip-rust @skip-typescript @skip-validation @team:DataDog/k9-cloud-security-platform
611+
Scenario: Validate a detection rule returns "Bad Request" response
612+
Given new "ValidateSecurityMonitoringRule" request
613+
And body with value {"cases":[{"name":"","status":"info","notifications":[],"condition":"a > 0"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":1800,"keepAlive":999999,"maxSignalDuration":1800,"detectionMethod":"threshold"},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"aggregation":"count","name":""}],"tags":["env:prod","team:security"],"type":"log_detection"}
614+
When the request is sent
615+
Then the response status is 400 Bad Request
616+
617+
@team:DataDog/k9-cloud-security-platform
618+
Scenario: Validate a detection rule returns "OK" response
619+
Given new "ValidateSecurityMonitoringRule" request
620+
And body with value {"cases":[{"name":"","status":"info","notifications":[],"condition":"a > 0"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":1800,"keepAlive":1800,"maxSignalDuration":1800,"detectionMethod":"threshold"},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"aggregation":"count","name":""}],"tags":["env:prod","team:security"],"type":"log_detection"}
621+
When the request is sent
622+
Then the response status is 204 OK

tests/v2/features/undo.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,12 @@
17511751
"type": "unsafe"
17521752
}
17531753
},
1754+
"ValidateSecurityMonitoringRule": {
1755+
"tag": "Security Monitoring",
1756+
"undo": {
1757+
"type": "idempotent"
1758+
}
1759+
},
17541760
"DeleteSecurityMonitoringRule": {
17551761
"tag": "Security Monitoring",
17561762
"undo": {

0 commit comments

Comments
 (0)