diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 7c9668ae428..05f293a5695 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.java b/examples/v2/security-monitoring/ValidateSecurityMonitoringRule_2609327779.java new file mode 100644 index 00000000000..4eb17209ded --- /dev/null +++ b/examples/v2/security-monitoring/ValidateSecurityMonitoringRule_2609327779.java @@ -0,0 +1,88 @@ +// Validate a detection rule with detection method 'new_value' with enabled feature +// 'instantaneousBaseline' returns "OK" +// response + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.v2.api.SecurityMonitoringApi; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleCaseCreate; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleDetectionMethod; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleEvaluationWindow; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleKeepAlive; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleMaxSignalDuration; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleNewValueOptions; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleNewValueOptionsForgetAfter; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleNewValueOptionsLearningDuration; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleNewValueOptionsLearningMethod; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleNewValueOptionsLearningThreshold; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleOptions; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleQueryAggregation; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleSeverity; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleTypeCreate; +import com.datadog.api.client.v2.model.SecurityMonitoringRuleValidatePayload; +import com.datadog.api.client.v2.model.SecurityMonitoringStandardDataSource; +import com.datadog.api.client.v2.model.SecurityMonitoringStandardRulePayload; +import com.datadog.api.client.v2.model.SecurityMonitoringStandardRuleQuery; +import java.util.Arrays; +import java.util.Collections; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = ApiClient.getDefaultApiClient(); + SecurityMonitoringApi apiInstance = new SecurityMonitoringApi(defaultClient); + + SecurityMonitoringRuleValidatePayload body = + new SecurityMonitoringRuleValidatePayload( + new SecurityMonitoringStandardRulePayload() + .cases( + Collections.singletonList( + new SecurityMonitoringRuleCaseCreate() + .name("") + .status(SecurityMonitoringRuleSeverity.INFO))) + .hasExtendedTitle(true) + .isEnabled(true) + .message("My security monitoring rule") + .name("My security monitoring rule") + .options( + new SecurityMonitoringRuleOptions() + .evaluationWindow(SecurityMonitoringRuleEvaluationWindow.ZERO_MINUTES) + .keepAlive(SecurityMonitoringRuleKeepAlive.FIVE_MINUTES) + .maxSignalDuration(SecurityMonitoringRuleMaxSignalDuration.TEN_MINUTES) + .detectionMethod(SecurityMonitoringRuleDetectionMethod.NEW_VALUE) + .newValueOptions( + new SecurityMonitoringRuleNewValueOptions() + .forgetAfter( + SecurityMonitoringRuleNewValueOptionsForgetAfter.ONE_WEEK) + .instantaneousBaseline(true) + .learningDuration( + SecurityMonitoringRuleNewValueOptionsLearningDuration.ONE_DAY) + .learningThreshold( + SecurityMonitoringRuleNewValueOptionsLearningThreshold + .ZERO_OCCURRENCES) + .learningMethod( + SecurityMonitoringRuleNewValueOptionsLearningMethod.DURATION))) + .queries( + Collections.singletonList( + new SecurityMonitoringStandardRuleQuery() + .query("source:source_here") + .groupByFields(Collections.singletonList("@userIdentity.assumed_role")) + .metric("name") + .metrics(Collections.singletonList("name")) + .aggregation(SecurityMonitoringRuleQueryAggregation.NEW_VALUE) + .name("") + .dataSource(SecurityMonitoringStandardDataSource.LOGS))) + .tags(Arrays.asList("env:prod", "team:security")) + .type(SecurityMonitoringRuleTypeCreate.LOG_DETECTION)); + + try { + apiInstance.validateSecurityMonitoringRule(body); + } catch (ApiException e) { + System.err.println( + "Exception when calling SecurityMonitoringApi#validateSecurityMonitoringRule"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/datadog/api/client/v2/model/SecurityMonitoringRuleNewValueOptions.java b/src/main/java/com/datadog/api/client/v2/model/SecurityMonitoringRuleNewValueOptions.java index 2081913d7b3..5f6b4159619 100644 --- a/src/main/java/com/datadog/api/client/v2/model/SecurityMonitoringRuleNewValueOptions.java +++ b/src/main/java/com/datadog/api/client/v2/model/SecurityMonitoringRuleNewValueOptions.java @@ -19,6 +19,7 @@ /** Options on new value detection method. */ @JsonPropertyOrder({ SecurityMonitoringRuleNewValueOptions.JSON_PROPERTY_FORGET_AFTER, + SecurityMonitoringRuleNewValueOptions.JSON_PROPERTY_INSTANTANEOUS_BASELINE, SecurityMonitoringRuleNewValueOptions.JSON_PROPERTY_LEARNING_DURATION, SecurityMonitoringRuleNewValueOptions.JSON_PROPERTY_LEARNING_METHOD, SecurityMonitoringRuleNewValueOptions.JSON_PROPERTY_LEARNING_THRESHOLD @@ -30,6 +31,9 @@ public class SecurityMonitoringRuleNewValueOptions { public static final String JSON_PROPERTY_FORGET_AFTER = "forgetAfter"; private SecurityMonitoringRuleNewValueOptionsForgetAfter forgetAfter; + public static final String JSON_PROPERTY_INSTANTANEOUS_BASELINE = "instantaneousBaseline"; + private Boolean instantaneousBaseline; + public static final String JSON_PROPERTY_LEARNING_DURATION = "learningDuration"; private SecurityMonitoringRuleNewValueOptionsLearningDuration learningDuration = SecurityMonitoringRuleNewValueOptionsLearningDuration.ZERO_DAYS; @@ -68,6 +72,30 @@ public void setForgetAfter(SecurityMonitoringRuleNewValueOptionsForgetAfter forg this.forgetAfter = forgetAfter; } + public SecurityMonitoringRuleNewValueOptions instantaneousBaseline( + Boolean instantaneousBaseline) { + this.instantaneousBaseline = instantaneousBaseline; + return this; + } + + /** + * 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. + * + * @return instantaneousBaseline + */ + @jakarta.annotation.Nullable + @JsonProperty(JSON_PROPERTY_INSTANTANEOUS_BASELINE) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public Boolean getInstantaneousBaseline() { + return instantaneousBaseline; + } + + public void setInstantaneousBaseline(Boolean instantaneousBaseline) { + this.instantaneousBaseline = instantaneousBaseline; + } + public SecurityMonitoringRuleNewValueOptions learningDuration( SecurityMonitoringRuleNewValueOptionsLearningDuration learningDuration) { this.learningDuration = learningDuration; @@ -210,6 +238,8 @@ public boolean equals(Object o) { SecurityMonitoringRuleNewValueOptions securityMonitoringRuleNewValueOptions = (SecurityMonitoringRuleNewValueOptions) o; return Objects.equals(this.forgetAfter, securityMonitoringRuleNewValueOptions.forgetAfter) + && Objects.equals( + this.instantaneousBaseline, securityMonitoringRuleNewValueOptions.instantaneousBaseline) && Objects.equals( this.learningDuration, securityMonitoringRuleNewValueOptions.learningDuration) && Objects.equals(this.learningMethod, securityMonitoringRuleNewValueOptions.learningMethod) @@ -222,7 +252,12 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( - forgetAfter, learningDuration, learningMethod, learningThreshold, additionalProperties); + forgetAfter, + instantaneousBaseline, + learningDuration, + learningMethod, + learningThreshold, + additionalProperties); } @Override @@ -230,6 +265,9 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class SecurityMonitoringRuleNewValueOptions {\n"); sb.append(" forgetAfter: ").append(toIndentedString(forgetAfter)).append("\n"); + sb.append(" instantaneousBaseline: ") + .append(toIndentedString(instantaneousBaseline)) + .append("\n"); sb.append(" learningDuration: ").append(toIndentedString(learningDuration)).append("\n"); sb.append(" learningMethod: ").append(toIndentedString(learningMethod)).append("\n"); sb.append(" learningThreshold: ").append(toIndentedString(learningThreshold)).append("\n"); diff --git a/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.freeze b/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.freeze new file mode 100644 index 00000000000..22633ada0a5 --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.freeze @@ -0,0 +1 @@ +2025-12-10T08:37:17.537Z \ No newline at end of file diff --git a/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.json b/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.json new file mode 100644 index 00000000000..6b2fc13cbfa --- /dev/null +++ b/src/test/resources/cassettes/features/v2/Validate_a_detection_rule_with_detection_method_new_value_with_enabled_feature_instantaneousBaseline_returns_OK_response.json @@ -0,0 +1,27 @@ +[ + { + "httpRequest": { + "body": { + "type": "JSON", + "json": "{\"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": {}, + "method": "POST", + "path": "/api/v2/security_monitoring/rules/validation", + "keepAlive": false, + "secure": true + }, + "httpResponse": { + "headers": {}, + "statusCode": 204, + "reasonPhrase": "No Content" + }, + "times": { + "remainingTimes": 1 + }, + "timeToLive": { + "unlimited": true + }, + "id": "cbc72101-0d20-de2d-84fc-d5191be021fe" + } +] \ No newline at end of file diff --git a/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature b/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature index 7dc352a7a4e..fd887519d7e 100644 --- a/src/test/resources/com/datadog/api/client/v2/api/security_monitoring.feature +++ b/src/test/resources/com/datadog/api/client/v2/api/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