From 37827a9d133d027505fb6dd3183b22ee0b1e3652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Marschollek?= Date: Fri, 1 Apr 2022 11:57:59 +0200 Subject: [PATCH] Update provider for detection method impossible travel Updates the provider for security monitoring rules to accept rules with the new detection method `impossible_travel`. See also: - DataDog/documentation#13204 - DataDog/datadog-api-client-go#1357 --- ...source_datadog_security_monitoring_rule.go | 45 +++++ ...MonitoringRule_ImpossibleTravelRule.freeze | 1 + ...tyMonitoringRule_ImpossibleTravelRule.yaml | 153 ++++++++++++++++ ...e_datadog_security_monitoring_rule_test.go | 169 ++++++++++++++++++ .../data-sources/security_monitoring_rules.md | 10 ++ docs/resources/security_monitoring_rule.md | 10 +- 6 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.freeze create mode 100644 datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.yaml diff --git a/datadog/resource_datadog_security_monitoring_rule.go b/datadog/resource_datadog_security_monitoring_rule.go index 85e4a996c5..d1eb0538b7 100644 --- a/datadog/resource_datadog_security_monitoring_rule.go +++ b/datadog/resource_datadog_security_monitoring_rule.go @@ -147,6 +147,24 @@ func datadogSecurityMonitoringRuleSchema() map[string]*schema.Schema { }, }, }, + + "impossible_travel_options": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Options for rules using the impossible travel detection method.", + + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "baseline_user_locations": { + Type: schema.TypeBool, + Optional: true, + Default: false, + Description: "If true, signals are suppressed for the first 24 hours. In that time, Datadog learns the user's regular access locations. This can be helpful to reduce noise and infer VPN usage or credentialed API access.", + }, + }, + }, + }, }, }, }, @@ -373,9 +391,31 @@ func buildPayloadOptions(tfOptionsList []interface{}) *datadogV2.SecurityMonitor } } + if v, ok := tfOptions["impossible_travel_options"]; ok { + tfImpossibleTravelOptionsList := v.([]interface{}) + if payloadImpossibleTravelOptions, ok := buildPayloadImpossibleTravelOptions(tfImpossibleTravelOptionsList); ok { + payloadOptions.ImpossibleTravelOptions = payloadImpossibleTravelOptions + } + } + return payloadOptions } +func buildPayloadImpossibleTravelOptions(tfOptionsList []interface{}) (*datadogV2.SecurityMonitoringRuleImpossibleTravelOptions, bool) { + options := datadogV2.NewSecurityMonitoringRuleImpossibleTravelOptions() + tfOptions := extractMapFromInterface(tfOptionsList) + + hasPayload := false + + if v, ok := tfOptions["baseline_user_locations"]; ok { + hasPayload = true + shouldBaselineUserLocations := v.(bool) + options.BaselineUserLocations = &shouldBaselineUserLocations + } + + return options, hasPayload +} + func buildPayloadNewValueOptions(tfOptionsList []interface{}) (*datadogV2.SecurityMonitoringRuleNewValueOptions, bool) { payloadNewValueRulesOptions := datadogV2.NewSecurityMonitoringRuleNewValueOptions() tfOptions := extractMapFromInterface(tfOptionsList) @@ -593,6 +633,11 @@ func extractTfOptions(options datadogV2.SecurityMonitoringRuleOptions) map[strin tfNewValueOptions["learning_duration"] = int(newValueOptions.GetLearningDuration()) tfOptions["new_value_options"] = []map[string]interface{}{tfNewValueOptions} } + if impossibleTravelOptions, ok := options.GetImpossibleTravelOptionsOk(); ok { + tfImpossibleTravelOptions := make(map[string]interface{}) + tfImpossibleTravelOptions["baseline_user_locations"] = impossibleTravelOptions.GetBaselineUserLocations() + tfOptions["impossible_travel_options"] = []map[string]interface{}{tfImpossibleTravelOptions} + } return tfOptions } diff --git a/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.freeze b/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.freeze new file mode 100644 index 0000000000..4287386a56 --- /dev/null +++ b/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.freeze @@ -0,0 +1 @@ +2022-04-01T14:25:16.819597+02:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.yaml b/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.yaml new file mode 100644 index 0000000000..0ab7810f91 --- /dev/null +++ b/datadog/tests/cassettes/TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule.yaml @@ -0,0 +1,153 @@ +--- +version: 1 +interactions: +- request: + body: | + {"cases":[{"condition":"","name":"","notifications":["@user"],"status":"high"}],"hasExtendedTitle":false,"isEnabled":false,"message":"impossible travel rule triggered","name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916","options":{"detectionMethod":"impossible_travel","evaluationWindow":0,"impossibleTravelOptions":{"baselineUserLocations":true},"keepAlive":600,"maxSignalDuration":900},"queries":[{"aggregation":"geo_data","distinctFields":[],"groupByFields":["@usr.handle"],"metric":"@usr.handle","name":"my_query","query":"*"}],"tags":["i:tomato","u:tomato"],"type":"log_detection"} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules + method: POST + response: + body: '{"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":1,"createdAt":1648815924442,"filters":[],"queries":[{"distinctFields":[],"name":"my_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","isDefault":false,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":1,"createdAt":1648815924442,"filters":[],"queries":[{"distinctFields":[],"name":"my_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","isDefault":false,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":1,"createdAt":1648815924442,"filters":[],"queries":[{"distinctFields":[],"name":"my_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","isDefault":false,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":1,"createdAt":1648815924442,"filters":[],"queries":[{"distinctFields":[],"name":"my_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","isDefault":false,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: | + {"cases":[{"condition":"","name":"new case name (updated)","notifications":["@user"],"status":"high"}],"hasExtendedTitle":false,"isEnabled":false,"message":"impossible travel rule triggered (updated)","name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916","options":{"detectionMethod":"impossible_travel","evaluationWindow":0,"impossibleTravelOptions":{"baselineUserLocations":true},"keepAlive":600,"maxSignalDuration":900},"queries":[{"aggregation":"geo_data","distinctFields":[],"groupByFields":["@usr.handle"],"metric":"@usr.handle","name":"my_updated_query","query":"*"}],"tags":["i:tomato","u:tomato"]} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: PUT + response: + body: '{"updateAuthorId":1445416,"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered (updated)","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":2,"isDefault":false,"filters":[],"queries":[{"distinctFields":[],"name":"my_updated_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"new case name (updated)","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","createdAt":1648815924442,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"updateAuthorId":1445416,"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered (updated)","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":2,"isDefault":false,"filters":[],"queries":[{"distinctFields":[],"name":"my_updated_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"new case name (updated)","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","createdAt":1648815924442,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"updateAuthorId":1445416,"creationAuthorId":1445416,"tags":["u:tomato","i:tomato"],"isEnabled":false,"hasExtendedTitle":false,"message":"impossible travel rule triggered (updated)","options":{"impossibleTravelOptions":{"baselineUserLocations":true},"detectionMethod":"impossible_travel","evaluationWindow":0,"maxSignalDuration":900,"keepAlive":600},"version":2,"isDefault":false,"filters":[],"queries":[{"distinctFields":[],"name":"my_updated_query","metric":"@usr.handle","aggregation":"geo_data","groupByFields":["@usr.handle"],"query":"*"}],"isDeleted":false,"cases":[{"status":"high","notifications":["@user"],"name":"new case name (updated)","condition":""}],"type":"log_detection","id":"t3n-fmu-mrn","createdAt":1648815924442,"name":"tf-TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule-local-1648815916"}' + headers: + Content-Type: + - application/json;charset=utf-8 + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: DELETE + response: + body: "" + headers: + Content-Type: + - application/json;charset=utf-8 + status: 204 No Content + code: 204 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/security_monitoring/rules/t3n-fmu-mrn + method: GET + response: + body: '{"errors":["Threat detection rule not found: t3n-fmu-mrn"]}' + headers: + Content-Type: + - application/json + status: 404 Not Found + code: 404 + duration: "" diff --git a/datadog/tests/resource_datadog_security_monitoring_rule_test.go b/datadog/tests/resource_datadog_security_monitoring_rule_test.go index 572873a741..beacb44aaf 100644 --- a/datadog/tests/resource_datadog_security_monitoring_rule_test.go +++ b/datadog/tests/resource_datadog_security_monitoring_rule_test.go @@ -65,6 +65,29 @@ func TestAccDatadogSecurityMonitoringRule_NewValueRule(t *testing.T) { }) } +func TestAccDatadogSecurityMonitoringRule_ImpossibleTravelRule(t *testing.T) { + t.Parallel() + ctx, accProviders := testAccProviders(context.Background(), t) + ruleName := uniqueEntityName(ctx, t) + accProvider := testAccProvider(t, accProviders) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogSecurityMonitoringRuleDestroy(accProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogSecurityMonitoringCreatedConfigImpossibleTravelRule(ruleName), + Check: testAccCheckDatadogSecurityMonitorCreatedCheckImpossibleTravelRule(accProvider, ruleName), + }, + { + Config: testAccCheckDatadogSecurityMonitoringUpdatedConfigImpossibleTravelRule(ruleName), + Check: testAccCheckDatadogSecurityMonitorUpdatedCheckImpossibleTravelRule(accProvider, ruleName), + }, + }, + }) +} + func TestAccDatadogSecurityMonitoringRule_CwsRule(t *testing.T) { t.Parallel() ctx, accProviders := testAccProviders(context.Background(), t) @@ -335,6 +358,152 @@ func testAccCheckDatadogSecurityMonitorCreatedCheckNewValueRule(accProvider func ) } +func testAccCheckDatadogSecurityMonitoringCreatedConfigImpossibleTravelRule(name string) string { + return fmt.Sprintf(` +resource "datadog_security_monitoring_rule" "acceptance_test" { + name = "%s" + message = "impossible travel rule triggered" + enabled = false + + query { + name = "my_query" + query = "*" + aggregation = "geo_data" + metric = "@usr.handle" + group_by_fields = ["@usr.handle"] + } + + case { + name = "" + status = "high" + notifications = ["@user"] + } + + options { + detection_method = "impossible_travel" + keep_alive = 600 + max_signal_duration = 900 + impossible_travel_options { + baseline_user_locations = true + } + } + + tags = ["i:tomato", "u:tomato"] +} +`, name) +} + +func testAccCheckDatadogSecurityMonitorCreatedCheckImpossibleTravelRule(accProvider func() (*schema.Provider, error), ruleName string) resource.TestCheckFunc { + return resource.ComposeTestCheckFunc( + testAccCheckDatadogSecurityMonitoringRuleExists(accProvider, tfSecurityRuleName), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "name", ruleName), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "message", "impossible travel rule triggered"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "enabled", "false"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.name", "my_query"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.query", "*"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.aggregation", "geo_data"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.group_by_fields.0", "@usr.handle"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.name", ""), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.status", "high"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.notifications.0", "@user"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.keep_alive", "600"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.max_signal_duration", "900"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.detection_method", "impossible_travel"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.impossible_travel_options.0.baseline_user_locations", "true"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "tags.0", "i:tomato"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "tags.1", "u:tomato"), + ) +} + +func testAccCheckDatadogSecurityMonitoringUpdatedConfigImpossibleTravelRule(name string) string { + return fmt.Sprintf(` +resource "datadog_security_monitoring_rule" "acceptance_test" { + name = "%s" + message = "impossible travel rule triggered (updated)" + enabled = false + + query { + name = "my_updated_query" + query = "*" + aggregation = "geo_data" + metric = "@usr.handle" + group_by_fields = ["@usr.handle"] + } + + case { + name = "new case name (updated)" + status = "high" + notifications = ["@user"] + } + + options { + detection_method = "impossible_travel" + keep_alive = 600 + max_signal_duration = 900 + impossible_travel_options { + baseline_user_locations = true + } + } + + tags = ["i:tomato", "u:tomato"] +} +`, name) +} + +func testAccCheckDatadogSecurityMonitorUpdatedCheckImpossibleTravelRule(accProvider func() (*schema.Provider, error), ruleName string) resource.TestCheckFunc { + return resource.ComposeTestCheckFunc( + testAccCheckDatadogSecurityMonitoringRuleExists(accProvider, tfSecurityRuleName), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "name", ruleName), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "message", "impossible travel rule triggered (updated)"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "enabled", "false"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.name", "my_updated_query"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.query", "*"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.aggregation", "geo_data"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "query.0.group_by_fields.0", "@usr.handle"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.name", "new case name (updated)"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.status", "high"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "case.0.notifications.0", "@user"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.keep_alive", "600"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.max_signal_duration", "900"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.detection_method", "impossible_travel"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "options.0.impossible_travel_options.0.baseline_user_locations", "true"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "tags.0", "i:tomato"), + resource.TestCheckResourceAttr( + tfSecurityRuleName, "tags.1", "u:tomato"), + ) +} + func testAccCheckDatadogSecurityMonitoringCreatedConfigCwsRule(name string) string { return fmt.Sprintf(` resource "datadog_security_monitoring_rule" "acceptance_test" { diff --git a/docs/data-sources/security_monitoring_rules.md b/docs/data-sources/security_monitoring_rules.md index f4aae28e7c..cf06c2eec6 100644 --- a/docs/data-sources/security_monitoring_rules.md +++ b/docs/data-sources/security_monitoring_rules.md @@ -82,6 +82,7 @@ Read-only: - **keep_alive** (Number) - **max_signal_duration** (Number) - **new_value_options** (List of Object) (see [below for nested schema](#nestedobjatt--rules--options--new_value_options)) +- **impossible_travel_options** (List of Object) (see [below for nested schema](#nestedblock--options--impossible_travel_options)) ### Nested schema for `rules.options.new_value_options` @@ -93,6 +94,15 @@ Read-only: + +### Nested schema for `rules.options.impossible_travel_options` + +Read-only: + +- **baseline_user_locations** (Boolean) + + + ### Nested schema for `rules.query` diff --git a/docs/resources/security_monitoring_rule.md b/docs/resources/security_monitoring_rule.md index ab4d6c80c2..af73cc03c2 100644 --- a/docs/resources/security_monitoring_rule.md +++ b/docs/resources/security_monitoring_rule.md @@ -132,8 +132,9 @@ Required: Optional: -- **detection_method** (String) The detection method. Valid values are `threshold`, `new_value`, `anomaly_detection`. +- **detection_method** (String) The detection method. Valid values are `threshold`, `new_value`, `anomaly_detection`, `impossible_travel`. - **new_value_options** (Block List, Max: 1) New value rules specific options. (see [below for nested schema](#nestedblock--options--new_value_options)) +- **impossible_travel_options** (Block List, Max: 1) Options for rules using the impossible travel detection method. (see [below for nested schema](#nestedblock--options--impossible_travel_options)) ### Nested schema for `options.new_value_options` @@ -143,6 +144,13 @@ Required: - **forget_after** (Number) The duration in days after which a learned value is forgotten. Valid values are `1`, `2`, `7`, `14`, `21`, `28`. - **learning_duration** (Number) 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. Valid values are `0`, `1`, `7`. + +### Nested schema for `options.impossible_travel_options` + +Optional: + +- **baseline_user_locations** (Boolean) If true, signals are suppressed for the first 24 hours. In that time, Datadog learns the user's regular access locations. This can be helpful to reduce noise and infer VPN usage or credentialed API access. Default is `false`. + ## Import Import is supported using the following syntax: