From 90c77a86b2a6bc89788f7555e6e165e48a845736 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <219317970+cx-ricardo-jesus@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:55:47 +0000 Subject: [PATCH 1/5] feat(query): implemented 'ensure critical contacts is configured for organization' query for terraform/gcp --- .../metadata.json | 14 ++++++ .../query.rego | 48 +++++++++++++++++++ .../test/negative1.tf | 16 +++++++ .../test/negative2.tf | 11 +++++ .../test/negative3.tf | 11 +++++ .../test/negative4.tf | 6 +++ .../test/positive1.tf | 15 ++++++ .../test/positive2.tf | 14 ++++++ .../test/positive3.tf | 11 +++++ .../test/positive4.tf | 10 ++++ .../test/positive_expected_result.json | 26 ++++++++++ 11 files changed, 182 insertions(+) create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/metadata.json create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative2.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative3.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative4.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive4.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive_expected_result.json diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/metadata.json b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/metadata.json new file mode 100644 index 00000000000..d6f0a0735ea --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/metadata.json @@ -0,0 +1,14 @@ +{ + "id": "7bd9c6a8-3b1f-495c-9752-a4a9c4e1b29f", + "queryName": "Beta - Ensure Essential Contacts Is Configured For Organization", + "severity": "LOW", + "category": "Access Control", + "descriptionText": "It is advisable to set up Essential Contacts to specify email addresses that Google Cloud can use to send important technical or security notifications.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/essential_contacts_contact", + "platform": "Terraform", + "descriptionID": "7bd9c6a8", + "cloudProvider": "gcp", + "cwe": "862", + "riskScore": "1.0", + "experimental": "true" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego new file mode 100644 index 00000000000..b2f41986272 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego @@ -0,0 +1,48 @@ +package Cx + +import data.generic.common as common_lib +import data.generic.terraform as tf_lib + +CxPolicy[result] { + doc := input.document[i] + contact := doc.resource.google_essential_contacts_contact[name] + + contacts_not_configured_for_org(contact, i, doc) + + result := { + "documentId": input.document[i].id, + "resourceType": "google_essential_contacts_contact", + "resourceName": tf_lib.get_resource_name(contact, name), + "searchKey": sprintf("google_essential_contacts_contact[%s].notification_category_subscription_field", [name]), + "issueType": " IncorrectValue", + "keyExpectedValue": "'notification_category_subscription_field' should have 'ALL' value or all 'LEGAL', 'SUSPENSION', 'TECHNICAL' and 'SECURITY' values defined", + "keyActualValue": "'notification_category_subscription_field' does not have 'ALL' value or all 'LEGAL', 'SUSPENSION', 'TECHNICAL' and 'SECURITY' values defined", + "searchLine": common_lib.build_search_line(["resource", "google_essential_contacts_contact", name, "notification_category_subscriptions"], []) + } +} + +contacts_not_configured_for_org(resource, document_index, document) { + is_at_organization_level(resource, document_index, document) + not all_in_list(resource.notification_category_subscriptions) +} + +all_in_list(list) { + common_lib.inArray(list, "LEGAL") + common_lib.inArray(list, "SECURITY") + common_lib.inArray(list, "SUSPENSION") + common_lib.inArray(list, "TECHNICAL") +} else { + common_lib.inArray(list, "ALL") +} + +# check if the contact is at organization level through the parent field +is_at_organization_level(resource, document_index, document) { + resource_type := split(resource.parent, "/")[0] + resource_type == "organizations" +} else { # case when the parent field references the cases when a data source of type google_organization + resource_type := split(resource.parent, ".")[1] + resource_type == "google_organization" + data_source_name := split(resource.parent, ".")[2] + data_source := document.data.google_organization[ds_name] + data_source_name == ds_name +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative1.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative1.tf new file mode 100644 index 00000000000..07451c61ccf --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative1.tf @@ -0,0 +1,16 @@ +data "google_organization" "org" { + organization = "123456789012" +} + +resource "google_essential_contacts_contact" "negative1" { + parent = data.google_organization.org.name + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + "TECHNICAL" + ] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative2.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative2.tf new file mode 100644 index 00000000000..17235e49979 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative2.tf @@ -0,0 +1,11 @@ +data "google_organization" "org" { + organization = "123456789012" +} + +resource "google_essential_contacts_contact" "negative2" { + parent = data.google_organization.org.name + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = ["ALL"] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative3.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative3.tf new file mode 100644 index 00000000000..c75aadfe231 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative3.tf @@ -0,0 +1,11 @@ +resource "google_essential_contacts_contact" "negative3" { + parent = "organizations/123456789012" + email = "foo@bar.com" + language_tag = "en-GB" + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + "TECHNICAL" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative4.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative4.tf new file mode 100644 index 00000000000..851419dd6a2 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative4.tf @@ -0,0 +1,6 @@ +resource "google_essential_contacts_contact" "negative4" { + parent = "organizations/123456789012" + email = "foo@bar.com" + language_tag = "en-GB" + notification_category_subscriptions = ["ALL"] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive1.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive1.tf new file mode 100644 index 00000000000..09ecd0d9b33 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive1.tf @@ -0,0 +1,15 @@ +data "google_organization" "org" { + organization = "123456789012" +} + +resource "google_essential_contacts_contact" "positive1" { + parent = data.google_organization.org.name + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + ] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive2.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive2.tf new file mode 100644 index 00000000000..59be89dbd24 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive2.tf @@ -0,0 +1,14 @@ +data "google_organization" "org" { + organization = "123456789012" +} + +resource "google_essential_contacts_contact" "positive2" { + parent = data.google_organization.org.name + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "BILLING", + "PRODUCT_UPDATES", + ] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive3.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive3.tf new file mode 100644 index 00000000000..28fd36e08f0 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive3.tf @@ -0,0 +1,11 @@ +resource "google_essential_contacts_contact" "positive3" { + parent = "organizations/123456789012" + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + ] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive4.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive4.tf new file mode 100644 index 00000000000..a4b2f72e78a --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive4.tf @@ -0,0 +1,10 @@ +resource "google_essential_contacts_contact" "positive4" { + parent = "organizations/123456789012" + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "BILLING", + "PRODUCT_UPDATES", + ] +} diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive_expected_result.json b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive_expected_result.json new file mode 100644 index 00000000000..7d7a85318de --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/positive_expected_result.json @@ -0,0 +1,26 @@ +[ + { + "queryName": "Beta - Ensure Essential Contacts Is Configured For Organization", + "severity": "LOW", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Ensure Essential Contacts Is Configured For Organization", + "severity": "LOW", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Ensure Essential Contacts Is Configured For Organization", + "severity": "LOW", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - Ensure Essential Contacts Is Configured For Organization", + "severity": "LOW", + "line": 6, + "fileName": "positive4.tf" + } +] \ No newline at end of file From 7eec3cd5313a0f2b34144ab302d8ebcce89d7160 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <219317970+cx-ricardo-jesus@users.noreply.github.com> Date: Mon, 10 Nov 2025 22:39:24 +0000 Subject: [PATCH 2/5] fixed issueType --- .../query.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego index b2f41986272..40366eb365b 100644 --- a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/query.rego @@ -14,7 +14,7 @@ CxPolicy[result] { "resourceType": "google_essential_contacts_contact", "resourceName": tf_lib.get_resource_name(contact, name), "searchKey": sprintf("google_essential_contacts_contact[%s].notification_category_subscription_field", [name]), - "issueType": " IncorrectValue", + "issueType": "IncorrectValue", "keyExpectedValue": "'notification_category_subscription_field' should have 'ALL' value or all 'LEGAL', 'SUSPENSION', 'TECHNICAL' and 'SECURITY' values defined", "keyActualValue": "'notification_category_subscription_field' does not have 'ALL' value or all 'LEGAL', 'SUSPENSION', 'TECHNICAL' and 'SECURITY' values defined", "searchLine": common_lib.build_search_line(["resource", "google_essential_contacts_contact", name, "notification_category_subscriptions"], []) From 9b9acd749285c513b0caf327877f2ccf7bc67c90 Mon Sep 17 00:00:00 2001 From: Ricardo Jesus <219317970+cx-ricardo-jesus@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:27:48 +0000 Subject: [PATCH 3/5] added query to similiryID_transition yaml file for terraform/gcp --- assets/similarityID_transition/terraform_gcp.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/similarityID_transition/terraform_gcp.yaml b/assets/similarityID_transition/terraform_gcp.yaml index e9e169889f8..3ac90d8174b 100644 --- a/assets/similarityID_transition/terraform_gcp.yaml +++ b/assets/similarityID_transition/terraform_gcp.yaml @@ -63,3 +63,7 @@ similarityIDChangeList: queryName: Beta - SQL DB Instance With Exposed Show Privileges observations: "" change: 2 + - queryId: 7bd9c6a8-3b1f-495c-9752-a4a9c4e1b29f + queryName: Beta - Ensure Essential Contacts Is Configured For Organization + observations: "" + change: 2 \ No newline at end of file From 2831e0e0ef5e5b7f96cdfaa49f6b59b484c50259 Mon Sep 17 00:00:00 2001 From: Vasco Oliveira <200926503+cx-vasco-oliveira@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:21:44 +0000 Subject: [PATCH 4/5] Added tests for complete QA Accuracy Validation for this query (#7891) --- .../test/negative5.tf | 7 +++++++ .../test/negative6.tf | 12 ++++++++++++ .../test/negative7.tf | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative5.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative6.tf create mode 100644 assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative5.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative5.tf new file mode 100644 index 00000000000..c4d2f17fa11 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative5.tf @@ -0,0 +1,7 @@ +resource "google_essential_contacts_contact" "negative5" { + parent = "folders/987654321" # Not organization-level + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = ["ALL"] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative6.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative6.tf new file mode 100644 index 00000000000..31de7f555f2 --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative6.tf @@ -0,0 +1,12 @@ +resource "google_essential_contacts_contact" "negative6" { + parent = "organizations/123456789012" + email = "foo@bar.com" + language_tag = "en-GB" + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + "BILLING", + "TECHNICAL" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf new file mode 100644 index 00000000000..0c8bf06772d --- /dev/null +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf @@ -0,0 +1,16 @@ +data "google_organization" "org" { + organization = "123456789012" +} + +resource "google_essential_contacts_contact" "positive1" { + parent = data.google_organization.org.name + email = "foo@bar.com" + language_tag = "en-GB" + + notification_category_subscriptions = [ + "LEGAL", + "SECURITY", + "SUSPENSION", + "ALL" + ] +} From 48948583c7acb0c427f0ea0c25afe68c2535e983 Mon Sep 17 00:00:00 2001 From: Vasco Oliveira <200926503+cx-vasco-oliveira@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:00:31 +0000 Subject: [PATCH 5/5] Fixed negative7 test (#7892) --- .../test/negative7.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf index 0c8bf06772d..49396aa04de 100644 --- a/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf +++ b/assets/queries/terraform/gcp/ensure_essential_contacts_is_configured_for_organization/test/negative7.tf @@ -2,7 +2,7 @@ data "google_organization" "org" { organization = "123456789012" } -resource "google_essential_contacts_contact" "positive1" { +resource "google_essential_contacts_contact" "negative7" { parent = data.google_organization.org.name email = "foo@bar.com" language_tag = "en-GB"