diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 7c9668ae42..05f293a569 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -47312,6 +47312,8 @@ components: properties: forgetAfter: $ref: '#/components/schemas/SecurityMonitoringRuleNewValueOptionsForgetAfter' + instantaneousBaseline: + $ref: '#/components/schemas/SecurityMonitoringRuleNewValueOptionsInstantaneousBaseline' learningDuration: $ref: '#/components/schemas/SecurityMonitoringRuleNewValueOptionsLearningDuration' learningMethod: @@ -47337,6 +47339,15 @@ components: - TWO_WEEKS - THREE_WEEKS - FOUR_WEEKS + SecurityMonitoringRuleNewValueOptionsInstantaneousBaseline: + description: 'If true, every time Datadog learns a new group-by value, it takes + old matching values within the learning window and builds the baseline with + it. + + Therefore, it attempts to build the baseline swiftly using existing values + instead of learning them over time.' + example: false + type: boolean SecurityMonitoringRuleNewValueOptionsLearningDuration: default: 0 description: 'The duration in days during which values are learned, and after diff --git a/examples/v2/security-monitoring/ValidateSecurityMonitoringRule_2609327779.py b/examples/v2/security-monitoring/ValidateSecurityMonitoringRule_2609327779.py new file mode 100644 index 0000000000..0b81efca60 --- /dev/null +++ b/examples/v2/security-monitoring/ValidateSecurityMonitoringRule_2609327779.py @@ -0,0 +1,91 @@ +""" +Validate a detection rule with detection method 'new_value' with enabled feature 'instantaneousBaseline' returns "OK" +response +""" + +from datadog_api_client import ApiClient, Configuration +from datadog_api_client.v2.api.security_monitoring_api import SecurityMonitoringApi +from datadog_api_client.v2.model.security_monitoring_rule_case_create import SecurityMonitoringRuleCaseCreate +from datadog_api_client.v2.model.security_monitoring_rule_detection_method import SecurityMonitoringRuleDetectionMethod +from datadog_api_client.v2.model.security_monitoring_rule_evaluation_window import ( + SecurityMonitoringRuleEvaluationWindow, +) +from datadog_api_client.v2.model.security_monitoring_rule_keep_alive import SecurityMonitoringRuleKeepAlive +from datadog_api_client.v2.model.security_monitoring_rule_max_signal_duration import ( + SecurityMonitoringRuleMaxSignalDuration, +) +from datadog_api_client.v2.model.security_monitoring_rule_new_value_options import SecurityMonitoringRuleNewValueOptions +from datadog_api_client.v2.model.security_monitoring_rule_new_value_options_forget_after import ( + SecurityMonitoringRuleNewValueOptionsForgetAfter, +) +from datadog_api_client.v2.model.security_monitoring_rule_new_value_options_learning_duration import ( + SecurityMonitoringRuleNewValueOptionsLearningDuration, +) +from datadog_api_client.v2.model.security_monitoring_rule_new_value_options_learning_method import ( + SecurityMonitoringRuleNewValueOptionsLearningMethod, +) +from datadog_api_client.v2.model.security_monitoring_rule_new_value_options_learning_threshold import ( + SecurityMonitoringRuleNewValueOptionsLearningThreshold, +) +from datadog_api_client.v2.model.security_monitoring_rule_options import SecurityMonitoringRuleOptions +from datadog_api_client.v2.model.security_monitoring_rule_query_aggregation import ( + SecurityMonitoringRuleQueryAggregation, +) +from datadog_api_client.v2.model.security_monitoring_rule_severity import SecurityMonitoringRuleSeverity +from datadog_api_client.v2.model.security_monitoring_rule_type_create import SecurityMonitoringRuleTypeCreate +from datadog_api_client.v2.model.security_monitoring_standard_data_source import SecurityMonitoringStandardDataSource +from datadog_api_client.v2.model.security_monitoring_standard_rule_payload import SecurityMonitoringStandardRulePayload +from datadog_api_client.v2.model.security_monitoring_standard_rule_query import SecurityMonitoringStandardRuleQuery + +body = SecurityMonitoringStandardRulePayload( + cases=[ + SecurityMonitoringRuleCaseCreate( + name="", + status=SecurityMonitoringRuleSeverity.INFO, + notifications=[], + ), + ], + has_extended_title=True, + is_enabled=True, + message="My security monitoring rule", + name="My security monitoring rule", + options=SecurityMonitoringRuleOptions( + evaluation_window=SecurityMonitoringRuleEvaluationWindow.ZERO_MINUTES, + keep_alive=SecurityMonitoringRuleKeepAlive.FIVE_MINUTES, + max_signal_duration=SecurityMonitoringRuleMaxSignalDuration.TEN_MINUTES, + detection_method=SecurityMonitoringRuleDetectionMethod.NEW_VALUE, + new_value_options=SecurityMonitoringRuleNewValueOptions( + forget_after=SecurityMonitoringRuleNewValueOptionsForgetAfter.ONE_WEEK, + instantaneous_baseline=True, + learning_duration=SecurityMonitoringRuleNewValueOptionsLearningDuration.ONE_DAY, + learning_threshold=SecurityMonitoringRuleNewValueOptionsLearningThreshold.ZERO_OCCURRENCES, + learning_method=SecurityMonitoringRuleNewValueOptionsLearningMethod.DURATION, + ), + ), + queries=[ + SecurityMonitoringStandardRuleQuery( + query="source:source_here", + group_by_fields=[ + "@userIdentity.assumed_role", + ], + distinct_fields=[], + metric="name", + metrics=[ + "name", + ], + aggregation=SecurityMonitoringRuleQueryAggregation.NEW_VALUE, + name="", + data_source=SecurityMonitoringStandardDataSource.LOGS, + ), + ], + tags=[ + "env:prod", + "team:security", + ], + type=SecurityMonitoringRuleTypeCreate.LOG_DETECTION, +) + +configuration = Configuration() +with ApiClient(configuration) as api_client: + api_instance = SecurityMonitoringApi(api_client) + api_instance.validate_security_monitoring_rule(body=body) diff --git a/src/datadog_api_client/v2/model/security_monitoring_rule_new_value_options.py b/src/datadog_api_client/v2/model/security_monitoring_rule_new_value_options.py index 4452680690..373e14b951 100644 --- a/src/datadog_api_client/v2/model/security_monitoring_rule_new_value_options.py +++ b/src/datadog_api_client/v2/model/security_monitoring_rule_new_value_options.py @@ -46,6 +46,7 @@ def openapi_types(_): return { "forget_after": (SecurityMonitoringRuleNewValueOptionsForgetAfter,), + "instantaneous_baseline": (bool,), "learning_duration": (SecurityMonitoringRuleNewValueOptionsLearningDuration,), "learning_method": (SecurityMonitoringRuleNewValueOptionsLearningMethod,), "learning_threshold": (SecurityMonitoringRuleNewValueOptionsLearningThreshold,), @@ -53,6 +54,7 @@ def openapi_types(_): attribute_map = { "forget_after": "forgetAfter", + "instantaneous_baseline": "instantaneousBaseline", "learning_duration": "learningDuration", "learning_method": "learningMethod", "learning_threshold": "learningThreshold", @@ -61,6 +63,7 @@ def openapi_types(_): def __init__( self_, forget_after: Union[SecurityMonitoringRuleNewValueOptionsForgetAfter, UnsetType] = unset, + instantaneous_baseline: Union[bool, UnsetType] = unset, learning_duration: Union[SecurityMonitoringRuleNewValueOptionsLearningDuration, UnsetType] = unset, learning_method: Union[SecurityMonitoringRuleNewValueOptionsLearningMethod, UnsetType] = unset, learning_threshold: Union[SecurityMonitoringRuleNewValueOptionsLearningThreshold, UnsetType] = unset, @@ -72,6 +75,10 @@ def __init__( :param forget_after: The duration in days after which a learned value is forgotten. :type forget_after: SecurityMonitoringRuleNewValueOptionsForgetAfter, optional + :param instantaneous_baseline: If true, every time Datadog learns a new group-by value, it takes old matching values within the learning window and builds the baseline with it. + Therefore, it attempts to build the baseline swiftly using existing values instead of learning them over time. + :type instantaneous_baseline: bool, optional + :param learning_duration: The duration in days during which values are learned, and after which signals will be generated for values that weren't learned. If set to 0, a signal will be generated for all new values after the first value is learned. :type learning_duration: SecurityMonitoringRuleNewValueOptionsLearningDuration, optional @@ -84,6 +91,8 @@ def __init__( """ if forget_after is not unset: kwargs["forget_after"] = forget_after + if instantaneous_baseline is not unset: + kwargs["instantaneous_baseline"] = instantaneous_baseline if learning_duration is not unset: kwargs["learning_duration"] = learning_duration if learning_method is not unset: diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.frozen b/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.frozen new file mode 100644 index 0000000000..22633ada0a --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.frozen @@ -0,0 +1 @@ +2025-12-10T08:37:17.537Z \ No newline at end of file diff --git a/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.yaml b/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.yaml new file mode 100644 index 0000000000..6eb85a5eff --- /dev/null +++ b/tests/v2/cassettes/test_scenarios/test_validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousbaseline_returns_ok_response.yaml @@ -0,0 +1,19 @@ +interactions: +- request: + body: '{"cases":[{"name":"","notifications":[],"status":"info"}],"hasExtendedTitle":true,"isEnabled":true,"message":"My + security monitoring rule","name":"My security monitoring rule","options":{"detectionMethod":"new_value","evaluationWindow":0,"keepAlive":300,"maxSignalDuration":600,"newValueOptions":{"forgetAfter":7,"instantaneousBaseline":true,"learningDuration":1,"learningMethod":"duration","learningThreshold":0}},"queries":[{"aggregation":"new_value","dataSource":"logs","distinctFields":[],"groupByFields":["@userIdentity.assumed_role"],"metric":"name","metrics":["name"],"name":"","query":"source:source_here"}],"tags":["env:prod","team:security"],"type":"log_detection"}' + headers: + accept: + - '*/*' + content-type: + - application/json + method: POST + uri: https://api.datadoghq.com/api/v2/security_monitoring/rules/validation + response: + body: + string: '' + headers: {} + status: + code: 204 + message: No Content +version: 1 diff --git a/tests/v2/features/security_monitoring.feature b/tests/v2/features/security_monitoring.feature index 7dc352a7a4..fd887519d7 100644 --- a/tests/v2/features/security_monitoring.feature +++ b/tests/v2/features/security_monitoring.feature @@ -1797,6 +1797,13 @@ Feature: Security Monitoring When the request is sent Then the response status is 204 OK + @team:DataDog/k9-cloud-security-platform + Scenario: Validate a detection rule with detection method 'new_value' with enabled feature 'instantaneousBaseline' returns "OK" response + Given new "ValidateSecurityMonitoringRule" request + And body with value {"cases":[{"name":"","status":"info","notifications":[]}],"hasExtendedTitle":true,"isEnabled":true,"message":"My security monitoring rule","name":"My security monitoring rule","options":{"evaluationWindow":0,"keepAlive":300,"maxSignalDuration":600,"detectionMethod":"new_value","newValueOptions":{"forgetAfter":7,"instantaneousBaseline":true,"learningDuration":1,"learningThreshold":0,"learningMethod":"duration"}},"queries":[{"query":"source:source_here","groupByFields":["@userIdentity.assumed_role"],"distinctFields":[],"metric":"name","metrics":["name"],"aggregation":"new_value","name":"","dataSource":"logs"}],"tags":["env:prod","team:security"],"type":"log_detection"} + When the request is sent + Then the response status is 204 OK + @team:DataDog/k9-cloud-security-platform Scenario: Validate a detection rule with detection method 'sequence_detection' returns "OK" response Given new "ValidateSecurityMonitoringRule" request