diff --git a/modules/secops-rules/README.md b/modules/secops-rules/README.md
new file mode 100644
index 000000000..e99aa3858
--- /dev/null
+++ b/modules/secops-rules/README.md
@@ -0,0 +1,217 @@
+# SecOps Rules
+
+This module allows creation and management of [custom rules](https://cloud.google.com/chronicle/docs/detection/view-all-rules) as well as [reference lists](https://cloud.google.com/chronicle/docs/reference/reference-lists) in Google SecOps.
+
+- rule definition (yaral code) and reference list entries are managed as files in data folder as per the `factories_config` variable and sample code
+- rule and reference list deployments can leverage both `rules_config` and `reference_lists_config` variables or YAML file still specified in the `factories_config` variable.
+
+
+- [Examples](#examples)
+ - [Sample SecOps Rules and reference list deployment](#sample-secops-rules-and-reference-list-deployment)
+ - [SecOps Rules Factory](#secops-rules-factory)
+- [Variables](#variables)
+
+
+## Examples
+
+### Sample SecOps Rules and reference list deployment
+
+This is a sample usage of the secops-rules module for deploying a rule (network_traffic_to_specific_country) and a reference list (private_ip_ranges), definition of the rule in yaral is available in the corresponding file in the `data/rules` folder and the reference list in the `data/reference_lists` folder. Deployment configuration for both is passed as an input to the module using the `rules_config` and `reference_lists_config` variables.
+
+```hcl
+module "secops" {
+ source = "./fabric/modules/secops-rules"
+ project_id = var.project_id
+ tenant_config = var.secops_tenant_config
+ reference_lists_config = {
+ "private_ip_ranges" = {
+ description = "Private CIDR ranges"
+ type = "CIDR"
+ }
+ }
+ rules_config = {
+ "network_traffic_to_specific_country" = {
+ enabled = true
+ alerting = true
+ archived = false
+ run_frequency = "LIVE"
+ }
+ }
+ factories_config = {
+ rules_defs = "./data/rules"
+ reference_lists_defs = "./data/reference_lists"
+ }
+}
+# tftest modules=1 resources=3 files=reference,rule inventory=basic.yaml
+```
+
+```
+rule network_traffic_to_specific_country {
+
+meta:
+ author = "Google Cloud Security"
+ description = "Identify network traffic based on target country"
+ type = "alert"
+ tags = "geoip enrichment"
+ data_source = "microsoft windows events"
+ severity = "Low"
+ priority = "Low"
+
+events:
+ $network.metadata.event_type = "NETWORK_CONNECTION"
+ //Specify a country of interest to monitor or add additional countries using an or statement
+ $network.target.ip_geo_artifact.location.country_or_region = "France" nocase
+ $network.target.ip = $ip
+
+match:
+ $ip over 30m
+
+outcome:
+ $risk_score = max(35)
+ $event_count = count_distinct($network.metadata.id)
+
+ // added to populate alert graph with additional context
+ $principal_ip = array_distinct($network.principal.ip)
+
+ // Commented out target.ip because it is already represented in graph as match variable. If match changes, can uncomment to add to results
+ //$target_ip = array_distinct($network.target.ip)
+ $principal_process_pid = array_distinct($network.principal.process.pid)
+ $principal_process_command_line = array_distinct($network.principal.process.command_line)
+ $principal_process_file_sha256 = array_distinct($network.principal.process.file.sha256)
+ $principal_process_file_full_path = array_distinct($network.principal.process.file.full_path)
+ $principal_process_product_specfic_process_id = array_distinct($network.principal.process.product_specific_process_id)
+ $principal_process_parent_process_product_specfic_process_id = array_distinct($network.principal.process.parent_process.product_specific_process_id)
+ $target_process_pid = array_distinct($network.target.process.pid)
+ $target_process_command_line = array_distinct($network.target.process.command_line)
+ $target_process_file_sha256 = array_distinct($network.target.process.file.sha256)
+ $target_process_file_full_path = array_distinct($network.target.process.file.full_path)
+ $target_process_product_specfic_process_id = array_distinct($network.target.process.product_specific_process_id)
+ $target_process_parent_process_product_specfic_process_id = array_distinct($network.target.process.parent_process.product_specific_process_id)
+ $principal_user_userid = array_distinct($network.principal.user.userid)
+ $target_user_userid = array_distinct($network.target.user.userid)
+
+condition:
+ $network
+}
+# tftest-file id=rule path=data/rules/network_traffic_to_specific_country.yaral
+```
+
+```
+10.0.0.0/8
+172.16.0.0/12
+192.168.0.0/16
+127.0.0.1/32
+::1/128
+fc00::/7
+fe80::/10
+# tftest-file id=reference path=data/reference_lists/private_ip_ranges.txt
+```
+
+### SecOps Rules Factory
+
+The module includes a secops rules and reference list factory (see [Resource Factories](../../blueprints/factories/)) for the configuration of rules and reference lists leveraging YAML configuration files. Each configuration file for rules and reference lists contains more than one rule with a structure that reflects the `rules_config` and `reference_lists_config` variables. Again rules and reference list definition is available in the corresponding yaral and txt files in the data folder.
+
+```hcl
+module "secops" {
+ source = "./fabric/modules/secops-rules"
+ project_id = var.project_id
+ tenant_config = var.secops_tenant_config
+ factories_config = {
+ rules = "./secops_rules.yaml"
+ rules_defs = "./data/rules"
+ reference_lists = "./secops_reference_lists.yaml"
+ reference_lists_defs = "./data/reference_lists"
+ }
+}
+# tftest modules=1 resources=3 files=1,2,reference,rule inventory=factory.yaml
+
+```
+
+```yaml
+network_traffic_to_specific_country:
+ enabled: true
+ alerting: true
+ archived: false
+ run_frequency: "DAILY"
+# tftest-file id=1 path=secops_rules.yaml
+```
+
+```yaml
+private_ip_ranges:
+ description: "Private CIDR ranges"
+ type: CIDR # either CIDR, STRING, REGEX
+# tftest-file id=2 path=secops_reference_lists.yaml
+```
+
+```
+rule network_traffic_to_specific_country {
+
+meta:
+ author = "Google Cloud Security"
+ description = "Identify network traffic based on target country"
+ type = "alert"
+ tags = "geoip enrichment"
+ data_source = "microsoft windows events"
+ severity = "Low"
+ priority = "Low"
+
+events:
+ $network.metadata.event_type = "NETWORK_CONNECTION"
+ //Specify a country of interest to monitor or add additional countries using an or statement
+ $network.target.ip_geo_artifact.location.country_or_region = "France" nocase
+ $network.target.ip = $ip
+
+match:
+ $ip over 30m
+
+outcome:
+ $risk_score = max(35)
+ $event_count = count_distinct($network.metadata.id)
+
+ // added to populate alert graph with additional context
+ $principal_ip = array_distinct($network.principal.ip)
+
+ // Commented out target.ip because it is already represented in graph as match variable. If match changes, can uncomment to add to results
+ //$target_ip = array_distinct($network.target.ip)
+ $principal_process_pid = array_distinct($network.principal.process.pid)
+ $principal_process_command_line = array_distinct($network.principal.process.command_line)
+ $principal_process_file_sha256 = array_distinct($network.principal.process.file.sha256)
+ $principal_process_file_full_path = array_distinct($network.principal.process.file.full_path)
+ $principal_process_product_specfic_process_id = array_distinct($network.principal.process.product_specific_process_id)
+ $principal_process_parent_process_product_specfic_process_id = array_distinct($network.principal.process.parent_process.product_specific_process_id)
+ $target_process_pid = array_distinct($network.target.process.pid)
+ $target_process_command_line = array_distinct($network.target.process.command_line)
+ $target_process_file_sha256 = array_distinct($network.target.process.file.sha256)
+ $target_process_file_full_path = array_distinct($network.target.process.file.full_path)
+ $target_process_product_specfic_process_id = array_distinct($network.target.process.product_specific_process_id)
+ $target_process_parent_process_product_specfic_process_id = array_distinct($network.target.process.parent_process.product_specific_process_id)
+ $principal_user_userid = array_distinct($network.principal.user.userid)
+ $target_user_userid = array_distinct($network.target.user.userid)
+
+condition:
+ $network
+}
+# tftest-file id=rule path=data/rules/network_traffic_to_specific_country.yaral
+```
+
+```
+10.0.0.0/8
+172.16.0.0/12
+192.168.0.0/16
+127.0.0.1/32
+::1/128
+fc00::/7
+fe80::/10
+# tftest-file id=reference path=data/reference_lists/private_ip_ranges.txt
+```
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---:|:---:|:---:|
+| [project_id](variables.tf#L29) | Project used for resources. | string | ✓ | |
+| [tenant_config](variables.tf#L66) | SecOps Tenant configuration. | object({…}) | ✓ | |
+| [factories_config](variables.tf#L17) | Paths to YAML config expected in 'rules' and 'reference_lists'. Path to folders containing rules definitions (yaral files) and reference lists content (txt files) for the corresponding _defs keys. | object({…}) | | {} |
+| [reference_lists_config](variables.tf#L34) | SecOps Reference lists configuration. | map(object({…})) | | {} |
+| [rules_config](variables.tf#L49) | SecOps Detection rules configuration. | map(object({…})) | | {} |
+
diff --git a/modules/secops-rules/main.tf b/modules/secops-rules/main.tf
new file mode 100644
index 000000000..b76191bb4
--- /dev/null
+++ b/modules/secops-rules/main.tf
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+locals {
+ reference_lists = try(yamldecode(file(var.factories_config.reference_lists)), var.reference_lists_config)
+ reference_lists_entries = {
+ for k, v in local.reference_lists : k => split("\n", file("${var.factories_config.reference_lists_defs}/${k}.txt"))
+ }
+ reference_list_type_mapping = {
+ STRING = "REFERENCE_LIST_SYNTAX_TYPE_PLAIN_TEXT_STRING"
+ REGEX = "REFERENCE_LIST_SYNTAX_TYPE_REGEX"
+ CIDR = "REFERENCE_LIST_SYNTAX_TYPE_CIDR"
+ }
+ secops_rules = {
+ for file_name in fileset(var.factories_config.rules_defs, "*.yaral") :
+ replace(file_name, ".yaral", "") => file("${var.factories_config.rules_defs}/${file_name}")
+ }
+ secops_rule_deployment = try(yamldecode(file(var.factories_config.rules)), var.rules_config)
+}
+
+resource "google_chronicle_reference_list" "default" {
+ for_each = local.reference_lists
+ project = var.project_id
+ location = var.tenant_config.region
+ instance = var.tenant_config.customer_id
+ reference_list_id = each.key
+ description = each.value.description
+ dynamic "entries" {
+ for_each = local.reference_lists_entries[each.key]
+ content {
+ value = entries.value
+ }
+ }
+ syntax_type = local.reference_list_type_mapping[each.value.type]
+}
+
+resource "google_chronicle_rule" "default" {
+ for_each = local.secops_rule_deployment
+ project = var.project_id
+ location = var.tenant_config.region
+ instance = var.tenant_config.customer_id
+ text = local.secops_rules[each.key]
+ deletion_policy = "FORCE"
+ depends_on = [
+ google_chronicle_reference_list.default
+ ]
+}
+
+resource "google_chronicle_rule_deployment" "default" {
+ for_each = local.secops_rule_deployment
+ project = var.project_id
+ location = var.tenant_config.region
+ instance = var.tenant_config.customer_id
+ rule = google_chronicle_rule.default[each.key].rule_id
+ enabled = each.value.enabled
+ alerting = each.value.alerting
+ archived = each.value.archived
+ run_frequency = each.value.run_frequency
+}
diff --git a/modules/secops-rules/variables.tf b/modules/secops-rules/variables.tf
new file mode 100644
index 000000000..163e29865
--- /dev/null
+++ b/modules/secops-rules/variables.tf
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+variable "factories_config" {
+ description = "Paths to YAML config expected in 'rules' and 'reference_lists'. Path to folders containing rules definitions (yaral files) and reference lists content (txt files) for the corresponding _defs keys."
+ type = object({
+ rules = optional(string)
+ rules_defs = optional(string, "data/rules")
+ reference_lists = optional(string)
+ reference_lists_defs = optional(string, "data/reference_lists")
+ })
+ nullable = false
+ default = {}
+}
+
+variable "project_id" {
+ description = "Project used for resources."
+ type = string
+}
+
+variable "reference_lists_config" {
+ description = "SecOps Reference lists configuration."
+ type = map(object({
+ description = string
+ type = string
+ }))
+ default = {}
+ validation {
+ condition = alltrue([
+ for config in var.reference_lists_config : contains(["CIDR", "STRING", "REGEX"], config.type)
+ ])
+ error_message = "The 'type' attribute for each reference list must be one of: CIDR, STRING, REGEX."
+ }
+}
+
+variable "rules_config" {
+ description = "SecOps Detection rules configuration."
+ type = map(object({
+ enabled = optional(bool, true)
+ alerting = optional(bool, false)
+ archived = optional(bool, false)
+ run_frequency : optional(string)
+ }))
+ default = {}
+ validation {
+ condition = alltrue([
+ for config in var.rules_config : contains(["LIVE", "HOURLY", "DAILY"], config.run_frequency)
+ ])
+ error_message = "The 'type' attribute for each reference list must be one of: CIDR, STRING, REGEX."
+ }
+}
+
+variable "tenant_config" {
+ description = "SecOps Tenant configuration."
+ type = object({
+ customer_id = string
+ region = string
+ })
+}
diff --git a/modules/secops-rules/versions.tf b/modules/secops-rules/versions.tf
new file mode 100644
index 000000000..469fa2ddb
--- /dev/null
+++ b/modules/secops-rules/versions.tf
@@ -0,0 +1,35 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Fabric release: v38.1.0
+
+terraform {
+ required_version = ">= 1.10.2"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 6.28.0, < 7.0.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 6.28.0, < 7.0.0" # tftest
+ }
+ }
+ provider_meta "google" {
+ module_name = "google-pso-tool/cloud-foundation-fabric/path:v38.1.0-tf"
+ }
+ provider_meta "google-beta" {
+ module_name = "google-pso-tool/cloud-foundation-fabric/path:v38.1.0-tf"
+ }
+}
diff --git a/modules/secops-rules/versions.tofu b/modules/secops-rules/versions.tofu
new file mode 100644
index 000000000..33635f966
--- /dev/null
+++ b/modules/secops-rules/versions.tofu
@@ -0,0 +1,35 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Fabric release: v38.1.0
+
+terraform {
+ required_version = ">= 1.9.0"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 6.28.0, < 7.0.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 6.28.0, < 7.0.0" # tftest
+ }
+ }
+ provider_meta "google" {
+ module_name = "google-pso-tool/cloud-foundation-fabric/path:v38.1.0-tofu"
+ }
+ provider_meta "google-beta" {
+ module_name = "google-pso-tool/cloud-foundation-fabric/path:v38.1.0-tofu"
+ }
+}
diff --git a/tests/examples/variables.tf b/tests/examples/variables.tf
index 80f76c234..6ba4c363f 100644
--- a/tests/examples/variables.tf
+++ b/tests/examples/variables.tf
@@ -61,6 +61,13 @@ variable "regions" {
}
}
+variable "secops_tenant_config" {
+ default = {
+ customer_id = "customer-id"
+ region = "europe"
+ }
+}
+
variable "service_account" {
default = {
id = "service_account_id"
diff --git a/tests/modules/secops_rules/examples/basic.yaml b/tests/modules/secops_rules/examples/basic.yaml
new file mode 100644
index 000000000..9c9f6d423
--- /dev/null
+++ b/tests/modules/secops_rules/examples/basic.yaml
@@ -0,0 +1,76 @@
+# Copyright 2023 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+values:
+ module.secops.google_chronicle_reference_list.default["private_ip_ranges"]:
+ description: Private CIDR ranges
+ entries:
+ - value: 10.0.0.0/8
+ - value: 172.16.0.0/12
+ - value: 192.168.0.0/16
+ - value: 127.0.0.1/32
+ - value: ::1/128
+ - value: fc00::/7
+ - value: fe80::/10
+ - value: '# tftest-file id=reference path=data/reference_lists/private_ip_ranges.txt'
+ - value: ''
+ instance: customer-id
+ location: europe
+ project: project-id
+ reference_list_id: private_ip_ranges
+ syntax_type: REFERENCE_LIST_SYNTAX_TYPE_CIDR
+ timeouts: null
+ module.secops.google_chronicle_rule.default["network_traffic_to_specific_country"]:
+ deletion_policy: FORCE
+ instance: customer-id
+ location: europe
+ project: project-id
+ scope: null
+ text: "rule network_traffic_to_specific_country {\n\nmeta:\n author = \"Google\
+ \ Cloud Security\"\n description = \"Identify network traffic based on target\
+ \ country\"\n type = \"alert\"\n tags = \"geoip enrichment\"\n data_source\
+ \ = \"microsoft windows events\"\n severity = \"Low\"\n priority = \"Low\"\
+ \n\nevents:\n $network.metadata.event_type = \"NETWORK_CONNECTION\"\n //Specify\
+ \ a country of interest to monitor or add additional countries using an or statement\n\
+ \ $network.target.ip_geo_artifact.location.country_or_region = \"France\" nocase\n\
+ \ $network.target.ip = $ip\n\nmatch:\n $ip over 30m\n\noutcome:\n $risk_score\
+ \ = max(35)\n $event_count = count_distinct($network.metadata.id)\n\n // added\
+ \ to populate alert graph with additional context\n $principal_ip = array_distinct($network.principal.ip)\n\
+ \n // Commented out target.ip because it is already represented in graph as\
+ \ match variable. If match changes, can uncomment to add to results\n //$target_ip\
+ \ = array_distinct($network.target.ip)\n $principal_process_pid = array_distinct($network.principal.process.pid)\n\
+ \ $principal_process_command_line = array_distinct($network.principal.process.command_line)\n\
+ \ $principal_process_file_sha256 = array_distinct($network.principal.process.file.sha256)\n\
+ \ $principal_process_file_full_path = array_distinct($network.principal.process.file.full_path)\n\
+ \ $principal_process_product_specfic_process_id = array_distinct($network.principal.process.product_specific_process_id)\n\
+ \ $principal_process_parent_process_product_specfic_process_id = array_distinct($network.principal.process.parent_process.product_specific_process_id)\n\
+ \ $target_process_pid = array_distinct($network.target.process.pid)\n $target_process_command_line\
+ \ = array_distinct($network.target.process.command_line)\n $target_process_file_sha256\
+ \ = array_distinct($network.target.process.file.sha256)\n $target_process_file_full_path\
+ \ = array_distinct($network.target.process.file.full_path)\n $target_process_product_specfic_process_id\
+ \ = array_distinct($network.target.process.product_specific_process_id)\n $target_process_parent_process_product_specfic_process_id\
+ \ = array_distinct($network.target.process.parent_process.product_specific_process_id)\n\
+ \ $principal_user_userid = array_distinct($network.principal.user.userid)\n\
+ \ $target_user_userid = array_distinct($network.target.user.userid)\n\ncondition:\n\
+ \ $network\n}\n# tftest-file id=rule path=data/rules/network_traffic_to_specific_country.yaral\n"
+ timeouts: null
+ module.secops.google_chronicle_rule_deployment.default["network_traffic_to_specific_country"]:
+ alerting: true
+ archived: false
+ enabled: true
+ instance: customer-id
+ location: europe
+ project: project-id
+ run_frequency: LIVE
+ timeouts: null
diff --git a/tests/modules/secops_rules/examples/factory.yaml b/tests/modules/secops_rules/examples/factory.yaml
new file mode 100644
index 000000000..aaca9c6f0
--- /dev/null
+++ b/tests/modules/secops_rules/examples/factory.yaml
@@ -0,0 +1,76 @@
+# Copyright 2023 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+values:
+ module.secops.google_chronicle_reference_list.default["private_ip_ranges"]:
+ description: Private CIDR ranges
+ entries:
+ - value: 10.0.0.0/8
+ - value: 172.16.0.0/12
+ - value: 192.168.0.0/16
+ - value: 127.0.0.1/32
+ - value: ::1/128
+ - value: fc00::/7
+ - value: fe80::/10
+ - value: '# tftest-file id=reference path=data/reference_lists/private_ip_ranges.txt'
+ - value: ''
+ instance: customer-id
+ location: europe
+ project: project-id
+ reference_list_id: private_ip_ranges
+ syntax_type: REFERENCE_LIST_SYNTAX_TYPE_CIDR
+ timeouts: null
+ module.secops.google_chronicle_rule.default["network_traffic_to_specific_country"]:
+ deletion_policy: FORCE
+ instance: customer-id
+ location: europe
+ project: project-id
+ scope: null
+ text: "rule network_traffic_to_specific_country {\n\nmeta:\n author = \"Google\
+ \ Cloud Security\"\n description = \"Identify network traffic based on target\
+ \ country\"\n type = \"alert\"\n tags = \"geoip enrichment\"\n data_source\
+ \ = \"microsoft windows events\"\n severity = \"Low\"\n priority = \"Low\"\
+ \n\nevents:\n $network.metadata.event_type = \"NETWORK_CONNECTION\"\n //Specify\
+ \ a country of interest to monitor or add additional countries using an or statement\n\
+ \ $network.target.ip_geo_artifact.location.country_or_region = \"France\" nocase\n\
+ \ $network.target.ip = $ip\n\nmatch:\n $ip over 30m\n\noutcome:\n $risk_score\
+ \ = max(35)\n $event_count = count_distinct($network.metadata.id)\n\n // added\
+ \ to populate alert graph with additional context\n $principal_ip = array_distinct($network.principal.ip)\n\
+ \n // Commented out target.ip because it is already represented in graph as\
+ \ match variable. If match changes, can uncomment to add to results\n //$target_ip\
+ \ = array_distinct($network.target.ip)\n $principal_process_pid = array_distinct($network.principal.process.pid)\n\
+ \ $principal_process_command_line = array_distinct($network.principal.process.command_line)\n\
+ \ $principal_process_file_sha256 = array_distinct($network.principal.process.file.sha256)\n\
+ \ $principal_process_file_full_path = array_distinct($network.principal.process.file.full_path)\n\
+ \ $principal_process_product_specfic_process_id = array_distinct($network.principal.process.product_specific_process_id)\n\
+ \ $principal_process_parent_process_product_specfic_process_id = array_distinct($network.principal.process.parent_process.product_specific_process_id)\n\
+ \ $target_process_pid = array_distinct($network.target.process.pid)\n $target_process_command_line\
+ \ = array_distinct($network.target.process.command_line)\n $target_process_file_sha256\
+ \ = array_distinct($network.target.process.file.sha256)\n $target_process_file_full_path\
+ \ = array_distinct($network.target.process.file.full_path)\n $target_process_product_specfic_process_id\
+ \ = array_distinct($network.target.process.product_specific_process_id)\n $target_process_parent_process_product_specfic_process_id\
+ \ = array_distinct($network.target.process.parent_process.product_specific_process_id)\n\
+ \ $principal_user_userid = array_distinct($network.principal.user.userid)\n\
+ \ $target_user_userid = array_distinct($network.target.user.userid)\n\ncondition:\n\
+ \ $network\n}\n# tftest-file id=rule path=data/rules/network_traffic_to_specific_country.yaral\n"
+ timeouts: null
+ module.secops.google_chronicle_rule_deployment.default["network_traffic_to_specific_country"]:
+ alerting: true
+ archived: false
+ enabled: true
+ instance: customer-id
+ location: europe
+ project: project-id
+ run_frequency: DAILY
+ timeouts: null